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.TXT405
1 files changed, 405 insertions, 0 deletions
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/YieldProlog/README.TXT b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/YieldProlog/README.TXT
new file mode 100644
index 0000000..05186f1
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/YieldProlog/README.TXT
@@ -0,0 +1,405 @@
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
33TODO
34* Utilize ability to generate Javascript and Python code
35* Integrate Prolog database with Sim
36* Translation error reporting back to the editor
37* Communications via message passing
38* Interface to external inference engines
39
40POSSIBILITIES
41* Inworld expert systems
42* Parallel logic programming and expert systems
43* Ontology based processing
44* Knowledge based alerting, accessing and business rules
45 For instance, listen on channel x, filter the events and broadcast alerts on channel y
46 or send IM, emails etc.
47
48
49USAGE:
50
51Add "yp" as an allowed compiler
52
53OpenSim.ini
54[ScriptEngine.DotNetEngine]
55AllowedCompilers=lsl,cs,js,vb,yp
56
57Enter scripts using the inworld editing process. Scripts have the following format.
58The first line of a file must have "//yp".
59
60//yp
61<PROLOG CODE>
62//CS
63<CS CODE>
64
65
66
67
68
69
70C# code calling a Prolog Predicate:
71-----------------------------------
72The Prolog predicate is transformed into a C# boolean function. So the general calling format is:
73 foreach( bool var in prolog_predicate(ARGS)) {};
74
75I/O is via using a string reader and writer in conjunction with YP.See() and YP.Tell()
76
77 StringWriter PrologOutuput= new StringWriter();
78 StringReader PrologInput= new StringReader(myInputString);
79 YP.see(PrologInput);
80 YP.tell(PrologOutuput);
81 <CALL PROLOG CODE HERE>
82 YP.seen();
83 YP.told();
84 StringBuilder builder = PrologOutput.GetStringBuilder();
85 string finaloutput = builder.ToString();
86
87Any prolog reads and writes will be to the passed StringReader and StringWriter. In fact any TextReader/TextWriter class can be used.
88
89Strings in Prolog are stored as Atom's and you need to use an Atom object to match.
90
91\\yp
92wanted('bob').
93\\cs
94string Who="bob";
95foreach( bool ans in wanted(Atom.a(Who) )){};
96
97
98Prolog code calling a C# function:
99-----------------------------------
100The prolog code uses the script_event('name_of_function',ARGS) builtin, which is transformed into the function call.
101The C# function called uses "PrologCallback" and returns a boolean.
102
103
104
105Dynamic database assertions:
106-----------------------------------
107
108void assertdb2(string predicate, string arg1, string arg2)
109{
110 name = Atom.a(predicate);
111 YP.assertFact(name, new object[] { arg1, arg2 });
112}
113
114void retractdb2(string predicate, string arg1, string arg2)
115{
116 name = Atom.a(predicate);
117 YP.retractFact(name, new object[] { arg1, arg2 });
118}
119
120
121========================= APPENDIX A: touch test ================================
122
123
124 ===================================
125Input YP Code
126 ===================================
127//yp
128 mydb('field2','field1').
129 mydb('andy','jane').
130 mydb('carl','dan').
131 mydb('andy','bill').
132 mydb('andy','betty').
133
134 call_me(X):-mydb(X,Y) , respond(Y).
135 respond(X):- script_event('sayit',X).
136
137//cs
138 public void default_event_touch_start(int N )
139 {
140 llSay(0,"pstart1");
141 foreach( bool ans in call_me(Atom.a(@"andy") )){};
142 llSay(0,"pstop2");
143 }
144
145 public void default_event_state_entry()
146 {
147 llSay(0,"prolog tester active.");
148 }
149
150PrologCallback sayit(object ans)
151 {
152 llSay(0,"sayit1");
153 string msg = "one answer is :"+((Variable)ans).getValue();
154 llSay(0,msg);
155 yield return false;
156 }
157
158
159 ===================================
160Generated CS Code
161 ===================================
162using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog;using OpenSim.Region.ScriptEngine.Common; using System.Collections.Generic;
163namespace SecondLife { public class Script : OpenSim.Region.ScriptEngine.Common.BuiltIn_Commands_BaseClass {
164static OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog.YP YP=null;public Script() { YP= new OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog.YP(); }
165//cs
166 public void default_event_touch_start(int N )
167 {
168 llSay(0,"pstart1");
169 foreach( bool ans in call_me(Atom.a(@"carl") )){};
170 llSay(0,"pstop2");
171 }
172
173 public void default_event_state_entry()
174 {
175 llSay(0,"prolog tester active.");
176 }
177
178public IEnumerable<bool> sayit(object ans)
179 {
180 llSay(0,"sayit1");
181 string msg = "one answer is :"+((Variable)ans).getValue();
182 llSay(0,msg);
183 yield return false;
184 }
185
186
187//YPEncoded
188public IEnumerable<bool> mydb(object arg1, object arg2) {
189 {
190 foreach (bool l2 in YP.unify(arg1, Atom.a(@"carl"))) {
191 foreach (bool l3 in YP.unify(arg2, Atom.a(@"dan"))) {
192 yield return false;
193 }
194 }
195 }
196 {
197 foreach (bool l2 in YP.unify(arg1, Atom.a(@"andy"))) {
198 foreach (bool l3 in YP.unify(arg2, Atom.a(@"bill"))) {
199 yield return false;
200 }
201 }
202 }
203 {
204 foreach (bool l2 in YP.unify(arg1, Atom.a(@"andy"))) {
205 foreach (bool l3 in YP.unify(arg2, Atom.a(@"betty"))) {
206 yield return false;
207 }
208 }
209 }
210}
211
212public IEnumerable<bool> call_me(object X) {
213 {
214 Variable Y = new Variable();
215 foreach (bool l2 in mydb(X, Y)) {
216 foreach (bool l3 in respond(Y)) {
217 yield return false;
218 }
219 }
220 }
221}
222
223public IEnumerable<bool> respond(object X) {
224 {
225 foreach (bool l2 in this.sayit( X)) {
226 yield return false;
227 }
228 }
229}
230
231} }
232
233
234
235========================= APPENDIX B:SENSOR INFORMED SCRIPT =====================
236
237
238 ===================================
239Input YP Code
240 ===================================
241//yp
242
243nop.
244
245good('Daxxon Kinoc').
246good('Fluffy Kitty').
247
248bad('Eric Evil').
249bad('Spikey Plant').
250
251prolog_notify(X) :- good(X) , script_event('accept',X).
252prolog_notify(X) :- bad(X) , script_event('reject',X).
253
254
255//cs
256
257public void default_event_state_entry()
258 {
259 llSay(0,"prolog sensor tester active.");
260
261 // Start a sensor looking for Agents
262 llSensorRepeat("","",AGENT, 10, PI,20);
263
264 }
265
266public void default_event_sensor(int number_detected )
267{
268 int i;
269 for(i=0;i< number_detected ;i++)
270 {
271 string dName = llDetectedName(i);
272 string dOwner = llDetectedName(i);
273 foreach(bool response in prolog_notify(Atom.a(dName)) ){};
274 foreach(bool response in prolog_notify(dOwner) ){};
275 llSay(0,"Saw "+dName);
276 }
277}
278
279string decodeToString(object obj)
280{
281 if (obj is Variable) { return (string) ((Variable)obj).getValue();}
282 if (obj is Atom) { return (string) ((Atom)obj)._name;}
283 return "unknown type";
284}
285
286PrologCallback accept(object ans)
287 {
288 string msg = "Welcoming :"+decodeToString(ans);
289 llSay(0,msg);
290 yield return false;
291 }
292
293PrologCallback reject(object ans)
294 {
295 string msg = "Watching :"+decodeToString(ans);
296 llSay(0,msg);
297 yield return false;
298 }
299
300
301 ===================================
302Generated CS Code
303 ===================================
304
305using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog; using OpenSim.Region.ScriptEngine.Common; using System.Collections.Generic;
306namespace SecondLife { public class Script : OpenSim.Region.ScriptEngine.Common.BuiltIn_Commands_BaseClass {
307static OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog.YP YP=null; public Script() { YP= new OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.YieldProlog.YP(); }
308//cs
309
310public void default_event_state_entry()
311 {
312 llSay(0,"prolog sensor tester active.");
313
314 // Start a sensor looking for Agents
315 llSensorRepeat("","",AGENT, 10, PI,20);
316
317 }
318
319public void default_event_sensor(int number_detected )
320{
321 int i;
322 for(i=0;i< number_detected ;i++)
323 {
324 string dName = llDetectedName(i);
325 string dOwner = llDetectedName(i);
326 foreach(bool response in prolog_notify(Atom.a(dName)) ){};
327 foreach(bool response in prolog_notify(dOwner) ){};
328 llSay(0,"Saw "+dName);
329 }
330}
331
332string decodeToString(object obj)
333{
334 if (obj is Variable) { return (string) ((Variable)obj).getValue();}
335 if (obj is Atom) { return (string) ((Atom)obj)._name;}
336 return "unknown type";
337}
338
339public IEnumerable<bool> accept(object ans)
340 {
341 string msg = "Welcoming :"+decodeToString(ans);
342 llSay(0,msg);
343 yield return false;
344 }
345
346public IEnumerable<bool> reject(object ans)
347 {
348 string msg = "Watching :"+decodeToString(ans);
349 llSay(0,msg);
350 yield return false;
351 }
352
353
354//YPEncoded
355public IEnumerable<bool> yp_nop_header_nop() {
356 {
357 yield return false;
358 }
359}
360
361public IEnumerable<bool> good(object arg1) {
362 {
363 foreach (bool l2 in YP.unify(arg1, Atom.a(@"Daxxon Kinoc"))) {
364 yield return false;
365 }
366 }
367 {
368 foreach (bool l2 in YP.unify(arg1, Atom.a(@"Fluffy Kitty"))) {
369 yield return false;
370 }
371 }
372}
373
374public IEnumerable<bool> bad(object arg1) {
375 {
376 foreach (bool l2 in YP.unify(arg1, Atom.a(@"Eric Evil"))) {
377 yield return false;
378 }
379 }
380 {
381 foreach (bool l2 in YP.unify(arg1, Atom.a(@"Spikey Plant"))) {
382 yield return false;
383 }
384 }
385}
386
387public IEnumerable<bool> prolog_notify(object X) {
388 {
389 foreach (bool l2 in good(X)) {
390 foreach (bool l3 in this.accept( X)) {
391 yield return false;
392 }
393 }
394 }
395 {
396 foreach (bool l2 in bad(X)) {
397 foreach (bool l3 in this.reject( X)) {
398 yield return false;
399 }
400 }
401 }
402}
403
404} }
405