PageRenderTime 57ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 2ms

/YieldProlog/Modules/YPCompiler.cs

https://bitbucket.org/VirtualReality/optional-modules
C# | 6379 lines | 6162 code | 80 blank | 137 comment | 138 complexity | c3c632043982c69adbf0080c8fa08b07 MD5 | raw file

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

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

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