PageRenderTime 57ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 1ms

/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/YPCompiler.cs

https://bitbucket.org/AlethiaGrid/opensimulator-0.7-.x
C# | 6382 lines | 6162 code | 80 blank | 140 comment | 138 complexity | 61e83ffe5567d2acb1bab3a61d02c6e6 MD5 | raw file
Possible License(s): MIT, BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * Copyright (C) 2007-2008, Jeff Thompson
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are met:
  8. *
  9. * * Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * * Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * * Neither the name of the copyright holder nor the names of its contributors
  15. * may be used to endorse or promote products derived from this software
  16. * without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  22. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  23. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  24. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  25. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  26. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  27. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. using System;
  31. using System.IO;
  32. using System.Collections;
  33. using System.Collections.Generic;
  34. using System.Text;
  35. using System.CodeDom.Compiler;
  36. using System.Reflection;
  37. namespace OpenSim.Region.ScriptEngine.Shared.YieldProlog
  38. {
  39. public class YPCompiler
  40. {
  41. private class CompilerState
  42. {
  43. public IndexedAnswers _pred = new IndexedAnswers(4);
  44. public Dictionary<YP.NameArity, Atom> _moduleForNameArity = new Dictionary<YP.NameArity, Atom>();
  45. public int _gensymCounter;
  46. public bool _useFinalCutCode;
  47. public Variable _finalCutCode;
  48. public bool _codeUsesYield;
  49. public Atom _determinism;
  50. // a list of '='(Name, Variable)
  51. public List<object> _variableNames;
  52. // Make these static functions that explicitly take the State so Prolog can call it.
  53. /// <summary>
  54. /// Make a new CompilerState and bind it to State.
  55. /// </summary>
  56. /// <param name="State"></param>
  57. /// <returns></returns>
  58. public static IEnumerable<bool> make(object State)
  59. {
  60. return YP.unify(State, new CompilerState());
  61. }
  62. public static void assertPred(object State, object Pred, object Determinism)
  63. {
  64. State = YP.getValue(State);
  65. object functorName = YP.getFunctorName(Pred);
  66. object[] functorArgs = YP.getFunctorArgs(Pred);
  67. // Debug: Should check if it's already asserted and is the same.
  68. ((CompilerState)State)._pred.addAnswer
  69. (new object[] { functorName, functorArgs.Length, Pred, YP.getValue(Determinism) });
  70. }
  71. public static void assertModuleForNameArity(object State, object Name, object Arity, object Module)
  72. {
  73. State = YP.getValue(State);
  74. Name = YP.getValue(Name);
  75. Arity = YP.getValue(Arity);
  76. Module = YP.getValue(Module);
  77. // If the Module Atom comes from the parser, it always has null _declaringClass.
  78. if (Module is Atom && ((Atom)Module)._module == null && Name is Atom && Arity is int)
  79. // Replace a previous entry if it exists.
  80. ((CompilerState)State)._moduleForNameArity[new YP.NameArity((Atom)Name, (int)Arity)] =
  81. (Atom)Module;
  82. }
  83. public static void startFunction(object State, object Head)
  84. {
  85. State = YP.getValue(State);
  86. ((CompilerState)State)._gensymCounter = 0;
  87. ((CompilerState)State)._useFinalCutCode = false;
  88. ((CompilerState)State)._finalCutCode = new Variable();
  89. ((CompilerState)State)._codeUsesYield = false;
  90. if (CompilerState.isDetNoneOut(State, Head))
  91. ((CompilerState)State)._determinism = Atom.a("detNoneOut");
  92. else if (CompilerState.isSemidetNoneOut(State, Head))
  93. ((CompilerState)State)._determinism = Atom.a("semidetNoneOut");
  94. else
  95. ((CompilerState)State)._determinism = Atom.a("nondet");
  96. }
  97. public static void setCodeUsesYield(object State)
  98. {
  99. State = YP.getValue(State);
  100. ((CompilerState)State)._codeUsesYield = true;
  101. }
  102. public static bool codeUsesYield(object State)
  103. {
  104. State = YP.getValue(State);
  105. return ((CompilerState)State)._codeUsesYield;
  106. }
  107. public static bool determinismEquals(object State, object Term)
  108. {
  109. State = YP.getValue(State);
  110. return YP.termEqual(((CompilerState)State)._determinism, Term);
  111. }
  112. /// <summary>
  113. /// Set _variableNames to a new list of (Name = Variable) for each unique variable in rule.
  114. /// If the variable is in variableNameSuggestions, use it, otherwise use x1, x2, etc.
  115. /// </summary>
  116. /// <param name="State"></param>
  117. /// <param name="rule"></param>
  118. /// <param name="variableNameSuggestions"></param>
  119. public static void newVariableNames(object State, object Rule, object VariableNameSuggestions)
  120. {
  121. State = YP.getValue(State);
  122. List<Variable> variablesSet = new List<Variable>();
  123. YP.addUniqueVariables(Rule, variablesSet);
  124. ((CompilerState)State)._variableNames = new List<object>();
  125. int xCounter = 0;
  126. foreach (Variable variable in variablesSet)
  127. ((CompilerState)State)._variableNames.Add
  128. (new Functor2(Atom.a("="), makeVariableName(variable, VariableNameSuggestions, ++xCounter),
  129. variable));
  130. }
  131. private static object makeVariableName(object variable, object variableNameSuggestions, int xCounter)
  132. {
  133. // Debug: should require named variables to start with _ or capital. Should
  134. // check for duplicates and clashes with keywords.
  135. for (object element = YP.getValue(variableNameSuggestions);
  136. element is Functor2 && ((Functor2)element)._name == Atom.DOT;
  137. element = YP.getValue(((Functor2)element)._arg2))
  138. {
  139. object suggestionPair = YP.getValue(((Functor2)element)._arg1);
  140. if (sameVariable(variable, ((Functor2)suggestionPair)._arg2))
  141. {
  142. Atom suggestion = (Atom)YP.getValue(((Functor2)suggestionPair)._arg1);
  143. if (suggestion.Equals(Atom.a("Atom")))
  144. suggestion = Atom.a("Atom_1");
  145. if (suggestion.Equals(Atom.a("Variable")))
  146. suggestion = Atom.a("Variable_1");
  147. if (suggestion.Equals(Atom.a("Functor")))
  148. suggestion = Atom.a("Functor_1");
  149. return suggestion;
  150. }
  151. }
  152. return Atom.a("x" + xCounter);
  153. }
  154. /// <summary>
  155. /// Unify Result with the name assigned by CompilerState.newVariableNames in State._variableNames
  156. /// for variable.
  157. /// </summary>
  158. /// <param name="variable">a Variable</param>
  159. /// <param name="State"></param>
  160. /// <param name="Result">the assigned Name</param>
  161. public static IEnumerable<bool> getVariableName(object State, object variable, object Result)
  162. {
  163. State = YP.getValue(State);
  164. foreach (object variableInfo in ((CompilerState)State)._variableNames)
  165. {
  166. if (variableInfo is Functor2 && ((Functor2)variableInfo)._name.Equals(Atom.a("=")))
  167. {
  168. if (sameVariable(variable, ((Functor2)variableInfo)._arg2))
  169. return YP.unify(Result, ((Functor2)variableInfo)._arg1);
  170. }
  171. }
  172. // We set up names for all unique variables, so this should never happen.
  173. throw new PrologException(Atom.a("Can't find entry in _variableNames"));
  174. }
  175. public static IEnumerable<bool> variableNamesList(object State, object VariableNamesList)
  176. {
  177. State = YP.getValue(State);
  178. return YP.unify(VariableNamesList, ListPair.make(((CompilerState)State)._variableNames));
  179. }
  180. public static IEnumerable<bool> gensym(object State, object Base, object Symbol)
  181. {
  182. State = YP.getValue(State);
  183. return YP.unify(Symbol, Atom.a(Base.ToString() + ++((CompilerState)State)._gensymCounter));
  184. }
  185. // disable warning on l1, don't see how we can
  186. // code this differently
  187. #pragma warning disable 0168, 0164, 0162, 0219
  188. public static bool isDetNoneOut(object State, object Term)
  189. {
  190. State = YP.getValue(State);
  191. object functorName = YP.getFunctorName(Term);
  192. object[] functorArgs = YP.getFunctorArgs(Term);
  193. Variable pred = new Variable();
  194. foreach (bool l1 in ((CompilerState)State)._pred.match
  195. (new object[] { functorName, functorArgs.Length, pred, Atom.a("det") }))
  196. {
  197. if (CompilerState.isNoneOut(YP.getFunctorArgs(pred.getValue())))
  198. {
  199. return true;
  200. }
  201. }
  202. return false;
  203. }
  204. public static bool isSemidetNoneOut(object State, object Term)
  205. {
  206. State = YP.getValue(State);
  207. object functorName = YP.getFunctorName(Term);
  208. object[] functorArgs = YP.getFunctorArgs(Term);
  209. Variable pred = new Variable();
  210. foreach (bool l1 in ((CompilerState)State)._pred.match
  211. (new object[] { functorName, functorArgs.Length, pred, Atom.a("semidet") }))
  212. {
  213. if (CompilerState.isNoneOut(YP.getFunctorArgs(pred.getValue())))
  214. {
  215. return true;
  216. }
  217. }
  218. return false;
  219. }
  220. #pragma warning restore 0168, 0164, 0162, 0219
  221. /// <summary>
  222. /// Return false if any of args is out, otherwise true.
  223. /// args is an array of ::(Type,Mode) where Mode is in or out.
  224. /// </summary>
  225. /// <param name="args"></param>
  226. /// <returns></returns>
  227. private static bool isNoneOut(object[] args)
  228. {
  229. foreach (object arg in args)
  230. {
  231. if (arg is Functor2 && ((Functor2)arg)._name == Atom.a("::") &&
  232. ((Functor2)arg)._arg2 == Atom.a("out"))
  233. return false;
  234. }
  235. return true;
  236. }
  237. public static bool nameArityHasModule(object State, object Name, object Arity, object Module)
  238. {
  239. State = YP.getValue(State);
  240. Name = YP.getValue(Name);
  241. Arity = YP.getValue(Arity);
  242. Module = YP.getValue(Module);
  243. if (Name is Atom && Arity is int)
  244. {
  245. Atom FoundModule;
  246. if (!((CompilerState)State)._moduleForNameArity.TryGetValue
  247. (new YP.NameArity((Atom)Name, (int)Arity), out FoundModule))
  248. return false;
  249. return FoundModule == Module;
  250. }
  251. return false;
  252. }
  253. }
  254. // disable warning on l1, don't see how we can
  255. // code this differently
  256. #pragma warning disable 0168, 0219,0164,0162
  257. /// <summary>
  258. /// Use makeFunctionPseudoCode, convertFunctionCSharp and compileAnonymousFunction
  259. /// to return an anonymous YP.IClause for the Head and Body of a rule clause.
  260. /// </summary>
  261. /// <param name="Head">a prolog term such as new Functor2("test1", X, Y).
  262. /// Note that the name of the head is ignored.
  263. /// </param>
  264. /// <param name="Body">a prolog term such as
  265. /// new Functor2(",", new Functor1(Atom.a("test2", Atom.a("")), X),
  266. /// new Functor2("=", Y, X)).
  267. /// This may not be null. (For a head-only clause, set the Body to Atom.a("true").
  268. /// </param>
  269. /// <param name="declaringClass">if not null, the code is compiled as a subclass of this class
  270. /// to resolve references to the default module Atom.a("")</param>
  271. /// <returns>a new YP.IClause object on which you can call match(object[] args) where
  272. /// args length is the arity of the Head</returns>
  273. public static YP.IClause compileAnonymousClause(object Head, object Body, Type declaringClass)
  274. {
  275. object[] args = YP.getFunctorArgs(Head);
  276. // compileAnonymousFunction wants "function".
  277. object Rule = new Functor2(Atom.RULE, Functor.make("function", args), Body);
  278. object RuleList = ListPair.make(new Functor2(Atom.F, Rule, Atom.NIL));
  279. StringWriter functionCode = new StringWriter();
  280. Variable SaveOutputStream = new Variable();
  281. foreach (bool l1 in YP.current_output(SaveOutputStream))
  282. {
  283. try
  284. {
  285. YP.tell(functionCode);
  286. Variable PseudoCode = new Variable();
  287. foreach (bool l2 in makeFunctionPseudoCode(RuleList, PseudoCode))
  288. {
  289. if (YP.termEqual(PseudoCode, Atom.a("getDeclaringClass")))
  290. // Ignore getDeclaringClass since we have access to the one passed in.
  291. continue;
  292. convertFunctionCSharp(PseudoCode);
  293. }
  294. YP.told();
  295. }
  296. finally
  297. {
  298. // Restore after calling tell.
  299. YP.tell(SaveOutputStream.getValue());
  300. }
  301. }
  302. return YPCompiler.compileAnonymousFunction
  303. (functionCode.ToString(), args.Length, declaringClass);
  304. }
  305. /// <summary>
  306. /// Use CodeDomProvider to compile the functionCode and return a YP.ClauseHeadAndBody
  307. /// which implements YP.IClause.
  308. /// The function name must be "function" and have nArgs arguments.
  309. /// </summary>
  310. /// <param name="functionCode">the code for the iterator, such as
  311. /// "public static IEnumerable<bool> function() { yield return false; }"
  312. /// </param>
  313. /// <param name="nArgs">the number of args in the function</param>
  314. /// <param name="declaringClass">if not null, then use the functionCode inside a class which
  315. /// inherits from contextClass, so that references in functionCode to methods in declaringClass don't
  316. /// have to be qualified</param>
  317. /// <returns>a new YP.IClause object on which you can call match(object[] args) where
  318. /// args length is nArgs</returns>
  319. public static YP.IClause compileAnonymousFunction(string functionCode, int nArgs, Type declaringClass)
  320. {
  321. CompilerParameters parameters = new CompilerParameters();
  322. // This gets the location of the System assembly.
  323. parameters.ReferencedAssemblies.Add(typeof(System.Int32).Assembly.Location);
  324. // This gets the location of this assembly which also has YieldProlog.YP, etc.
  325. parameters.ReferencedAssemblies.Add(typeof(YPCompiler).Assembly.Location);
  326. if (declaringClass != null)
  327. parameters.ReferencedAssemblies.Add(declaringClass.Assembly.Location);
  328. parameters.GenerateInMemory = true;
  329. StringBuilder sourceCode = new StringBuilder();
  330. sourceCode.Append(@"
  331. using System;
  332. using System.Collections.Generic;
  333. using OpenSim.Region.ScriptEngine.Shared.YieldProlog;
  334. namespace Temporary {
  335. public class Temporary : YP.ClauseHeadAndBody, YP.IClause {");
  336. if (declaringClass == null)
  337. // We don't extend a class with getDeclaringClass, so define it.
  338. sourceCode.Append(@"
  339. public class Inner {
  340. public static System.Type getDeclaringClass() { return null; }
  341. ");
  342. else
  343. sourceCode.Append(@"
  344. public class Inner : " + declaringClass.FullName + @" {
  345. ");
  346. sourceCode.Append(functionCode);
  347. // Basically, match applies the args to function.
  348. sourceCode.Append(@"
  349. }
  350. public IEnumerable<bool> match(object[] args) {
  351. return Inner.function(");
  352. if (nArgs >= 1)
  353. sourceCode.Append("args[0]");
  354. for (int i = 1; i < nArgs; ++i)
  355. sourceCode.Append(", args[" + i + "]");
  356. sourceCode.Append(@");
  357. }
  358. }
  359. }
  360. ");
  361. CompilerResults results = CodeDomProvider.CreateProvider
  362. ("CSharp").CompileAssemblyFromSource(parameters, sourceCode.ToString());
  363. if (results.Errors.Count > 0)
  364. throw new Exception("Error evaluating code: " + results.Errors[0]);
  365. // Return a new Temporary.Temporary object.
  366. return (YP.IClause)results.CompiledAssembly.GetType
  367. ("Temporary.Temporary").GetConstructor(Type.EmptyTypes).Invoke(null);
  368. }
  369. /// <summary>
  370. /// If the functor with name and args can be called directly as determined by
  371. /// functorCallFunctionName, then call it and return its iterator. If the predicate is
  372. /// dynamic and undefined, or if static and the method cannot be found, return
  373. /// the result of YP.unknownPredicate.
  374. /// This returns null if the functor has a special form than needs to be compiled
  375. /// (including ,/2 and ;/2).
  376. /// </summary>
  377. /// <param name="name"></param>
  378. /// <param name="args"></param>
  379. /// <param name="declaringClass">used to resolve references to the default
  380. /// module Atom.a(""). If a declaringClass is needed to resolve the reference but it is
  381. /// null, this throws a PrologException for existence_error</param>
  382. /// <returns></returns>
  383. public static IEnumerable<bool> getSimpleIterator(Atom name, object[] args, Type declaringClass)
  384. {
  385. CompilerState state = new CompilerState();
  386. Variable FunctionName = new Variable();
  387. foreach (bool l1 in functorCallFunctionName(state, name, args.Length, FunctionName))
  388. {
  389. Atom functionNameAtom = ((Atom)FunctionName.getValue());
  390. if (functionNameAtom == Atom.NIL)
  391. // name is for a dynamic predicate.
  392. return YP.matchDynamic(name, args);
  393. string methodName = functionNameAtom._name;
  394. // Set the default for the method to call.
  395. Type methodClass = declaringClass;
  396. bool checkMode = false;
  397. if (methodName.StartsWith("YP."))
  398. {
  399. // Assume we only check mode in calls to standard Prolog predicates in YP.
  400. checkMode = true;
  401. // Use the method in class YP.
  402. methodName = methodName.Substring(3);
  403. methodClass = typeof(YP);
  404. }
  405. if (methodName.Contains("."))
  406. // We don't support calling inner classes, etc.
  407. return null;
  408. if (methodClass == null)
  409. return YP.unknownPredicate
  410. (name, args.Length,
  411. "Cannot find predicate function for: " + name + "/" + args.Length +
  412. " because declaringClass is null. Set declaringClass to the class containing " +
  413. methodName);
  414. try
  415. {
  416. if (checkMode)
  417. {
  418. assertYPPred(state);
  419. object functor = Functor.make(name, args);
  420. if (CompilerState.isDetNoneOut(state, functor))
  421. {
  422. methodClass.InvokeMember
  423. (methodName, BindingFlags.InvokeMethod, null, null, args);
  424. return YP.succeed();
  425. }
  426. if (CompilerState.isSemidetNoneOut(state, functor))
  427. {
  428. if ((bool)methodClass.InvokeMember
  429. (methodName, BindingFlags.InvokeMethod, null, null, args))
  430. return YP.succeed();
  431. else
  432. return YP.fail();
  433. }
  434. }
  435. return (IEnumerable<bool>)methodClass.InvokeMember
  436. (methodName, BindingFlags.InvokeMethod, null, null, args);
  437. }
  438. catch (TargetInvocationException exception)
  439. {
  440. throw exception.InnerException;
  441. }
  442. catch (MissingMethodException)
  443. {
  444. return YP.unknownPredicate
  445. (name, args.Length,
  446. "Cannot find predicate function " + methodName + " for " + name + "/" + args.Length +
  447. " in " + methodClass.FullName);
  448. }
  449. }
  450. return null;
  451. }
  452. /// <summary>
  453. /// Return true if there is a dynamic or static predicate with name and arity.
  454. /// This returns false for built-in predicates.
  455. /// </summary>
  456. /// <param name="name"></param>
  457. /// <param name="arity"></param>
  458. /// <param name="declaringClass">used to resolve references to the default
  459. /// module Atom.a(""). If a declaringClass is needed to resolve the reference but it is
  460. /// null, return false</param>
  461. /// <returns></returns>
  462. public static bool isCurrentPredicate(Atom name, int arity, Type declaringClass)
  463. {
  464. CompilerState state = new CompilerState();
  465. Variable FunctionName = new Variable();
  466. foreach (bool l1 in functorCallFunctionName(state, name, arity, FunctionName))
  467. {
  468. Atom functionNameAtom = ((Atom)FunctionName.getValue());
  469. if (functionNameAtom == Atom.NIL)
  470. // name is for a dynamic predicate.
  471. return YP.isDynamicCurrentPredicate(name, arity);
  472. string methodName = functionNameAtom._name;
  473. if (methodName.StartsWith("YP."))
  474. // current_predicate/1 should fail for built-ins.
  475. return false;
  476. if (methodName.Contains("."))
  477. // We don't support calling inner classes, etc.
  478. return false;
  479. if (declaringClass == null)
  480. return false;
  481. foreach (MemberInfo member in declaringClass.GetMember(methodName))
  482. {
  483. MethodInfo method = member as MethodInfo;
  484. if (method == null)
  485. continue;
  486. if ((method.Attributes | MethodAttributes.Static) == 0)
  487. // Not a static method.
  488. continue;
  489. if (method.GetParameters().Length == arity)
  490. return true;
  491. }
  492. }
  493. return false;
  494. }
  495. // Compiler output follows.
  496. public class YPInnerClass { }
  497. public static System.Type getDeclaringClass() { return typeof(YPInnerClass).DeclaringType; }
  498. public static void repeatWrite(object arg1, object N)
  499. {
  500. {
  501. object _Value = arg1;
  502. if (YP.termEqual(N, 0))
  503. {
  504. return;
  505. }
  506. }
  507. {
  508. object Value = arg1;
  509. Variable NextN = new Variable();
  510. YP.write(Value);
  511. foreach (bool l2 in YP.unify(NextN, YP.subtract(N, 1)))
  512. {
  513. repeatWrite(Value, NextN);
  514. return;
  515. }
  516. }
  517. }
  518. public static bool sameVariable(object Variable1, object Variable2)
  519. {
  520. {
  521. if (YP.var(Variable1))
  522. {
  523. if (YP.var(Variable2))
  524. {
  525. if (YP.termEqual(Variable1, Variable2))
  526. {
  527. return true;
  528. }
  529. }
  530. }
  531. }
  532. return false;
  533. }
  534. public static IEnumerable<bool> makeFunctionPseudoCode(object RuleList, object FunctionCode)
  535. {
  536. {
  537. Variable State = new Variable();
  538. foreach (bool l2 in CompilerState.make(State))
  539. {
  540. assertYPPred(State);
  541. processCompilerDirectives(RuleList, State);
  542. foreach (bool l3 in YP.unify(FunctionCode, Atom.a("getDeclaringClass")))
  543. {
  544. yield return false;
  545. }
  546. foreach (bool l3 in makeFunctionPseudoCode3(RuleList, State, FunctionCode))
  547. {
  548. yield return false;
  549. }
  550. }
  551. }
  552. }
  553. public static void assertYPPred(object State)
  554. {
  555. {
  556. CompilerState.assertPred(State, Atom.a("nl"), Atom.a("det"));
  557. CompilerState.assertPred(State, new Functor1("write", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("det"));
  558. CompilerState.assertPred(State, new Functor1("put_code", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("det"));
  559. CompilerState.assertPred(State, new Functor1("see", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("det"));
  560. CompilerState.assertPred(State, Atom.a("seen"), Atom.a("det"));
  561. CompilerState.assertPred(State, new Functor1("tell", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("det"));
  562. CompilerState.assertPred(State, Atom.a("told"), Atom.a("det"));
  563. CompilerState.assertPred(State, new Functor1("throw", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("det"));
  564. CompilerState.assertPred(State, new Functor1("abolish", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("det"));
  565. CompilerState.assertPred(State, new Functor1("retractall", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("det"));
  566. CompilerState.assertPred(State, new Functor2("set_prolog_flag", new Functor2("::", Atom.a("univ"), Atom.a("in")), new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("det"));
  567. CompilerState.assertPred(State, new Functor1("var", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("semidet"));
  568. CompilerState.assertPred(State, new Functor1("nonvar", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("semidet"));
  569. CompilerState.assertPred(State, new Functor1("atom", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("semidet"));
  570. CompilerState.assertPred(State, new Functor1("integer", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("semidet"));
  571. CompilerState.assertPred(State, new Functor1("float", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("semidet"));
  572. CompilerState.assertPred(State, new Functor1("number", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("semidet"));
  573. CompilerState.assertPred(State, new Functor1("atomic", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("semidet"));
  574. CompilerState.assertPred(State, new Functor1("compound", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("semidet"));
  575. CompilerState.assertPred(State, new Functor2("==", new Functor2("::", Atom.a("univ"), Atom.a("in")), new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("semidet"));
  576. CompilerState.assertPred(State, new Functor2("\\==", new Functor2("::", Atom.a("univ"), Atom.a("in")), new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("semidet"));
  577. CompilerState.assertPred(State, new Functor2("@<", new Functor2("::", Atom.a("univ"), Atom.a("in")), new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("semidet"));
  578. CompilerState.assertPred(State, new Functor2("@=<", new Functor2("::", Atom.a("univ"), Atom.a("in")), new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("semidet"));
  579. CompilerState.assertPred(State, new Functor2("@>", new Functor2("::", Atom.a("univ"), Atom.a("in")), new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("semidet"));
  580. CompilerState.assertPred(State, new Functor2("@>=", new Functor2("::", Atom.a("univ"), Atom.a("in")), new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("semidet"));
  581. return;
  582. }
  583. }
  584. public static void processCompilerDirectives(object arg1, object arg2)
  585. {
  586. {
  587. object _State = arg2;
  588. foreach (bool l2 in YP.unify(arg1, Atom.NIL))
  589. {
  590. return;
  591. }
  592. }
  593. {
  594. object State = arg2;
  595. Variable Pred = new Variable();
  596. Variable Determinism = new Variable();
  597. Variable x3 = new Variable();
  598. Variable RestRules = new Variable();
  599. foreach (bool l2 in YP.unify(arg1, new ListPair(new Functor2("f", new Functor1(":-", new Functor1("pred", new Functor2("is", Pred, Determinism))), x3), RestRules)))
  600. {
  601. CompilerState.assertPred(State, Pred, Determinism);
  602. processCompilerDirectives(RestRules, State);
  603. return;
  604. }
  605. }
  606. {
  607. object State = arg2;
  608. Variable Module = new Variable();
  609. Variable PredicateList = new Variable();
  610. Variable x3 = new Variable();
  611. Variable RestRules = new Variable();
  612. foreach (bool l2 in YP.unify(arg1, new ListPair(new Functor2("f", new Functor1(":-", new Functor2("import", Module, PredicateList)), x3), RestRules)))
  613. {
  614. foreach (bool l3 in importPredicateList(State, Module, PredicateList))
  615. {
  616. processCompilerDirectives(RestRules, State);
  617. return;
  618. }
  619. }
  620. }
  621. {
  622. object State = arg2;
  623. Variable x1 = new Variable();
  624. Variable x2 = new Variable();
  625. Variable RestRules = new Variable();
  626. foreach (bool l2 in YP.unify(arg1, new ListPair(new Functor2("f", new Functor1(":-", x1), x2), RestRules)))
  627. {
  628. processCompilerDirectives(RestRules, State);
  629. return;
  630. }
  631. }
  632. {
  633. object State = arg2;
  634. Variable Head = new Variable();
  635. Variable _Body = new Variable();
  636. Variable x3 = new Variable();
  637. Variable RestRules = new Variable();
  638. Variable Name = new Variable();
  639. Variable Arity = new Variable();
  640. foreach (bool l2 in YP.unify(arg1, new ListPair(new Functor2("f", new Functor2(":-", Head, _Body), x3), RestRules)))
  641. {
  642. foreach (bool l3 in YP.functor(Head, Name, Arity))
  643. {
  644. CompilerState.assertModuleForNameArity(State, Name, Arity, Atom.a(""));
  645. processCompilerDirectives(RestRules, State);
  646. return;
  647. }
  648. }
  649. }
  650. {
  651. object State = arg2;
  652. Variable Fact = new Variable();
  653. Variable x2 = new Variable();
  654. Variable RestRules = new Variable();
  655. Variable Name = new Variable();
  656. Variable Arity = new Variable();
  657. foreach (bool l2 in YP.unify(arg1, new ListPair(new Functor2("f", Fact, x2), RestRules)))
  658. {
  659. foreach (bool l3 in YP.functor(Fact, Name, Arity))
  660. {
  661. CompilerState.assertModuleForNameArity(State, Name, Arity, Atom.a(""));
  662. processCompilerDirectives(RestRules, State);
  663. return;
  664. }
  665. }
  666. }
  667. {
  668. object State = arg2;
  669. Variable x1 = new Variable();
  670. Variable RestRules = new Variable();
  671. foreach (bool l2 in YP.unify(arg1, new ListPair(x1, RestRules)))
  672. {
  673. processCompilerDirectives(RestRules, State);
  674. return;
  675. }
  676. }
  677. }
  678. public static IEnumerable<bool> importPredicateList(object arg1, object arg2, object arg3)
  679. {
  680. {
  681. object _State = arg1;
  682. object _Module = arg2;
  683. foreach (bool l2 in YP.unify(arg3, Atom.NIL))
  684. {
  685. yield return true;
  686. yield break;
  687. }
  688. }
  689. {
  690. object State = arg1;
  691. object Module = arg2;
  692. Variable Name = new Variable();
  693. Variable Arity = new Variable();
  694. Variable Rest = new Variable();
  695. foreach (bool l2 in YP.unify(arg3, new ListPair(new Functor2("/", Name, Arity), Rest)))
  696. {
  697. CompilerState.assertModuleForNameArity(State, Name, Arity, Module);
  698. foreach (bool l3 in importPredicateList(State, Module, Rest))
  699. {
  700. yield return true;
  701. yield break;
  702. }
  703. }
  704. }
  705. {
  706. object State = arg1;
  707. object Module = arg2;
  708. Variable x3 = new Variable();
  709. Variable Rest = new Variable();
  710. foreach (bool l2 in YP.unify(arg3, new ListPair(x3, Rest)))
  711. {
  712. foreach (bool l3 in importPredicateList(State, Module, Rest))
  713. {
  714. yield return true;
  715. yield break;
  716. }
  717. }
  718. }
  719. }
  720. public static IEnumerable<bool> makeFunctionPseudoCode3(object RuleList, object State, object FunctionCode)
  721. {
  722. {
  723. Variable SamePredicateRuleList = new Variable();
  724. Variable RestRules = new Variable();
  725. foreach (bool l2 in samePredicateRuleList(RuleList, SamePredicateRuleList, RestRules))
  726. {
  727. if (YP.termNotEqual(SamePredicateRuleList, Atom.NIL))
  728. {
  729. foreach (bool l4 in compileSamePredicateFunction(SamePredicateRuleList, State, FunctionCode))
  730. {
  731. yield return false;
  732. }
  733. foreach (bool l4 in makeFunctionPseudoCode3(RestRules, State, FunctionCode))
  734. {
  735. yield return false;
  736. }
  737. }
  738. }
  739. }
  740. }
  741. public static IEnumerable<bool> compileSamePredicateFunction(object SamePredicateRuleList, object State, object FunctionCode)
  742. {
  743. {
  744. Variable FirstRule = new Variable();
  745. Variable x5 = new Variable();
  746. Variable x6 = new Variable();
  747. Variable x7 = new Variable();
  748. Variable Head = new Variable();
  749. Variable x9 = new Variable();
  750. Variable ArgAssignments = new Variable();
  751. Variable Calls = new Variable();
  752. Variable Rule = new Variable();
  753. Variable VariableNameSuggestions = new Variable();
  754. Variable ClauseBag = new Variable();
  755. Variable Name = new Variable();
  756. Variable ArgsList = new Variable();
  757. Variable FunctionArgNames = new Variable();
  758. Variable MergedArgName = new Variable();
  759. Variable ArgName = new Variable();
  760. Variable MergedArgNames = new Variable();
  761. Variable FunctionArgs = new Variable();
  762. Variable BodyCode = new Variable();
  763. Variable ReturnType = new Variable();
  764. Variable BodyWithReturn = new Variable();
  765. foreach (bool l2 in YP.unify(new ListPair(new Functor2("f", FirstRule, x5), x6), SamePredicateRuleList))
  766. {
  767. foreach (bool l3 in YP.unify(FirstRule, new Functor1(":-", x7)))
  768. {
  769. goto cutIf1;
  770. }
  771. foreach (bool l3 in YP.unify(new Functor2(":-", Head, x9), FirstRule))
  772. {
  773. CompilerState.startFunction(State, Head);
  774. FindallAnswers findallAnswers3 = new FindallAnswers(new Functor2("f", ArgAssignments, Calls));
  775. foreach (bool l4 in member(new Functor2("f", Rule, VariableNameSuggestions), SamePredicateRuleList))
  776. {
  777. foreach (bool l5 in compileBodyWithHeadBindings(Rule, VariableNameSuggestions, State, ArgAssignments, Calls))
  778. {
  779. findallAnswers3.add();
  780. }
  781. }
  782. foreach (bool l4 in findallAnswers3.result(ClauseBag))
  783. {
  784. foreach (bool l5 in YP.univ(Head, new ListPair(Name, ArgsList)))
  785. {
  786. foreach (bool l6 in getFunctionArgNames(ArgsList, 1, FunctionArgNames))
  787. {
  788. FindallAnswers findallAnswers4 = new FindallAnswers(MergedArgName);
  789. foreach (bool l7 in member(ArgName, FunctionArgNames))
  790. {
  791. foreach (bool l8 in argAssignedAll(ArgName, ClauseBag, MergedArgName))
  792. {
  793. findallAnswers4.add();
  794. goto cutIf5;
  795. }
  796. foreach (bool l8 in YP.unify(MergedArgName, ArgName))
  797. {
  798. findallAnswers4.add();
  799. }
  800. cutIf5:
  801. { }
  802. }
  803. foreach (bool l7 in findallAnswers4.result(MergedArgNames))
  804. {
  805. foreach (bool l8 in maplist_arg(MergedArgNames, FunctionArgs))
  806. {
  807. foreach (bool l9 in maplist_compileClause(ClauseBag, MergedArgNames, BodyCode))
  808. {
  809. if (CompilerState.determinismEquals(State, Atom.a("detNoneOut")))
  810. {
  811. foreach (bool l11 in YP.unify(ReturnType, Atom.a("void")))
  812. {
  813. if (CompilerState.determinismEquals(State, Atom.a("semidetNoneOut")))
  814. {
  815. foreach (bool l13 in append(BodyCode, new ListPair(Atom.a("returnfalse"), Atom.NIL), BodyWithReturn))
  816. {
  817. foreach (bool l14 in YP.unify(FunctionCode, new Functor("function", new object[] { ReturnType, Name, FunctionArgs, BodyWithReturn })))
  818. {
  819. yield return false;
  820. }
  821. }
  822. goto cutIf7;
  823. }
  824. if (CompilerState.determinismEquals(State, Atom.a("detNoneOut")))
  825. {
  826. foreach (bool l13 in YP.unify(BodyWithReturn, BodyCode))
  827. {
  828. foreach (bool l14 in YP.unify(FunctionCode, new Functor("function", new object[] { ReturnType, Name, FunctionArgs, BodyWithReturn })))
  829. {
  830. yield return false;
  831. }
  832. }
  833. goto cutIf8;
  834. }
  835. if (CompilerState.codeUsesYield(State))
  836. {
  837. foreach (bool l13 in YP.unify(BodyWithReturn, BodyCode))
  838. {
  839. foreach (bool l14 in YP.unify(FunctionCode, new Functor("function", new object[] { ReturnType, Name, FunctionArgs, BodyWithReturn })))
  840. {
  841. yield return false;
  842. }
  843. }
  844. goto cutIf9;
  845. }
  846. foreach (bool l12 in append(BodyCode, new ListPair(new Functor2("foreach", new Functor2("call", Atom.a("YP.fail"), Atom.NIL), new ListPair(Atom.a("yieldfalse"), Atom.NIL)), Atom.NIL), BodyWithReturn))
  847. {
  848. foreach (bool l13 in YP.unify(FunctionCode, new Functor("function", new object[] { ReturnType, Name, FunctionArgs, BodyWithReturn })))
  849. {
  850. yield return false;
  851. }
  852. }
  853. cutIf9:
  854. cutIf8:
  855. cutIf7:
  856. { }
  857. }
  858. goto cutIf6;
  859. }
  860. if (CompilerState.determinismEquals(State, Atom.a("semidetNoneOut")))
  861. {
  862. foreach (bool l11 in YP.unify(ReturnType, Atom.a("bool")))
  863. {
  864. if (CompilerState.determinismEquals(State, Atom.a("semidetNoneOut")))
  865. {
  866. foreach (bool l13 in append(BodyCode, new ListPair(Atom.a("returnfalse"), Atom.NIL), BodyWithReturn))
  867. {
  868. foreach (bool l14 in YP.unify(FunctionCode, new Functor("function", new object[] { ReturnType, Name, FunctionArgs, BodyWithReturn })))
  869. {
  870. yield return false;
  871. }
  872. }
  873. goto cutIf11;
  874. }
  875. if (CompilerState.determinismEquals(State, Atom.a("detNoneOut")))
  876. {
  877. foreach (bool l13 in YP.unify(BodyWithReturn, BodyCode))
  878. {
  879. foreach (bool l14 in YP.unify(FunctionCode, new Functor("function", new object[] { ReturnType, Name, FunctionArgs, BodyWithReturn })))
  880. {
  881. yield return false;
  882. }
  883. }
  884. goto cutIf12;
  885. }
  886. if (CompilerState.codeUsesYield(State))
  887. {
  888. foreach (bool l13 in YP.unify(BodyWithReturn, BodyCode))
  889. {
  890. foreach (bool l14 in YP.unify(FunctionCode, new Functor("function", new object[] { ReturnType, Name, FunctionArgs, BodyWithReturn })))
  891. {
  892. yield return false;
  893. }
  894. }
  895. goto cutIf13;
  896. }
  897. foreach (bool l12 in append(BodyCode, new ListPair(new Functor2("foreach", new Functor2("call", Atom.a("YP.fail"), Atom.NIL), new ListPair(Atom.a("yieldfalse"), Atom.NIL)), Atom.NIL), BodyWithReturn))
  898. {
  899. foreach (bool l13 in YP.unify(FunctionCode, new Functor("function", new object[] { ReturnType, Name, FunctionArgs, BodyWithReturn })))
  900. {
  901. yield return false;
  902. }
  903. }
  904. cutIf13:
  905. cutIf12:

Large files files are truncated, but you can click here to view the full file