Final-report - infrastructure - prolog

advertisement
Wrapping C# with Prolog
Dameon G Rogers
Workflow Team – Prolog to C#
Abstract
The goal of getting the logical functionality of Prolog converted in a C# environment has been
achieved and now the logical functionality that is required in OpenSim can be implemented for
the medical simulation.
1. Problem
The infrastructure teams’ main task is to assist and build all the tools and pieces that other teams
may use to support their own work in OpenSim and Second Life. This includes: browser, cell
phone, database, lisp, ontology and prolog integration and use along with the programs and or
work that can help support the effort of integration into the OpenSim environment.
The specific task of the sub-team (which includes Jerry Maine working on Lisp to C#) is to
attempt the use of the advantageous properties of Lisp and Prolog, ported into C#, to affect the
OpenSim world to assist with any programmed behaviors that may be desired to complete the
goal of workflow implementation within a medical simulation.
2. Objective
The infrastructure team is attempting on several fronts to implement certain behaviors into the
OpenSim platform. These behaviors relate to infrastructure the workflow team has created to
implement behaviors that would and will be useful in a medical setting to simulate the function
of RFID tagging in a hospital setting. The tools are programmed for specific tasks: get blanket,
push button and chat that will assist in the accurate simulation of a medical environment and
allow data to be gathered with RFID.
The specific task of my sub team, which includes Jerry Maine, is to try to port Prolog, which
May Zeineldin created, and Lisp scripts into the OpenSim platform and allow the versatile
functionality within the language type of Prolog and Lisp. Prolog is excellent for logic and state
based programming, the basis of the OpenSim platform and Lisp is excellent at ordering lists
which is extremely useful for the implementation of tasks that must be completed in order get the
desired functionality in the virtual world.
3. Related Work
Prolog Scripts. May Zeineldin. 7 Nov. 2008. http://www.csce.uark.edu/~cwt/COURSES/200808--CSCE-4313--PL/STATUS-REPORTS/HW3b/.
Lisp Parsings. Jerry Maine. 7 Nov. 2008. http://www.csce.uark.edu/~cwt/COURSES/2008-08-CSCE-4313--PL/STATUS-REPORTS/HW3b/.
4. Architecture
4.1 Design
The overall design of the project was ‘Workflow’ and this team was responsible for making the
actual workflow of the system functional and able to complete some useful functions.
The design of my subproject was to try to code some prolog functionality into C# code. C# code
will run in the OpenSim platform so the process is two fold. First the Prolog code is ported into
C# and then the C# is ported into OpenSim using the DotNet Engine. This allows functionality
to be added to the OpenSim environment and lays groundwork for the successful testing and
deployment of a virtual RFID network to improve and further explore a medical environment in
OpenSim.
4.2 Testing
Testing included writing C# code in Visual Studio 2008 and making sure that it compiled and
was logically identical or very similar to the prolog scripts that May had written for the OpenSim
platform. It compiled and ran on both Mono for Windows and Visual Studio. I also noticed that
if the ‘cut’ operator is not used there will be warnings in both Mono and Visual Studio but those
can be ignored. This warning message is generated because if the ‘cut’ operator is not used then
those values in the parser and compiler are not used.
5. Results
The testing of the conversion of Prolog to C# is a success and within the testing environments of
Visual Studio and Mono the code functions correctly and also gives interesting output that will
be useful to the state-based virtual world.
6. Yield Prolog Details
Yield Prolog is a set of C# Windows tools that allows for the logic functionality of prolog to be
coded with a DotNet Engine. When this project began, prolog was completely unknown to the
sub team. The first step was to visit the main library and discover any resources that the library
may have, this included a short list of books on prolog: syntax, grammar, functionality and code
examples. This step took about half a month. At this point there was no viable connection
between any Windows suite, web interface and prolog functionality. After a very informative
and useful meeting with Dr. Thompson and Jerry Maine ‘yield prolog’ was mentioned as a
possible viable synthesis of this schema to create logic behavior and functionality. Yield prolog
allows almost ‘all’ the logic functionality of prolog including the cut operator for limiting the
search space with prolog. It also allows for the linking of two components known as ‘atoms’
inside an object. This will let any two data structures exist in a logically linked manner. This
relationship is very helpful when coding logic parameters to get a logical behavior. There are
two basic methods to wrap and translate the prolog language into C# which greatly increases the
available implementation and usefulness of prolog.
6.1 Method One – Translation
This method allows a direct translation from prolog to the C# language and will assist with
encoding prolog functions and larger prolog code, including the search limiting ‘cut’ operator.
Prolog Function – Author: May Zeineldin ‘scenario10’
request(patient,'Order dinner'):-push(patient,'Call button').
push(patient,'Call button'):chat_command('Can I help you'),
chat_command('Yes,I would like to order my dinner'),
chat_command('Let me check the doctor’s orders'),
chat_command('Yes, you can now have a regular diet,I will be right in to help you order'),
goto(free_nurse,room),
get(menu),
chat_command('You can order one item from each category'),
chat_command('What kind of soup would you like,Tomato or chicken noodle'),
chat_command('chicken noodle'),
chat_command('Would you like pasta, chicken or beef'),
chat_command('I will take the pasta'),
chat_command('That comes with a small salad,What kind of dressing would you like'),
chat_command('blue cheese'),
chat_command('We will bring that on the side'),
chat_command('What would you like for dessert,There is chocolate cake, ice cream or apple pie'),
chat_command('No dessert'),
chat_command('what would you like to drink,There is coffee, tea, cola or milk'),
chat_command('I will take coffee with cream and sugar'),
chat_command('I will put your order in,A new menu for each meal will be on your food tray,Just turn it in
with your tray each meal'),
chat_command('Thank you').
Translate to C#
/*
* Dinner_Prolog
*
* This class specifies the behavior allow a patient to order dinner.
*
* Author: Dameon G Rogers
*/
using System;
using System.Collections.Generic;
using YieldProlog;
class Dinner_Prolog
{
static void Main(string[] args)
{
Console.WriteLine("Return an action for a patient:");
Variable Request = new Variable();
foreach (bool l1 in nurseRequest("patient", "push", Request))
Console.WriteLine("Connect = " + Request.getValue());
Console.WriteLine("Unify push with action:");
Variable Action = new Variable();
Variable Move = new Variable();
Console.WriteLine("Can I help you?");
Console.WriteLine("Yes, I would like to order dinner.");
Console.WriteLine("Let me check the doctor’s orders.");
Console.WriteLine("Yes, you can now have a regular diet, I will be
right in to help you order.");
foreach (bool l1 in nurseMovement("nurse", Move, new
ListPair("nurse", new ListPair("free_room", Atom.NIL))))
Console.WriteLine("The nurse location is " + Move.getValue());
foreach (bool l1 in nurseRequest("patient", Action, new
ListPair("patient", new ListPair("'get menu'", Atom.NIL))))
Console.WriteLine("The action is " + Action.getValue());
Console.WriteLine("You can order one item from each category.");
Console.WriteLine("What kind of soup would you like,Tomato or chicken
noodle.");
Console.WriteLine("Chicken noodle...");
Console.WriteLine("Would you like pasta, chicken or beef.");
Console.WriteLine("I will take the pasta.");
Console.WriteLine("That comes with a small salad. What kind of
dressing would you like?");
Console.WriteLine("blue cheese");
Console.WriteLine("We will bring that on the side.");
Console.WriteLine("What would you like for dessert? There is
chocolate cake, ice cream or apple pie.");
Console.WriteLine("No dessert, please.");
Console.WriteLine("what would you like to drink? There is coffee,
tea, cola or milk.");
Console.WriteLine("I will take coffee with cream and sugar");
Console.WriteLine("I will put your order in. A new menu for each
meal will be on your food tray. Just turn it in with your tray each meal.");
Console.WriteLine("Thank you.");
foreach (bool l1 in nurseMovement("nurse", Move, new
ListPair("nurse", new ListPair("nurse_room", Atom.NIL))))
Console.WriteLine("The nurse location is " + Move.getValue());
Console.WriteLine("\nPress Enter to finish.");
Console.ReadLine();
}
static IEnumerable<bool> nurseRequest(object patient, object Action,
object Request)
{
ListPair action1 = new ListPair(Action, Atom.NIL);
ListPair result = new ListPair(patient, action1);
foreach (bool l1 in YP.unify(Request, result))
yield return false;
}
static IEnumerable<bool> nurseMovement(object nurse, object Move, object
Location)
{
ListPair move1 = new ListPair(Move, Atom.NIL);
ListPair location = new ListPair(nurse, move1);
foreach (bool l1 in YP.unify(Location, location))
yield return false;
}
}
6.2 Method Two – Wrapping
This method allows a wrapping of prolog to the C# language and will assist with encoding
prolog functions and larger prolog code, including the search limiting ‘cut’ operator.
Prolog Function – Author: May Zeineldin ‘ scenario10‘
request(patient,sit_up):-push(patient,'Call button').
push(patient,'Call button'):chat_command('Can I help you'),
chat_command('Yes,I would like to sit up'),
goto(free_nurse,room),
action('Bed upright position').
Prolog Function using Wrapping
/*
* CallNurse_Prolog
*
* This class specifies the behavior allow a patient to call a nurse
* for assistance.
*
* Author: Dameon G Rogers
*/
using
using
using
using
System;
System.IO;
System.Collections.Generic;
YieldProlog;
class CalllNurse
{
static void Main(string[] args)
{
YP.assertFact(Atom.a("request"),
new object[] { Atom.a("patient"), Atom.a("sit up") });
YP.assertFact(Atom.a("push"),
new object[] { Atom.a("patient"), Atom.a("Call button") });
YP.assertFact(Atom.a("goto"),
new object[] { Atom.a("nurse"), Atom.a("free room") });
YP.assertFact(Atom.a("action"),
new object[] { Atom.a("patient"), Atom.a("Bed upright
position")});
Variable Request = new Variable();
Console.WriteLine("Using dynamic assert:");
foreach (bool l1 in YP.matchDynamic
(Atom.a("request"), new object[]
{ Atom.a("patient"), Request}))
Console.WriteLine("Patient has request " +
Request.getValue() + ".");
Variable Push = new Variable();
Console.WriteLine("Using dynamic assert:");
foreach (bool l1 in YP.matchDynamic
(Atom.a("push"), new object[]
{ Atom.a("patient"), Push}))
Console.WriteLine("Patient has pushed " +
Push.getValue() + ".");
string prologCode =
"request(Patient, sit_up) :- \n" +
"push(patient,’Call button’). \n” +
"goto(free_nurse, room), \n” +
"action(‘Bed upright’). \n”;
Console.WriteLine("\n// Compiled code:");
compileAndWrite(prologCode);
Console.WriteLine("Calling compiled code having a dynamic goal:");
Variable Patient = new Variable();
Variable Request = new Variable();
foreach (bool l1 in uncle(Patient, Request))
Console.WriteLine(Patient.getValue() +
" has request " + Request.getValue() + ".");
Console.WriteLine("\nPress Enter to finish.");
Console.ReadLine();
}
static void compileAndWrite(string prologCode)
{
YP.tell(Console.Out);
YP.see(new StringReader(prologCode));
Variable TermList = new Variable();
Variable PseudoCode = new Variable();
foreach (bool l1 in Parser.parseInput(TermList))
{
foreach (bool l2 in Compiler.makeFunctionPseudoCode
(TermList, PseudoCode))
Compiler.convertFunctionCSharp(PseudoCode);
}
YP.seen();
}
public class YPInnerClass { }
public static Type getDeclaringClass()
{
return typeof(YPInnerClass).DeclaringType;
}
public static IEnumerable<bool> action
(object Patient, object Action)
{
foreach (bool l1 in YP.unify
(Patient, Atom.a("Patient")))
{
foreach (bool l2 in YP.unify
(Action, Atom.a("Call Button")))
yield return false;
}
foreach (bool l1 in YP.unify
(Patient, Atom.a("Patient")))
{
foreach (bool l2 in YP.unify
(Action, Atom.a("Upright Position")))
yield return false;
}
}
}
This code only asserts two facts dynamically for display that are actions from a patient to help to define the actions
that a patient is able to perform in this specific instance to call a nurse to place a patient in the upright position. The
main difference between this form of wrapper and the translation is that the facts are asserted at the beginning of the
code, then the prolog code is wrapper and then inner classes are constructed to logically link and define the patient
actions.
More information and complete tutorials available at: http://yieldprolog.sourceforge.net/
If possible it is be to get a minimum understanding of prolog and the use of the ‘cut’ operator here:
http://cs.union.edu/~striegnk/learn-prolog-now/
7. Conclusions
7.1 Summary
It was challenging to code on C# since it was a new language for this assignment but it was fun
to get the functionality that is possible with Prolog into a different language and discover that the
Prolog code can be wrapped with C# or converted into C# as they both work. It is also possible
to code into Mono instead and not uses Visual Studio in any way.
7.2 Impact
Since the logical functionality of Prolog is possible as a C# import to OpenSim this means that
any and all of the functions needed to make the hospital actually work will able to support the
actions needed. This means that the workflow goal of my sub team is solved and success has
been achieved.
7.3 Future Work
The next person needs to try to get a bigger idea of the logic needed for this project, for example,
a basic set of actions and tasks that are needed to make the hospital simulation function. This
will allow C# code, which behaves like Prolog, to support all the tasks and actions that are
required to make the hospital function to assist in the research of workflow in a medical setting.
References
[1]
Yield Prolog. Sourceforge.NET. 15 Oct. 2008
http://yieldprolog.sourceforge.net/index.html/.
Download