/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/YPCompiler.cs
C# | 6382 lines | 6162 code | 80 blank | 140 comment | 138 complexity | 61e83ffe5567d2acb1bab3a61d02c6e6 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- /*
- * Copyright (C) 2007-2008, Jeff Thompson
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the copyright holder nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- using System;
- using System.IO;
- using System.Collections;
- using System.Collections.Generic;
- using System.Text;
- using System.CodeDom.Compiler;
- using System.Reflection;
- namespace OpenSim.Region.ScriptEngine.Shared.YieldProlog
- {
- public class YPCompiler
- {
- private class CompilerState
- {
- public IndexedAnswers _pred = new IndexedAnswers(4);
- public Dictionary<YP.NameArity, Atom> _moduleForNameArity = new Dictionary<YP.NameArity, Atom>();
- public int _gensymCounter;
- public bool _useFinalCutCode;
- public Variable _finalCutCode;
- public bool _codeUsesYield;
- public Atom _determinism;
- // a list of '='(Name, Variable)
- public List<object> _variableNames;
- // Make these static functions that explicitly take the State so Prolog can call it.
- /// <summary>
- /// Make a new CompilerState and bind it to State.
- /// </summary>
- /// <param name="State"></param>
- /// <returns></returns>
- public static IEnumerable<bool> make(object State)
- {
- return YP.unify(State, new CompilerState());
- }
- public static void assertPred(object State, object Pred, object Determinism)
- {
- State = YP.getValue(State);
- object functorName = YP.getFunctorName(Pred);
- object[] functorArgs = YP.getFunctorArgs(Pred);
- // Debug: Should check if it's already asserted and is the same.
- ((CompilerState)State)._pred.addAnswer
- (new object[] { functorName, functorArgs.Length, Pred, YP.getValue(Determinism) });
- }
- public static void assertModuleForNameArity(object State, object Name, object Arity, object Module)
- {
- State = YP.getValue(State);
- Name = YP.getValue(Name);
- Arity = YP.getValue(Arity);
- Module = YP.getValue(Module);
- // If the Module Atom comes from the parser, it always has null _declaringClass.
- if (Module is Atom && ((Atom)Module)._module == null && Name is Atom && Arity is int)
- // Replace a previous entry if it exists.
- ((CompilerState)State)._moduleForNameArity[new YP.NameArity((Atom)Name, (int)Arity)] =
- (Atom)Module;
- }
- public static void startFunction(object State, object Head)
- {
- State = YP.getValue(State);
- ((CompilerState)State)._gensymCounter = 0;
- ((CompilerState)State)._useFinalCutCode = false;
- ((CompilerState)State)._finalCutCode = new Variable();
- ((CompilerState)State)._codeUsesYield = false;
- if (CompilerState.isDetNoneOut(State, Head))
- ((CompilerState)State)._determinism = Atom.a("detNoneOut");
- else if (CompilerState.isSemidetNoneOut(State, Head))
- ((CompilerState)State)._determinism = Atom.a("semidetNoneOut");
- else
- ((CompilerState)State)._determinism = Atom.a("nondet");
- }
- public static void setCodeUsesYield(object State)
- {
- State = YP.getValue(State);
- ((CompilerState)State)._codeUsesYield = true;
- }
- public static bool codeUsesYield(object State)
- {
- State = YP.getValue(State);
- return ((CompilerState)State)._codeUsesYield;
- }
- public static bool determinismEquals(object State, object Term)
- {
- State = YP.getValue(State);
- return YP.termEqual(((CompilerState)State)._determinism, Term);
- }
- /// <summary>
- /// Set _variableNames to a new list of (Name = Variable) for each unique variable in rule.
- /// If the variable is in variableNameSuggestions, use it, otherwise use x1, x2, etc.
- /// </summary>
- /// <param name="State"></param>
- /// <param name="rule"></param>
- /// <param name="variableNameSuggestions"></param>
- public static void newVariableNames(object State, object Rule, object VariableNameSuggestions)
- {
- State = YP.getValue(State);
- List<Variable> variablesSet = new List<Variable>();
- YP.addUniqueVariables(Rule, variablesSet);
- ((CompilerState)State)._variableNames = new List<object>();
- int xCounter = 0;
- foreach (Variable variable in variablesSet)
- ((CompilerState)State)._variableNames.Add
- (new Functor2(Atom.a("="), makeVariableName(variable, VariableNameSuggestions, ++xCounter),
- variable));
- }
- private static object makeVariableName(object variable, object variableNameSuggestions, int xCounter)
- {
- // Debug: should require named variables to start with _ or capital. Should
- // check for duplicates and clashes with keywords.
- for (object element = YP.getValue(variableNameSuggestions);
- element is Functor2 && ((Functor2)element)._name == Atom.DOT;
- element = YP.getValue(((Functor2)element)._arg2))
- {
- object suggestionPair = YP.getValue(((Functor2)element)._arg1);
- if (sameVariable(variable, ((Functor2)suggestionPair)._arg2))
- {
- Atom suggestion = (Atom)YP.getValue(((Functor2)suggestionPair)._arg1);
- if (suggestion.Equals(Atom.a("Atom")))
- suggestion = Atom.a("Atom_1");
- if (suggestion.Equals(Atom.a("Variable")))
- suggestion = Atom.a("Variable_1");
- if (suggestion.Equals(Atom.a("Functor")))
- suggestion = Atom.a("Functor_1");
- return suggestion;
- }
- }
- return Atom.a("x" + xCounter);
- }
- /// <summary>
- /// Unify Result with the name assigned by CompilerState.newVariableNames in State._variableNames
- /// for variable.
- /// </summary>
- /// <param name="variable">a Variable</param>
- /// <param name="State"></param>
- /// <param name="Result">the assigned Name</param>
- public static IEnumerable<bool> getVariableName(object State, object variable, object Result)
- {
- State = YP.getValue(State);
- foreach (object variableInfo in ((CompilerState)State)._variableNames)
- {
- if (variableInfo is Functor2 && ((Functor2)variableInfo)._name.Equals(Atom.a("=")))
- {
- if (sameVariable(variable, ((Functor2)variableInfo)._arg2))
- return YP.unify(Result, ((Functor2)variableInfo)._arg1);
- }
- }
- // We set up names for all unique variables, so this should never happen.
- throw new PrologException(Atom.a("Can't find entry in _variableNames"));
- }
- public static IEnumerable<bool> variableNamesList(object State, object VariableNamesList)
- {
- State = YP.getValue(State);
- return YP.unify(VariableNamesList, ListPair.make(((CompilerState)State)._variableNames));
- }
- public static IEnumerable<bool> gensym(object State, object Base, object Symbol)
- {
- State = YP.getValue(State);
- return YP.unify(Symbol, Atom.a(Base.ToString() + ++((CompilerState)State)._gensymCounter));
- }
- // disable warning on l1, don't see how we can
- // code this differently
- #pragma warning disable 0168, 0164, 0162, 0219
- public static bool isDetNoneOut(object State, object Term)
- {
- State = YP.getValue(State);
- object functorName = YP.getFunctorName(Term);
- object[] functorArgs = YP.getFunctorArgs(Term);
- Variable pred = new Variable();
- foreach (bool l1 in ((CompilerState)State)._pred.match
- (new object[] { functorName, functorArgs.Length, pred, Atom.a("det") }))
- {
- if (CompilerState.isNoneOut(YP.getFunctorArgs(pred.getValue())))
- {
- return true;
- }
- }
- return false;
- }
- public static bool isSemidetNoneOut(object State, object Term)
- {
- State = YP.getValue(State);
- object functorName = YP.getFunctorName(Term);
- object[] functorArgs = YP.getFunctorArgs(Term);
- Variable pred = new Variable();
- foreach (bool l1 in ((CompilerState)State)._pred.match
- (new object[] { functorName, functorArgs.Length, pred, Atom.a("semidet") }))
- {
- if (CompilerState.isNoneOut(YP.getFunctorArgs(pred.getValue())))
- {
- return true;
- }
- }
- return false;
- }
- #pragma warning restore 0168, 0164, 0162, 0219
- /// <summary>
- /// Return false if any of args is out, otherwise true.
- /// args is an array of ::(Type,Mode) where Mode is in or out.
- /// </summary>
- /// <param name="args"></param>
- /// <returns></returns>
- private static bool isNoneOut(object[] args)
- {
- foreach (object arg in args)
- {
- if (arg is Functor2 && ((Functor2)arg)._name == Atom.a("::") &&
- ((Functor2)arg)._arg2 == Atom.a("out"))
- return false;
- }
- return true;
- }
- public static bool nameArityHasModule(object State, object Name, object Arity, object Module)
- {
- State = YP.getValue(State);
- Name = YP.getValue(Name);
- Arity = YP.getValue(Arity);
- Module = YP.getValue(Module);
- if (Name is Atom && Arity is int)
- {
- Atom FoundModule;
- if (!((CompilerState)State)._moduleForNameArity.TryGetValue
- (new YP.NameArity((Atom)Name, (int)Arity), out FoundModule))
- return false;
- return FoundModule == Module;
- }
- return false;
- }
- }
- // disable warning on l1, don't see how we can
- // code this differently
- #pragma warning disable 0168, 0219,0164,0162
- /// <summary>
- /// Use makeFunctionPseudoCode, convertFunctionCSharp and compileAnonymousFunction
- /// to return an anonymous YP.IClause for the Head and Body of a rule clause.
- /// </summary>
- /// <param name="Head">a prolog term such as new Functor2("test1", X, Y).
- /// Note that the name of the head is ignored.
- /// </param>
- /// <param name="Body">a prolog term such as
- /// new Functor2(",", new Functor1(Atom.a("test2", Atom.a("")), X),
- /// new Functor2("=", Y, X)).
- /// This may not be null. (For a head-only clause, set the Body to Atom.a("true").
- /// </param>
- /// <param name="declaringClass">if not null, the code is compiled as a subclass of this class
- /// to resolve references to the default module Atom.a("")</param>
- /// <returns>a new YP.IClause object on which you can call match(object[] args) where
- /// args length is the arity of the Head</returns>
- public static YP.IClause compileAnonymousClause(object Head, object Body, Type declaringClass)
- {
- object[] args = YP.getFunctorArgs(Head);
- // compileAnonymousFunction wants "function".
- object Rule = new Functor2(Atom.RULE, Functor.make("function", args), Body);
- object RuleList = ListPair.make(new Functor2(Atom.F, Rule, Atom.NIL));
- StringWriter functionCode = new StringWriter();
- Variable SaveOutputStream = new Variable();
- foreach (bool l1 in YP.current_output(SaveOutputStream))
- {
- try
- {
- YP.tell(functionCode);
- Variable PseudoCode = new Variable();
- foreach (bool l2 in makeFunctionPseudoCode(RuleList, PseudoCode))
- {
- if (YP.termEqual(PseudoCode, Atom.a("getDeclaringClass")))
- // Ignore getDeclaringClass since we have access to the one passed in.
- continue;
- convertFunctionCSharp(PseudoCode);
- }
- YP.told();
- }
- finally
- {
- // Restore after calling tell.
- YP.tell(SaveOutputStream.getValue());
- }
- }
- return YPCompiler.compileAnonymousFunction
- (functionCode.ToString(), args.Length, declaringClass);
- }
- /// <summary>
- /// Use CodeDomProvider to compile the functionCode and return a YP.ClauseHeadAndBody
- /// which implements YP.IClause.
- /// The function name must be "function" and have nArgs arguments.
- /// </summary>
- /// <param name="functionCode">the code for the iterator, such as
- /// "public static IEnumerable<bool> function() { yield return false; }"
- /// </param>
- /// <param name="nArgs">the number of args in the function</param>
- /// <param name="declaringClass">if not null, then use the functionCode inside a class which
- /// inherits from contextClass, so that references in functionCode to methods in declaringClass don't
- /// have to be qualified</param>
- /// <returns>a new YP.IClause object on which you can call match(object[] args) where
- /// args length is nArgs</returns>
- public static YP.IClause compileAnonymousFunction(string functionCode, int nArgs, Type declaringClass)
- {
- CompilerParameters parameters = new CompilerParameters();
- // This gets the location of the System assembly.
- parameters.ReferencedAssemblies.Add(typeof(System.Int32).Assembly.Location);
- // This gets the location of this assembly which also has YieldProlog.YP, etc.
- parameters.ReferencedAssemblies.Add(typeof(YPCompiler).Assembly.Location);
- if (declaringClass != null)
- parameters.ReferencedAssemblies.Add(declaringClass.Assembly.Location);
- parameters.GenerateInMemory = true;
- StringBuilder sourceCode = new StringBuilder();
- sourceCode.Append(@"
- using System;
- using System.Collections.Generic;
- using OpenSim.Region.ScriptEngine.Shared.YieldProlog;
- namespace Temporary {
- public class Temporary : YP.ClauseHeadAndBody, YP.IClause {");
- if (declaringClass == null)
- // We don't extend a class with getDeclaringClass, so define it.
- sourceCode.Append(@"
- public class Inner {
- public static System.Type getDeclaringClass() { return null; }
- ");
- else
- sourceCode.Append(@"
- public class Inner : " + declaringClass.FullName + @" {
- ");
- sourceCode.Append(functionCode);
- // Basically, match applies the args to function.
- sourceCode.Append(@"
- }
- public IEnumerable<bool> match(object[] args) {
- return Inner.function(");
- if (nArgs >= 1)
- sourceCode.Append("args[0]");
- for (int i = 1; i < nArgs; ++i)
- sourceCode.Append(", args[" + i + "]");
- sourceCode.Append(@");
- }
- }
- }
- ");
- CompilerResults results = CodeDomProvider.CreateProvider
- ("CSharp").CompileAssemblyFromSource(parameters, sourceCode.ToString());
- if (results.Errors.Count > 0)
- throw new Exception("Error evaluating code: " + results.Errors[0]);
- // Return a new Temporary.Temporary object.
- return (YP.IClause)results.CompiledAssembly.GetType
- ("Temporary.Temporary").GetConstructor(Type.EmptyTypes).Invoke(null);
- }
- /// <summary>
- /// If the functor with name and args can be called directly as determined by
- /// functorCallFunctionName, then call it and return its iterator. If the predicate is
- /// dynamic and undefined, or if static and the method cannot be found, return
- /// the result of YP.unknownPredicate.
- /// This returns null if the functor has a special form than needs to be compiled
- /// (including ,/2 and ;/2).
- /// </summary>
- /// <param name="name"></param>
- /// <param name="args"></param>
- /// <param name="declaringClass">used to resolve references to the default
- /// module Atom.a(""). If a declaringClass is needed to resolve the reference but it is
- /// null, this throws a PrologException for existence_error</param>
- /// <returns></returns>
- public static IEnumerable<bool> getSimpleIterator(Atom name, object[] args, Type declaringClass)
- {
- CompilerState state = new CompilerState();
- Variable FunctionName = new Variable();
- foreach (bool l1 in functorCallFunctionName(state, name, args.Length, FunctionName))
- {
- Atom functionNameAtom = ((Atom)FunctionName.getValue());
- if (functionNameAtom == Atom.NIL)
- // name is for a dynamic predicate.
- return YP.matchDynamic(name, args);
- string methodName = functionNameAtom._name;
- // Set the default for the method to call.
- Type methodClass = declaringClass;
- bool checkMode = false;
- if (methodName.StartsWith("YP."))
- {
- // Assume we only check mode in calls to standard Prolog predicates in YP.
- checkMode = true;
- // Use the method in class YP.
- methodName = methodName.Substring(3);
- methodClass = typeof(YP);
- }
- if (methodName.Contains("."))
- // We don't support calling inner classes, etc.
- return null;
- if (methodClass == null)
- return YP.unknownPredicate
- (name, args.Length,
- "Cannot find predicate function for: " + name + "/" + args.Length +
- " because declaringClass is null. Set declaringClass to the class containing " +
- methodName);
- try
- {
- if (checkMode)
- {
- assertYPPred(state);
- object functor = Functor.make(name, args);
- if (CompilerState.isDetNoneOut(state, functor))
- {
- methodClass.InvokeMember
- (methodName, BindingFlags.InvokeMethod, null, null, args);
- return YP.succeed();
- }
- if (CompilerState.isSemidetNoneOut(state, functor))
- {
- if ((bool)methodClass.InvokeMember
- (methodName, BindingFlags.InvokeMethod, null, null, args))
- return YP.succeed();
- else
- return YP.fail();
- }
- }
- return (IEnumerable<bool>)methodClass.InvokeMember
- (methodName, BindingFlags.InvokeMethod, null, null, args);
- }
- catch (TargetInvocationException exception)
- {
- throw exception.InnerException;
- }
- catch (MissingMethodException)
- {
- return YP.unknownPredicate
- (name, args.Length,
- "Cannot find predicate function " + methodName + " for " + name + "/" + args.Length +
- " in " + methodClass.FullName);
- }
- }
- return null;
- }
- /// <summary>
- /// Return true if there is a dynamic or static predicate with name and arity.
- /// This returns false for built-in predicates.
- /// </summary>
- /// <param name="name"></param>
- /// <param name="arity"></param>
- /// <param name="declaringClass">used to resolve references to the default
- /// module Atom.a(""). If a declaringClass is needed to resolve the reference but it is
- /// null, return false</param>
- /// <returns></returns>
- public static bool isCurrentPredicate(Atom name, int arity, Type declaringClass)
- {
- CompilerState state = new CompilerState();
- Variable FunctionName = new Variable();
- foreach (bool l1 in functorCallFunctionName(state, name, arity, FunctionName))
- {
- Atom functionNameAtom = ((Atom)FunctionName.getValue());
- if (functionNameAtom == Atom.NIL)
- // name is for a dynamic predicate.
- return YP.isDynamicCurrentPredicate(name, arity);
- string methodName = functionNameAtom._name;
- if (methodName.StartsWith("YP."))
- // current_predicate/1 should fail for built-ins.
- return false;
- if (methodName.Contains("."))
- // We don't support calling inner classes, etc.
- return false;
- if (declaringClass == null)
- return false;
- foreach (MemberInfo member in declaringClass.GetMember(methodName))
- {
- MethodInfo method = member as MethodInfo;
- if (method == null)
- continue;
- if ((method.Attributes | MethodAttributes.Static) == 0)
- // Not a static method.
- continue;
- if (method.GetParameters().Length == arity)
- return true;
- }
- }
- return false;
- }
- // Compiler output follows.
- public class YPInnerClass { }
- public static System.Type getDeclaringClass() { return typeof(YPInnerClass).DeclaringType; }
- public static void repeatWrite(object arg1, object N)
- {
- {
- object _Value = arg1;
- if (YP.termEqual(N, 0))
- {
- return;
- }
- }
- {
- object Value = arg1;
- Variable NextN = new Variable();
- YP.write(Value);
- foreach (bool l2 in YP.unify(NextN, YP.subtract(N, 1)))
- {
- repeatWrite(Value, NextN);
- return;
- }
- }
- }
- public static bool sameVariable(object Variable1, object Variable2)
- {
- {
- if (YP.var(Variable1))
- {
- if (YP.var(Variable2))
- {
- if (YP.termEqual(Variable1, Variable2))
- {
- return true;
- }
- }
- }
- }
- return false;
- }
- public static IEnumerable<bool> makeFunctionPseudoCode(object RuleList, object FunctionCode)
- {
- {
- Variable State = new Variable();
- foreach (bool l2 in CompilerState.make(State))
- {
- assertYPPred(State);
- processCompilerDirectives(RuleList, State);
- foreach (bool l3 in YP.unify(FunctionCode, Atom.a("getDeclaringClass")))
- {
- yield return false;
- }
- foreach (bool l3 in makeFunctionPseudoCode3(RuleList, State, FunctionCode))
- {
- yield return false;
- }
- }
- }
- }
- public static void assertYPPred(object State)
- {
- {
- CompilerState.assertPred(State, Atom.a("nl"), Atom.a("det"));
- CompilerState.assertPred(State, new Functor1("write", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("det"));
- CompilerState.assertPred(State, new Functor1("put_code", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("det"));
- CompilerState.assertPred(State, new Functor1("see", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("det"));
- CompilerState.assertPred(State, Atom.a("seen"), Atom.a("det"));
- CompilerState.assertPred(State, new Functor1("tell", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("det"));
- CompilerState.assertPred(State, Atom.a("told"), Atom.a("det"));
- CompilerState.assertPred(State, new Functor1("throw", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("det"));
- CompilerState.assertPred(State, new Functor1("abolish", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("det"));
- CompilerState.assertPred(State, new Functor1("retractall", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("det"));
- 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"));
- CompilerState.assertPred(State, new Functor1("var", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("semidet"));
- CompilerState.assertPred(State, new Functor1("nonvar", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("semidet"));
- CompilerState.assertPred(State, new Functor1("atom", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("semidet"));
- CompilerState.assertPred(State, new Functor1("integer", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("semidet"));
- CompilerState.assertPred(State, new Functor1("float", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("semidet"));
- CompilerState.assertPred(State, new Functor1("number", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("semidet"));
- CompilerState.assertPred(State, new Functor1("atomic", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("semidet"));
- CompilerState.assertPred(State, new Functor1("compound", new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("semidet"));
- CompilerState.assertPred(State, new Functor2("==", new Functor2("::", Atom.a("univ"), Atom.a("in")), new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("semidet"));
- CompilerState.assertPred(State, new Functor2("\\==", new Functor2("::", Atom.a("univ"), Atom.a("in")), new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("semidet"));
- CompilerState.assertPred(State, new Functor2("@<", new Functor2("::", Atom.a("univ"), Atom.a("in")), new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("semidet"));
- CompilerState.assertPred(State, new Functor2("@=<", new Functor2("::", Atom.a("univ"), Atom.a("in")), new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("semidet"));
- CompilerState.assertPred(State, new Functor2("@>", new Functor2("::", Atom.a("univ"), Atom.a("in")), new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("semidet"));
- CompilerState.assertPred(State, new Functor2("@>=", new Functor2("::", Atom.a("univ"), Atom.a("in")), new Functor2("::", Atom.a("univ"), Atom.a("in"))), Atom.a("semidet"));
- return;
- }
- }
- public static void processCompilerDirectives(object arg1, object arg2)
- {
- {
- object _State = arg2;
- foreach (bool l2 in YP.unify(arg1, Atom.NIL))
- {
- return;
- }
- }
- {
- object State = arg2;
- Variable Pred = new Variable();
- Variable Determinism = new Variable();
- Variable x3 = new Variable();
- Variable RestRules = new Variable();
- foreach (bool l2 in YP.unify(arg1, new ListPair(new Functor2("f", new Functor1(":-", new Functor1("pred", new Functor2("is", Pred, Determinism))), x3), RestRules)))
- {
- CompilerState.assertPred(State, Pred, Determinism);
- processCompilerDirectives(RestRules, State);
- return;
- }
- }
- {
- object State = arg2;
- Variable Module = new Variable();
- Variable PredicateList = new Variable();
- Variable x3 = new Variable();
- Variable RestRules = new Variable();
- foreach (bool l2 in YP.unify(arg1, new ListPair(new Functor2("f", new Functor1(":-", new Functor2("import", Module, PredicateList)), x3), RestRules)))
- {
- foreach (bool l3 in importPredicateList(State, Module, PredicateList))
- {
- processCompilerDirectives(RestRules, State);
- return;
- }
- }
- }
- {
- object State = arg2;
- Variable x1 = new Variable();
- Variable x2 = new Variable();
- Variable RestRules = new Variable();
- foreach (bool l2 in YP.unify(arg1, new ListPair(new Functor2("f", new Functor1(":-", x1), x2), RestRules)))
- {
- processCompilerDirectives(RestRules, State);
- return;
- }
- }
- {
- object State = arg2;
- Variable Head = new Variable();
- Variable _Body = new Variable();
- Variable x3 = new Variable();
- Variable RestRules = new Variable();
- Variable Name = new Variable();
- Variable Arity = new Variable();
- foreach (bool l2 in YP.unify(arg1, new ListPair(new Functor2("f", new Functor2(":-", Head, _Body), x3), RestRules)))
- {
- foreach (bool l3 in YP.functor(Head, Name, Arity))
- {
- CompilerState.assertModuleForNameArity(State, Name, Arity, Atom.a(""));
- processCompilerDirectives(RestRules, State);
- return;
- }
- }
- }
- {
- object State = arg2;
- Variable Fact = new Variable();
- Variable x2 = new Variable();
- Variable RestRules = new Variable();
- Variable Name = new Variable();
- Variable Arity = new Variable();
- foreach (bool l2 in YP.unify(arg1, new ListPair(new Functor2("f", Fact, x2), RestRules)))
- {
- foreach (bool l3 in YP.functor(Fact, Name, Arity))
- {
- CompilerState.assertModuleForNameArity(State, Name, Arity, Atom.a(""));
- processCompilerDirectives(RestRules, State);
- return;
- }
- }
- }
- {
- object State = arg2;
- Variable x1 = new Variable();
- Variable RestRules = new Variable();
- foreach (bool l2 in YP.unify(arg1, new ListPair(x1, RestRules)))
- {
- processCompilerDirectives(RestRules, State);
- return;
- }
- }
- }
- public static IEnumerable<bool> importPredicateList(object arg1, object arg2, object arg3)
- {
- {
- object _State = arg1;
- object _Module = arg2;
- foreach (bool l2 in YP.unify(arg3, Atom.NIL))
- {
- yield return true;
- yield break;
- }
- }
- {
- object State = arg1;
- object Module = arg2;
- Variable Name = new Variable();
- Variable Arity = new Variable();
- Variable Rest = new Variable();
- foreach (bool l2 in YP.unify(arg3, new ListPair(new Functor2("/", Name, Arity), Rest)))
- {
- CompilerState.assertModuleForNameArity(State, Name, Arity, Module);
- foreach (bool l3 in importPredicateList(State, Module, Rest))
- {
- yield return true;
- yield break;
- }
- }
- }
- {
- object State = arg1;
- object Module = arg2;
- Variable x3 = new Variable();
- Variable Rest = new Variable();
- foreach (bool l2 in YP.unify(arg3, new ListPair(x3, Rest)))
- {
- foreach (bool l3 in importPredicateList(State, Module, Rest))
- {
- yield return true;
- yield break;
- }
- }
- }
- }
- public static IEnumerable<bool> makeFunctionPseudoCode3(object RuleList, object State, object FunctionCode)
- {
- {
- Variable SamePredicateRuleList = new Variable();
- Variable RestRules = new Variable();
- foreach (bool l2 in samePredicateRuleList(RuleList, SamePredicateRuleList, RestRules))
- {
- if (YP.termNotEqual(SamePredicateRuleList, Atom.NIL))
- {
- foreach (bool l4 in compileSamePredicateFunction(SamePredicateRuleList, State, FunctionCode))
- {
- yield return false;
- }
- foreach (bool l4 in makeFunctionPseudoCode3(RestRules, State, FunctionCode))
- {
- yield return false;
- }
- }
- }
- }
- }
- public static IEnumerable<bool> compileSamePredicateFunction(object SamePredicateRuleList, object State, object FunctionCode)
- {
- {
- Variable FirstRule = new Variable();
- Variable x5 = new Variable();
- Variable x6 = new Variable();
- Variable x7 = new Variable();
- Variable Head = new Variable();
- Variable x9 = new Variable();
- Variable ArgAssignments = new Variable();
- Variable Calls = new Variable();
- Variable Rule = new Variable();
- Variable VariableNameSuggestions = new Variable();
- Variable ClauseBag = new Variable();
- Variable Name = new Variable();
- Variable ArgsList = new Variable();
- Variable FunctionArgNames = new Variable();
- Variable MergedArgName = new Variable();
- Variable ArgName = new Variable();
- Variable MergedArgNames = new Variable();
- Variable FunctionArgs = new Variable();
- Variable BodyCode = new Variable();
- Variable ReturnType = new Variable();
- Variable BodyWithReturn = new Variable();
- foreach (bool l2 in YP.unify(new ListPair(new Functor2("f", FirstRule, x5), x6), SamePredicateRuleList))
- {
- foreach (bool l3 in YP.unify(FirstRule, new Functor1(":-", x7)))
- {
- goto cutIf1;
- }
- foreach (bool l3 in YP.unify(new Functor2(":-", Head, x9), FirstRule))
- {
- CompilerState.startFunction(State, Head);
- FindallAnswers findallAnswers3 = new FindallAnswers(new Functor2("f", ArgAssignments, Calls));
- foreach (bool l4 in member(new Functor2("f", Rule, VariableNameSuggestions), SamePredicateRuleList))
- {
- foreach (bool l5 in compileBodyWithHeadBindings(Rule, VariableNameSuggestions, State, ArgAssignments, Calls))
- {
- findallAnswers3.add();
- }
- }
- foreach (bool l4 in findallAnswers3.result(ClauseBag))
- {
- foreach (bool l5 in YP.univ(Head, new ListPair(Name, ArgsList)))
- {
- foreach (bool l6 in getFunctionArgNames(ArgsList, 1, FunctionArgNames))
- {
- FindallAnswers findallAnswers4 = new FindallAnswers(MergedArgName);
- foreach (bool l7 in member(ArgName, FunctionArgNames))
- {
- foreach (bool l8 in argAssignedAll(ArgName, ClauseBag, MergedArgName))
- {
- findallAnswers4.add();
- goto cutIf5;
- }
- foreach (bool l8 in YP.unify(MergedArgName, ArgName))
- {
- findallAnswers4.add();
- }
- cutIf5:
- { }
- }
- foreach (bool l7 in findallAnswers4.result(MergedArgNames))
- {
- foreach (bool l8 in maplist_arg(MergedArgNames, FunctionArgs))
- {
- foreach (bool l9 in maplist_compileClause(ClauseBag, MergedArgNames, BodyCode))
- {
- if (CompilerState.determinismEquals(State, Atom.a("detNoneOut")))
- {
- foreach (bool l11 in YP.unify(ReturnType, Atom.a("void")))
- {
- if (CompilerState.determinismEquals(State, Atom.a("semidetNoneOut")))
- {
- foreach (bool l13 in append(BodyCode, new ListPair(Atom.a("returnfalse"), Atom.NIL), BodyWithReturn))
- {
- foreach (bool l14 in YP.unify(FunctionCode, new Functor("function", new object[] { ReturnType, Name, FunctionArgs, BodyWithReturn })))
- {
- yield return false;
- }
- }
- goto cutIf7;
- }
- if (CompilerState.determinismEquals(State, Atom.a("detNoneOut")))
- {
- foreach (bool l13 in YP.unify(BodyWithReturn, BodyCode))
- {
- foreach (bool l14 in YP.unify(FunctionCode, new Functor("function", new object[] { ReturnType, Name, FunctionArgs, BodyWithReturn })))
- {
- yield return false;
- }
- }
- goto cutIf8;
- }
- if (CompilerState.codeUsesYield(State))
- {
- foreach (bool l13 in YP.unify(BodyWithReturn, BodyCode))
- {
- foreach (bool l14 in YP.unify(FunctionCode, new Functor("function", new object[] { ReturnType, Name, FunctionArgs, BodyWithReturn })))
- {
- yield return false;
- }
- }
- goto cutIf9;
- }
- 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))
- {
- foreach (bool l13 in YP.unify(FunctionCode, new Functor("function", new object[] { ReturnType, Name, FunctionArgs, BodyWithReturn })))
- {
- yield return false;
- }
- }
- cutIf9:
- cutIf8:
- cutIf7:
- { }
- }
- goto cutIf6;
- }
- if (CompilerState.determinismEquals(State, Atom.a("semidetNoneOut")))
- {
- foreach (bool l11 in YP.unify(ReturnType, Atom.a("bool")))
- {
- if (CompilerState.determinismEquals(State, Atom.a("semidetNoneOut")))
- {
- foreach (bool l13 in append(BodyCode, new ListPair(Atom.a("returnfalse"), Atom.NIL), BodyWithReturn))
- {
- foreach (bool l14 in YP.unify(FunctionCode, new Functor("function", new object[] { ReturnType, Name, FunctionArgs, BodyWithReturn })))
- {
- yield return false;
- }
- }
- goto cutIf11;
- }
- if (CompilerState.determinismEquals(State, Atom.a("detNoneOut")))
- {
- foreach (bool l13 in YP.unify(BodyWithReturn, BodyCode))
- {
- foreach (bool l14 in YP.unify(FunctionCode, new Functor("function", new object[] { ReturnType, Name, FunctionArgs, BodyWithReturn })))
- {
- yield return false;
- }
- }
- goto cutIf12;
- }
- if (CompilerState.codeUsesYield(State))
- {
- foreach (bool l13 in YP.unify(BodyWithReturn, BodyCode))
- {
- foreach (bool l14 in YP.unify(FunctionCode, new Functor("function", new object[] { ReturnType, Name, FunctionArgs, BodyWithReturn })))
- {
- yield return false;
- }
- }
- goto cutIf13;
- }
- 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))
- {
- foreach (bool l13 in YP.unify(FunctionCode, new Functor("function", new object[] { ReturnType, Name, FunctionArgs, BodyWithReturn })))
- {
- yield return false;
- }
- }
- cutIf13:
- cutIf12:
- …
Large files files are truncated, but you can click here to view the full file