static IEnumerable<bool> attack3(object X, object N, object Arg3) { Variable Y = new Variable(); foreach (bool l in new ListPair(Y, new Variable()).unify(Arg3)) { if ((int)YP.getValue(X) == (int)Y.getValue() + (int)YP.getValue(N)) yield return false; if ((int)YP.getValue(X) == (int)Y.getValue() - (int)YP.getValue(N)) yield return false; } Variable Ys = new Variable(); Variable N1 = new Variable(); foreach (bool l1 in new ListPair(new Variable(), Ys).unify(Arg3)) { foreach (bool l2 in N1.unify((int)YP.getValue(N) + 1)) { foreach (bool l3 in attack3(X, N1, Ys)) yield return false; } } }
/// <summary> /// For each result, unify the _freeVariables and unify Bag with the associated bag. /// </summary> /// <param name="Bag"></param> /// <returns></returns> public IEnumerable <bool> result(object Bag) { Variable bagArrayVariable = new Variable(); foreach (bool l1 in resultArray(bagArrayVariable)) { foreach (bool l2 in YP.unify(Bag, ListPair.make((List <object>)bagArrayVariable.getValue()))) { yield return(false); } } }
/// <summary> /// For each result, unify the _freeVariables and unify Bag with the associated bag which is sorted /// with duplicates removed, as in setof. /// </summary> /// <param name="Bag"></param> /// <returns></returns> public IEnumerable <bool> resultSet(object Bag) { Variable bagArrayVariable = new Variable(); foreach (bool l1 in resultArray(bagArrayVariable)) { List <object> bagArray = (List <object>)bagArrayVariable.getValue(); YP.sortArray(bagArray); foreach (bool l2 in YP.unify(Bag, ListPair.makeWithoutRepeatedTerms(bagArray))) { yield return(false); } } }
static IEnumerable<bool> queens3(object UnplacedQs, object SafeQs, Variable Qs) { ListPair UnplacedQsListPair = YP.getValue(UnplacedQs) as ListPair; if (UnplacedQsListPair != null) { Variable UnplacedQs1 = new Variable(); Variable Q = new Variable(); foreach (bool l1 in selectq(Q, UnplacedQsListPair, UnplacedQs1)) { if (!(SafeQs is ListPair && hasAttack((int)Q.getValue(), (ListPair)SafeQs))) { foreach (bool l2 in queens3(UnplacedQs1, new ListPair(Q, SafeQs), Qs)) yield return false; } } } else { foreach (bool l1 in Qs.unify(SafeQs)) yield return false; } }
/// <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; }
/// <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> /// 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 Compiler.compileAnonymousFunction (functionCode.ToString(), args.Length, declaringClass); }
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; }