// disable warning on l1, don't see how we can // code this differently #pragma warning disable 0168, 0219 /// If arg is another Functor2, then succeed (yield once) if this and arg have the /// same name and all functor args unify, otherwise fail (don't yield). /// If arg is a Variable, then call its unify to unify with this. /// Otherwise fail (don't yield). public IEnumerable <bool> unify(object arg) { arg = YP.getValue(arg); if (arg is Functor2) { Functor2 argFunctor = (Functor2)arg; if (_name.Equals(argFunctor._name)) { foreach (bool l1 in YP.unify(_arg1, argFunctor._arg1)) { foreach (bool l2 in YP.unify(_arg2, argFunctor._arg2)) { yield return(false); } } } } else if (arg is Variable) { foreach (bool l1 in ((Variable)arg).unify(this)) { yield return(false); } } }
private static string listPairToString(Functor2 listPair) { string result = "["; while (true) { object head = YP.getValue(listPair._arg1); object tail = YP.getValue(listPair._arg2); if (tail == (object)Atom.NIL) { result += head; break; } else if (tail is Functor2 && ((Functor2)tail)._name == Atom.DOT) { result += head + ", "; listPair = (Functor2)tail; // Loop again. } else { // The list is not terminated with NIL. result += head + "|" + tail; break; } } result += "]"; return(result); }
public bool termEqual(object term) { term = YP.getValue(term); if (term is Functor2) { Functor2 termFunctor = (Functor2)term; return(_name.Equals(termFunctor._name) && YP.termEqual(_arg1, termFunctor._arg1) && YP.termEqual(_arg2, termFunctor._arg2)); } return(false); }
public bool lessThan(Functor2 functor) { // Do the equal check first since it is faster. if (!_name.Equals(functor._name)) { return(_name.lessThan(functor._name)); } if (!YP.termEqual(_arg1, functor._arg1)) { return(YP.termLessThan(_arg1, functor._arg1)); } return(YP.termLessThan(_arg2, functor._arg2)); }
// 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); }
private static string listPairToString(Functor2 listPair) { string result = "["; while (true) { object head = YP.getValue(listPair._arg1); object tail = YP.getValue(listPair._arg2); if (tail == (object)Atom.NIL) { result += head; break; } else if (tail is Functor2 && ((Functor2)tail)._name == Atom.DOT) { result += head + ", "; listPair = (Functor2)tail; // Loop again. } else { // The list is not terminated with NIL. result += head + "|" + tail; break; } } result += "]"; return result; }
public bool lessThan(Functor2 functor) { // Do the equal check first since it is faster. if (!_name.Equals(functor._name)) return _name.lessThan(functor._name); if (!YP.termEqual(_arg1, functor._arg1)) return YP.termLessThan(_arg1, functor._arg1); return YP.termLessThan(_arg2, functor._arg2); }