예제 #1
0
 /// <summary>
 /// If this Variable is bound, then just call YP.unify to unify this with arg.
 /// (Note that if arg is an unbound Variable, then YP.unify will bind it to
 /// this Variable's value.)
 /// Otherwise, bind this Variable to YP.getValue(arg) and yield once.  After the
 /// yield, return this Variable to the unbound state.
 /// For more details, see http://yieldprolog.sourceforge.net/tutorial1.html
 /// </summary>
 /// <param name="arg"></param>
 /// <returns></returns>
 public IEnumerable <bool> unify(object arg)
 {
     if (!_isBound)
     {
         _value = YP.getValue(arg);
         if (_value == this)
         {
             // We are unifying this unbound variable with itself, so leave it unbound.
             yield return(false);
         }
         else
         {
             _isBound = true;
             try
             {
                 yield return(false);
             }
             finally
             {
                 // Remove the binding.
                 _isBound = false;
             }
         }
     }
     else
     {
         foreach (bool l1 in YP.unify(this, arg))
         {
             yield return(false);
         }
     }
 }
예제 #2
0
    /// <summary>
    /// Parse goalString and yield for each Goal, setting VariableList to a list of
    /// (variableAtom = Var).
    /// </summary>
    /// <param name="goalString"></param>
    /// <param name="Goal"></param>
    /// <param name="VariableList"></param>
    /// <returns></returns>
    static IEnumerable <bool> parseGoal(string goalString, object Goal, object VariableList)
    {
        // The parser requires a newline at the end.
        YP.see(new StringReader(goalString + "\n"));
        object TermList = new Variable();

        // parseInput set TermList to a list of f(Goal, VariableList).
        foreach (bool l1 in Parser.parseInput(TermList))
        {
            // Close the input now before yielding.
            YP.seen();
            // Iterate through each member of TermList.
            for (TermList = YP.getValue(TermList);
                 TermList is Functor2 && ((Functor2)TermList)._name == Atom.DOT;
                 TermList = YP.getValue(((Functor2)TermList)._arg2))
            {
                // Unify the head of the list with f(Goal, VariableList).
                foreach (bool l2 in YP.unify
                             (((Functor2)TermList)._arg1, new Functor2(Atom.F, Goal, VariableList)))
                {
                    yield return(false);
                }
            }
            yield break;
        }
        // Close the input in case parseInput failed.
        YP.seen();
    }
예제 #3
0
 /// 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);
         }
     }
 }
예제 #4
0
        public IEnumerable <bool> retract(object Head, object Body)
        {
            Head = YP.getValue(Head);
            if (Head is Variable)
            {
                throw new PrologException("instantiation_error", "Head is an unbound variable");
            }
            object[] arguments = YP.getFunctorArgs(Head);

            // We always match Head from _allAnswers, and the Body is Atom.a("true").
            #pragma warning disable 0168, 0219
            foreach (bool l1 in YP.unify(Body, Atom.a("true")))
            {
                // The caller can assert another answer into this same predicate during yield, so we have to
                //   make a copy of the answers.
                foreach (object[] answer in _allAnswers.ToArray())
                {
                    foreach (bool l2 in YP.unifyArrays(arguments, answer))
                    {
                        _allAnswers.Remove(answer);
                        clearIndexes();
                        yield return(false);
                    }
                }
            }
            #pragma warning restore 0168, 0219
        }
예제 #5
0
 static IEnumerable <bool> squaredRectangle(object Width, object Height)
 {
     foreach (bool l1 in YP.unify(Width, Height))
     {
         yield return(false);
     }
 }
        /// <summary>
        /// Unify Bag with the result. This frees the internal answers, so you can only call this once.
        /// </summary>
        /// <param name="Bag"></param>
        /// <returns></returns>
        public IEnumerable <bool> result(object Bag)
        {
            object result = ListPair.make(_bagArray);

            // Try to free the memory.
            _bagArray = null;
            return(YP.unify(Bag, result));
        }
예제 #7
0
    static IEnumerable <bool> makeList(object First, object Second, object List)
    {
        ListPair list1  = new ListPair(Second, Atom.NIL);
        ListPair result = new ListPair(First, list1);

        foreach (bool l1 in YP.unify(List, result))
        {
            yield return(false);
        }
    }
예제 #8
0
        /// <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);
                }
            }
        }
예제 #9
0
 public static IEnumerable <bool> detected(object Obj)
 {
     {
         Variable Value = new Variable();
         Variable Min   = new Variable();
         Variable Max   = new Variable();
         foreach (bool l2 in recognition(Obj, Value))
         {
             foreach (bool l3 in confidence(Obj, Min, Max))
             {
                 if (YP.greaterThan(Value, Min))
                 {
                     if (YP.lessThan(Value, Max))
                     {
                         yield return(false);
                     }
                 }
             }
         }
     }
     {
         Variable Value = new Variable();
         Variable Min   = new Variable();
         Variable Max   = new Variable();
         foreach (bool l2 in recognition(Obj, Value))
         {
             foreach (bool l3 in confidence(Obj, Min, Max))
             {
                 foreach (bool l4 in YP.unify(Value, Min))
                 {
                     yield return(false);
                 }
             }
         }
     }
     {
         Variable Value = new Variable();
         Variable Min   = new Variable();
         Variable Max   = new Variable();
         foreach (bool l2 in recognition(Obj, Value))
         {
             foreach (bool l3 in confidence(Obj, Min, Max))
             {
                 foreach (bool l4 in YP.unify(Value, Max))
                 {
                     yield return(false);
                 }
             }
         }
     }
 }
예제 #10
0
        /// <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);
                }
            }
        }
예제 #11
0
 /// <summary>
 /// If Obj is an Atom unify its _module with Module.  If the Atom's _module is null, use Atom.NIL.
 /// </summary>
 /// <param name="Atom"></param>
 /// <param name="Module"></param>
 /// <returns></returns>
 public static IEnumerable <bool> module(object Obj, object Module)
 {
     Obj = YP.getValue(Obj);
     if (Obj is Atom)
     {
         if (((Atom)Obj)._module == null)
         {
             return(YP.unify(Module, Atom.NIL));
         }
         else
         {
             return(YP.unify(Module, ((Atom)Obj)._module));
         }
     }
     return(YP.fail());
 }
예제 #12
0
 static IEnumerable <bool> rangeList(object M, object N, object List)
 {
     if ((int)YP.getValue(M) >= (int)YP.getValue(N))
     {
         foreach (bool l1 in YP.unify(List, new ListPair(N, Atom.NIL)))
         {
             yield return(false);
         }
     }
     else
     {
         Variable Tail = new Variable();
         foreach (bool l1 in rangeList((int)YP.getValue(M) + 1, (int)YP.getValue(N), Tail))
         {
             foreach (bool l2 in YP.unify(List, new ListPair(M, Tail)))
             {
                 yield return(false);
             }
         }
     }
 }
예제 #13
0
 static IEnumerable <bool> brother(object Person, object Brother)
 {
     foreach (bool l1 in YP.unify(Person, "Hillary"))
     {
         foreach (bool l2 in YP.unify(Brother, "Tony"))
         {
             yield return(false);
         }
         foreach (bool l2 in YP.unify(Brother, "Hugh"))
         {
             yield return(false);
         }
     }
     foreach (bool l1 in YP.unify(Person, "Bill"))
     {
         foreach (bool l2 in YP.unify(Brother, "Roger"))
         {
             yield return(false);
         }
     }
 }
예제 #14
0
 public static IEnumerable <bool> parent
     (object Person, object Parent)
 {
     foreach (bool l1 in YP.unify
                  (Person, Atom.a("Chelsea")))
     {
         foreach (bool l2 in YP.unify
                      (Parent, Atom.a("Hillary")))
         {
             yield return(false);
         }
     }
     foreach (bool l1 in YP.unify
                  (Person, Atom.a("Chelsea")))
     {
         foreach (bool l2 in YP.unify
                      (Parent, Atom.a("Bill")))
         {
             yield return(false);
         }
     }
 }
예제 #15
0
 public static IEnumerable <bool> uncle
     (object Person, object Uncle)
 {
     {
         Variable Goal   = new Variable();
         Variable Parent = new Variable();
         foreach (bool l2 in YP.unify
                      (Goal, new Functor2
                          (Atom.a("parent", Atom.a("")),
                          Person, Parent)))
         {
             foreach (bool l3 in YP.getIterator
                          (Goal, getDeclaringClass()))
             {
                 foreach (bool l4 in YP.matchDynamic
                              (Atom.a("brother"), new object[] { Parent, Uncle }))
                 {
                     yield return(false);
                 }
             }
         }
     }
 }
예제 #16
0
        public IEnumerable <bool> clause(object Head, object Body)
        {
            Head = YP.getValue(Head);
            if (Head is Variable)
            {
                throw new PrologException("instantiation_error", "Head is an unbound variable");
            }
            object[] arguments = YP.getFunctorArgs(Head);

            // We always match Head from _allAnswers, and the Body is Atom.TRUE.
            foreach (bool l1 in YP.unify(Body, Atom.TRUE))
            {
                // The caller can assert another answer into this same predicate during yield, so we have to
                //   make a copy of the answers.
                foreach (object[] answer in _allAnswers.ToArray())
                {
                    foreach (bool l2 in YP.unifyArrays(arguments, answer))
                    {
                        yield return(false);
                    }
                }
            }
        }
예제 #17
0
        static IEnumerable <bool> queens3(object UnplacedQs, object SafeQs, object Qs)
        {
            Variable UnplacedQs1 = new Variable();
            Variable Q           = new Variable();

            foreach (bool l1 in selectq(Q, UnplacedQs, UnplacedQs1))
            {
                foreach (bool l2 in notHasAttack(Q, SafeQs))
                {
                    foreach (bool l3 in queens3(UnplacedQs1, new ListPair(Q, SafeQs), Qs))
                    {
                        yield return(false);
                    }
                }
            }
            foreach (bool l1 in YP.unify(UnplacedQs, Atom.NIL))
            {
                foreach (bool l2 in YP.unify(Qs, SafeQs))
                {
                    yield return(false);
                }
            }
        }
예제 #18
0
 /// <summary>
 /// If this Variable is bound, then just call YP.unify to unify this with arg.
 /// (Note that if arg is an unbound Variable, then YP.unify will bind it to
 /// this Variable's value.)
 /// Otherwise, bind this Variable to YP.getValue(arg) and yield once.  After the
 /// yield, return this Variable to the unbound state.
 /// For more details, see http://yieldprolog.sourceforge.net/tutorial1.html
 /// </summary>
 /// <param name="arg"></param>
 /// <returns></returns>
 public IEnumerable <bool> unify(object arg)
 {
     if (!_isBound)
     {
         _value = YP.getValue(arg);
         if (_value == this)
         {
             // We are unifying this unbound variable with itself, so leave it unbound.
             yield return(false);
         }
         else
         {
             _isBound = true;
             try
             {
                 yield return(false);
             }
             finally
             {
                 // Remove the binding.
                 _isBound = false;
             }
         }
     }
     else
     {
         // disable warning on l1, don't see how we can
         // code this differently
         #pragma warning disable 0168, 0219
         foreach (bool l1 in YP.unify(this, arg))
         {
             yield return(false);
         }
         #pragma warning restore 0168, 0219
     }
 }
예제 #19
0
        public IEnumerable <bool> match(object[] arguments)
        {
            if (arguments.Length != _arity)
            {
                yield break;
            }

            // Set up indexArgs, up to arg position MAX_INDEX_ARGS.  The signature has a 1 bit for
            //   each non-null index arg.
            HashedList indexArgs       = new HashedList(arguments.Length);
            bool       gotAllIndexArgs = true;
            int        signature       = 0;

            for (int i = 0; i < arguments.Length; ++i)
            {
                object indexValue = null;
                if (i < MAX_INDEX_ARGS)
                {
                    // We limit the number of args in a 32-bit signature.
                    indexValue = getIndexValue(YP.getValue(arguments[i]));
                    if (indexValue != null)
                    {
                        signature += (1 << i);
                    }
                }
                if (indexValue == null)
                {
                    gotAllIndexArgs = false;
                }
                indexArgs.Add(indexValue);
            }

            List <object[]> answers;

            if (signature == 0)
            {
                // No index args, so we have to match from _allAnswers.
                answers = _allAnswers;
            }
            else
            {
                if (!_gotAnswersForSignature.ContainsKey(signature))
                {
                    // We need to create the entry in _indexedAnswers.
                    foreach (object[] answer in _allAnswers)
                    {
                        indexAnswerForSignature(answer, signature);
                    }
                    // Mark that we did this signature.
                    _gotAnswersForSignature[signature] = null;
                }
                if (!_indexedAnswers.TryGetValue(indexArgs, out answers))
                {
                    yield break;
                }
            }

            if (gotAllIndexArgs)
            {
                // All the arguments were already bound, so we don't need to do bindings.
                yield return(false);

                yield break;
            }

            // Find matches in answers.
            IEnumerator <bool>[] iterators = new IEnumerator <bool> [arguments.Length];
            // Debug: If the caller asserts another answer into this same predicate during yield, the iterator
            //   over clauses will be corrupted.  Should we take the time to copy answers?
            foreach (object[] answer in answers)
            {
                bool gotMatch   = true;
                int  nIterators = 0;
                // Try to bind all the arguments.
                for (int i = 0; i < arguments.Length; ++i)
                {
                    if (indexArgs[i] != null)
                    {
                        // We already matched this argument by looking up _indexedAnswers.
                        continue;
                    }

                    IEnumerator <bool> iterator = YP.unify(arguments[i], answer[i]).GetEnumerator();
                    iterators[nIterators++] = iterator;
                    // MoveNext() is true if YP.unify succeeds.
                    if (!iterator.MoveNext())
                    {
                        gotMatch = false;
                        break;
                    }
                }
                int z = 0;
                try
                {
                    if (gotMatch)
                    {
                        yield return(false);
                    }
                }
                finally
                {
                    // Manually finalize all the iterators.
                    for (z = 0; z < nIterators; ++z)
                    {
                        iterators[z].Dispose();
                    }
                }
            }
        }