aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/YieldProlog/README.TXT
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/YieldProlog/README.TXT')
-rw-r--r--OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/YieldProlog/README.TXT514
1 files changed, 0 insertions, 514 deletions
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/YieldProlog/README.TXT b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/YieldProlog/README.TXT
deleted file mode 100644
index 3c11938..0000000
--- a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/YieldProlog/README.TXT
+++ /dev/null
@@ -1,514 +0,0 @@
1YPOS: YieldProlog for OpenSim
2
3 a compiler from Prolog to OpenSim compatible C# scripts
4
5Ported by Kino Coursey and Douglas Miles at Daxtron Labs.
6Based on Jeff Thompson Yield Prolog, http://yieldprolog.sourceforge.net/
7For Prolog see http://en.wikipedia.org/wiki/Prolog
8
9
10INTRODUCTION
11
12This folder contains code to implement a Prolog compiler using the "Yield Statement" found in C#, Javascript, and Python.
13The original Yield Prolog system can transform Prolog programs into C# code.
14In this system we detect and extract YieldProlog code (with "//YP" as the first four characters in the script) and seperate it from any c# code ("marked by "//CS").
15The YP code is transformed to C# and prepended to the "//CS" section, and passed as a bundel to the existing C# compiler.
16The end result is Prolog can interface to OpenSim using the existing "//CS" functionality, and C# can call the compiled Prolog.
17As such YP allows both declaritive and procedural programming in a 3D script enabled environment.
18
19FEATURES
20* Allows implementation of logic programming for objects and agents.
21* C#/Javascript/Python as intermediate language
22* Yield Prolog has relatively high speed of execution which is important in OpenSim. http://yieldprolog.sourceforge.net/benchmarks.html
23* It is compatable with the existing C#/Mono based system.
24* Yield Prolog is BSD license
25* Calling Prolog from C# scripts
26* Calling C# functions (with LSL and OS functions) from Prolog
27* Prolog dynamic database
28* Edinburgh, Cocksin & Mellish style syntax.
29* Compiler is generated by compiling the Prolog descrition of itself into C#
30* Same script entry interface as LSL
31
32* Yield Prolog 1.0.1 Released : it passes all but 9 of the 421 tests in the ISO Prolog test suite (97.8%).
33
34TODO
35* Utilize ability to generate Javascript and Python code
36* Integrate Prolog database with Sim
37* Translation error reporting back to the editor
38* Communications via message passing
39* Interface to external inference engines
40
41POSSIBILITIES
42* Inworld expert systems
43* Parallel logic programming and expert systems
44* Ontology based processing
45* Knowledge based alerting, accessing and business rules
46 For instance, listen on channel x, filter the events and broadcast alerts on channel y
47 or send IM, emails etc.
48
49
50USAGE:
51
52Add "yp" as an allowed compiler
53
54OpenSim.ini
55[ScriptEngine.DotNetEngine]
56AllowedCompilers=lsl,cs,js,vb,yp
57
58Enter scripts using the inworld editing process. Scripts have the following format.
59The first line of a file must have "//yp".
60
61//yp
62<PROLOG CODE>
63//CS
64<CS CODE>
65
66
67
68
69
70
71C# code calling a Prolog Predicate:
72-----------------------------------
73The Prolog predicate is transformed into a C# boolean function. So the general calling format is:
74 foreach( bool var in prolog_predicate(ARGS)) {};
75
76I/O is via using a string reader and writer in conjunction with YP.See() and YP.Tell()
77
78 StringWriter PrologOutuput= new StringWriter();
79 StringReader PrologInput= new StringReader(myInputString);
80 YP.see(PrologInput);
81 YP.tell(PrologOutuput);
82 <CALL PROLOG CODE HERE>
83 YP.seen();
84 YP.told();
85 StringBuilder builder = PrologOutput.GetStringBuilder();
86 string finaloutput = builder.ToString();
87
88Any prolog reads and writes will be to the passed StringReader and StringWriter. In fact any TextReader/TextWriter class can be used.
89
90Strings in Prolog are stored as Atom's and you need to use an Atom object to match.
91
92\\yp
93wanted('bob').
94\\cs
95string Who="bob";
96foreach( bool ans in wanted(Atom.a(Who) )){};
97
98
99Prolog code calling a C# function:
100-----------------------------------
101The prolog code uses the script_event('name_of_function',ARGS) builtin, which is transformed into the function call.
102The C# function called uses "PrologCallback" and returns a boolean.
103
104
105
106Dynamic database assertions:
107-----------------------------------
108
109void assertdb2(string predicate, string arg1, string arg2)
110{
111 name = Atom.a(predicate);
112 YP.assertFact(name, new object[] { arg1, arg2 });
113}
114
115void retractdb2(string predicate, string arg1, string arg2)
116{
117 name = Atom.a(predicate);
118 YP.retractFact(name, new object[] { arg1, arg2 });
119}
120
121----------- IMPORT EXTERNAL FUNCTIONS ----------
122Using 'import' to call a static function
123
124Taken mostly from http://yieldprolog.sourceforge.net/tutorial4.html
125
126If we want to call a static function but it is not defined in the Prolog code, we can simply add an import directive.
127(In Prolog, if you start a line with :- it is a directive to the compiler. Don't forget to end with a period.):
128
129:- import('', [parent/2]).
130uncle(Person, Uncle):- parent(Person, Parent), brother(Parent, Uncle).
131
132The import directive has two arguments.
133The first argument is the module where the imported function is found, which is always ''.
134For C#, this means the imported function is in the same class as the calling function.
135For Javascript and Python, this means the imported function is in the global scope.
136The second argument to import is the comma-separated list of imported functions, where each member of the list is 'name/n', where 'name' is the name of the function and 'n' is the number of arguments.
137In this example, parent has two arguments, so we use parent/2.
138
139Note: you can use an imported function in a dynamically defined goal, or a function in another class.
140
141:- import('', [parent/2]).
142uncle(Person, Uncle) :- Goal = parent(Person, Parent), Goal, brother(Parent, Uncle).
143
144:- import('', ['OtherClass.parent'/2]).
145uncle(Person, Uncle) :- 'OtherClass.parent'(Person, Parent), brother(Parent, Uncle).
146
147--------- Round-about Hello Wonderful world ----------
148//yp
149:-import('',[sayit/1]).
150sayhello(X):-sayit(X).
151
152//cs
153public void default_event_state_entry()
154 {
155 llSay(0,"prolog hello.");
156 foreach( bool ans in sayhello(Atom.a(@"wonderful world") )){};
157 }
158
159PrologCallback sayit(object ans)
160 {
161 llSay(0,"sayit1");
162 string msg = "one answer is :"+((Variable)ans).getValue();
163 llSay(0,msg);
164 yield return false;
165 }
166
167------------------ UPDATES -----------------
168Yield Prolog 1.0 Released : It passes all but 15 of the 421 tests in the ISO Prolog test suite.
169
170New Features:
171* Added support for Prolog predicates read and read_term.
172* In see, Added support for a char code list as the input.
173Using this as the input for "fred" makes
174set_prolog_flag(double_quotes, atom) and
175set_prolog_flag(double_quotes, chars) pass the ISO test suite.
176
177Fixed Bugs:
178* In atom_chars, check for unbound tail in the char list.
179This makes atom_chars pass the ISO test suite.
180* In current_predicate, also check for static functions.
181This makes current_predicate pass the ISO test suite.
182
183Known Issues:
184
185Here are the 9 errors of the 421 tests in the ISO test suite in
186YieldProlog\source\prolog\isoTestSuite.P .
187Some of these have a good excuse for why Yield Prolog produces the error. The rest will be addressed in a future maintenance release.
188
189Goal: call((fail, 1))
190Expected: type_error(callable, (fail, 1))
191Extra Solutions found: failure
192
193Goal: call((write(3), 1))
194Expected: type_error(callable, (write(3), 1))
195Extra Solutions found: type_error(callable, 1)
196
197Goal: call((1; true))
198Expected: type_error(callable, (1 ; true))
199Extra Solutions found: type_error(callable, 1)
200
201Goal: (catch(true, C, write('something')), throw(blabla))
202Expected: system_error
203Extra Solutions found: unexpected_ball(blabla)
204
205Goal: catch(number_chars(A,L), error(instantiation_error, _), fail)
206Expected: failure
207Extra Solutions found: instantiation_error
208
209Goal: Goal: (X = 1 + 2, 'is'(Y, X * 3))
210Expected: [[X <-- (1 + 2), Y <-- 9]]
211Extra Solutions found: type_error(evaluable, /(+, 2))
212
213Goal: 'is'(77, N)
214Expected: instantiation_error
215Extra Solutions found: N <-- 77)
216
217Goal: \+(!, fail)
218Expected: success
219Extra Solutions found: failure
220
221((X=1;X=2), \+((!,fail)))
222Expected: [[X <-- 1],[X <-- 2]]
223Extra Solutions found: failure
224
225
226
227
228
229========================= APPENDIX A: touch test ================================
230
231
232 ===================================
233Input YP Code
234 ===================================
235//yp
236 mydb('field2','field1').
237 mydb('andy','jane').
238 mydb('carl','dan').
239 mydb('andy','bill').
240 mydb('andy','betty').
241
242 call_me(X):-mydb(X,Y) , respond(Y).
243 respond(X):- script_event('sayit',X).
244
245//cs
246 public void default_event_touch_start(int N )
247 {
248 llSay(0,"pstart1");
249 foreach( bool ans in call_me(Atom.a(@"andy") )){};
250 llSay(0,"pstop2");
251 }
252
253 public void default_event_state_entry()
254 {
255 llSay(0,"prolog tester active.");
256 }
257
258PrologCallback sayit(object ans)
259 {
260 llSay(0,"sayit1");
261 string msg = "one answer is :"+((Variable)ans).getValue();
262 llSay(0,msg);
263 yield return false;
264 }
265
266
267 ===================================
268Generated CS Code
269 ===================================
270using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog;using OpenSim.Region.ScriptEngine.Common; using System.Collections.Generic;
271namespace SecondLife { public class Script : OpenSim.Region.ScriptEngine.Common.ScriptBaseClass {
272static OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog.YP YP=null;public Script() { YP= new OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog.YP(); }
273//cs
274 public void default_event_touch_start(int N )
275 {
276 llSay(0,"pstart1");
277 foreach( bool ans in call_me(Atom.a(@"carl") )){};
278 llSay(0,"pstop2");
279 }
280
281 public void default_event_state_entry()
282 {
283 llSay(0,"prolog tester active.");
284 }
285
286public IEnumerable<bool> sayit(object ans)
287 {
288 llSay(0,"sayit1");
289 string msg = "one answer is :"+((Variable)ans).getValue();
290 llSay(0,msg);
291 yield return false;
292 }
293
294
295//YPEncoded
296public IEnumerable<bool> mydb(object arg1, object arg2) {
297 {
298 foreach (bool l2 in YP.unify(arg1, Atom.a(@"carl"))) {
299 foreach (bool l3 in YP.unify(arg2, Atom.a(@"dan"))) {
300 yield return false;
301 }
302 }
303 }
304 {
305 foreach (bool l2 in YP.unify(arg1, Atom.a(@"andy"))) {
306 foreach (bool l3 in YP.unify(arg2, Atom.a(@"bill"))) {
307 yield return false;
308 }
309 }
310 }
311 {
312 foreach (bool l2 in YP.unify(arg1, Atom.a(@"andy"))) {
313 foreach (bool l3 in YP.unify(arg2, Atom.a(@"betty"))) {
314 yield return false;
315 }
316 }
317 }
318}
319
320public IEnumerable<bool> call_me(object X) {
321 {
322 Variable Y = new Variable();
323 foreach (bool l2 in mydb(X, Y)) {
324 foreach (bool l3 in respond(Y)) {
325 yield return false;
326 }
327 }
328 }
329}
330
331public IEnumerable<bool> respond(object X) {
332 {
333 foreach (bool l2 in this.sayit( X)) {
334 yield return false;
335 }
336 }
337}
338
339} }
340
341
342
343========================= APPENDIX B:SENSOR INFORMED SCRIPT =====================
344
345
346 ===================================
347Input YP Code
348 ===================================
349//yp
350
351nop.
352
353good('Daxxon Kinoc').
354good('Fluffy Kitty').
355
356bad('Eric Evil').
357bad('Spikey Plant').
358
359prolog_notify(X) :- good(X) , script_event('accept',X).
360prolog_notify(X) :- bad(X) , script_event('reject',X).
361
362
363//cs
364
365public void default_event_state_entry()
366 {
367 llSay(0,"prolog sensor tester active.");
368
369 // Start a sensor looking for Agents
370 llSensorRepeat("","",AGENT, 10, PI,20);
371
372 }
373
374public void default_event_sensor(int number_detected )
375{
376 int i;
377 for(i=0;i< number_detected ;i++)
378 {
379 string dName = llDetectedName(i);
380 string dOwner = llDetectedName(i);
381 foreach(bool response in prolog_notify(Atom.a(dName)) ){};
382 foreach(bool response in prolog_notify(dOwner) ){};
383 llSay(0,"Saw "+dName);
384 }
385}
386
387string decodeToString(object obj)
388{
389 if (obj is Variable) { return (string) ((Variable)obj).getValue();}
390 if (obj is Atom) { return (string) ((Atom)obj)._name;}
391 return "unknown type";
392}
393
394PrologCallback accept(object ans)
395 {
396 string msg = "Welcoming :"+decodeToString(ans);
397 llSay(0,msg);
398 yield return false;
399 }
400
401PrologCallback reject(object ans)
402 {
403 string msg = "Watching :"+decodeToString(ans);
404 llSay(0,msg);
405 yield return false;
406 }
407
408
409 ===================================
410Generated CS Code
411 ===================================
412
413using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog; using OpenSim.Region.ScriptEngine.Common; using System.Collections.Generic;
414namespace SecondLife { public class Script : OpenSim.Region.ScriptEngine.Common.ScriptBaseClass {
415static OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog.YP YP=null; public Script() { YP= new OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog.YP(); }
416//cs
417
418public void default_event_state_entry()
419 {
420 llSay(0,"prolog sensor tester active.");
421
422 // Start a sensor looking for Agents
423 llSensorRepeat("","",AGENT, 10, PI,20);
424
425 }
426
427public void default_event_sensor(int number_detected )
428{
429 int i;
430 for(i=0;i< number_detected ;i++)
431 {
432 string dName = llDetectedName(i);
433 string dOwner = llDetectedName(i);
434 foreach(bool response in prolog_notify(Atom.a(dName)) ){};
435 foreach(bool response in prolog_notify(dOwner) ){};
436 llSay(0,"Saw "+dName);
437 }
438}
439
440string decodeToString(object obj)
441{
442 if (obj is Variable) { return (string) ((Variable)obj).getValue();}
443 if (obj is Atom) { return (string) ((Atom)obj)._name;}
444 return "unknown type";
445}
446
447public IEnumerable<bool> accept(object ans)
448 {
449 string msg = "Welcoming :"+decodeToString(ans);
450 llSay(0,msg);
451 yield return false;
452 }
453
454public IEnumerable<bool> reject(object ans)
455 {
456 string msg = "Watching :"+decodeToString(ans);
457 llSay(0,msg);
458 yield return false;
459 }
460
461
462//YPEncoded
463public IEnumerable<bool> yp_nop_header_nop() {
464 {
465 yield return false;
466 }
467}
468
469public IEnumerable<bool> good(object arg1) {
470 {
471 foreach (bool l2 in YP.unify(arg1, Atom.a(@"Daxxon Kinoc"))) {
472 yield return false;
473 }
474 }
475 {
476 foreach (bool l2 in YP.unify(arg1, Atom.a(@"Fluffy Kitty"))) {
477 yield return false;
478 }
479 }
480}
481
482public IEnumerable<bool> bad(object arg1) {
483 {
484 foreach (bool l2 in YP.unify(arg1, Atom.a(@"Eric Evil"))) {
485 yield return false;
486 }
487 }
488 {
489 foreach (bool l2 in YP.unify(arg1, Atom.a(@"Spikey Plant"))) {
490 yield return false;
491 }
492 }
493}
494
495public IEnumerable<bool> prolog_notify(object X) {
496 {
497 foreach (bool l2 in good(X)) {
498 foreach (bool l3 in this.accept( X)) {
499 yield return false;
500 }
501 }
502 }
503 {
504 foreach (bool l2 in bad(X)) {
505 foreach (bool l3 in this.reject( X)) {
506 yield return false;
507 }
508 }
509 }
510}
511
512} }
513
514