コード例 #1
0
 public bool termEqual(object term)
 {
     term = YP.getValue(term);
     if (term is Functor)
     {
         Functor termFunctor = (Functor)term;
         if (_name.Equals(termFunctor._name) && _args.Length == termFunctor._args.Length)
         {
             for (int i = 0; i < _args.Length; ++i)
             {
                 if (!YP.termEqual(_args[i], termFunctor._args[i]))
                 {
                     return(false);
                 }
             }
             return(true);
         }
     }
     return(false);
 }
コード例 #2
0
        /// <summary>
        /// To get the free variables, split off any existential qualifiers from Goal such as the X in
        /// "X ^ f(Y)", get the set of unbound variables in Goal that are not qualifiers, then remove
        /// the unbound variables that are qualifiers as well as the unbound variables in Template.
        /// </summary>
        /// <param name="Template"></param>
        /// <param name="Goal"></param>
        public BagofAnswers(object Template, object Goal)
        {
            _template = Template;

            // First get the set of variables that are not free variables.
            List <Variable> variableSet = new List <Variable>();

            YP.addUniqueVariables(Template, variableSet);
            object UnqualifiedGoal = YP.getValue(Goal);

            while (UnqualifiedGoal is Functor2 && ((Functor2)UnqualifiedGoal)._name == Atom.HAT)
            {
                YP.addUniqueVariables(((Functor2)UnqualifiedGoal)._arg1, variableSet);
                UnqualifiedGoal = YP.getValue(((Functor2)UnqualifiedGoal)._arg2);
            }

            // Remember how many non-free variables there are so we can find the unique free variables
            //   that are added.
            int nNonFreeVariables = variableSet.Count;

            YP.addUniqueVariables(UnqualifiedGoal, variableSet);
            int nFreeVariables = variableSet.Count - nNonFreeVariables;

            if (nFreeVariables == 0)
            {
                // There were no free variables added, so we won't waste time with _bagForFreeVariables.
                _freeVariables   = null;
                _findallBagArray = new List <object>();
            }
            else
            {
                // Copy the free variables.
                _freeVariables = new Variable[nFreeVariables];
                for (int i = 0; i < nFreeVariables; ++i)
                {
                    _freeVariables[i] = variableSet[i + nNonFreeVariables];
                }

                _bagForFreeVariables = new Dictionary <object[], List <object> >(_termArrayEqualityComparer);
            }
        }
コード例 #3
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);
             }
         }
     }
 }
コード例 #4
0
 /// <summary>
 /// If arg is another Functor1, then succeed (yield once) if this and arg have the
 /// same name and the 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).
 /// </summary>
 /// <param name="arg"></param>
 /// <returns></returns>
 public IEnumerable <bool> unify(object arg)
 {
     arg = YP.getValue(arg);
     if (arg is Functor1)
     {
         Functor1 argFunctor = (Functor1)arg;
         if (_name.Equals(argFunctor._name))
         {
             foreach (bool l1 in YP.unify(_arg1, argFunctor._arg1))
             {
                 yield return(false);
             }
         }
     }
     else if (arg is Variable)
     {
         foreach (bool l1 in ((Variable)arg).unify(this))
         {
             yield return(false);
         }
     }
 }
コード例 #5
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);
                    }
                }
            }
        }
コード例 #6
0
        /// <summary>
        /// Return an array of the elements in list or null if it is not
        /// a proper list.  If list is Atom.NIL, return an array of zero elements.
        /// If the list or one of the tails of the list is Variable, raise an instantiation_error.
        /// This does not call YP.getValue on each element.
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        public static object[] toArray(object list)
        {
            list = YP.getValue(list);
            if (list.Equals(Atom.NIL))
            {
                return(new object[0]);
            }

            List <object> result  = new List <object>();
            object        element = list;

            while (true)
            {
                if (element == Atom.NIL)
                {
                    break;
                }
                if (element is Variable)
                {
                    throw new PrologException(Atom.a("instantiation_error"),
                                              "List tail is an unbound variable");
                }
                if (!(element is Functor2 && ((Functor2)element)._name == Atom.DOT))
                {
                    // Not a proper list.
                    return(null);
                }
                result.Add(((Functor2)element)._arg1);
                element = YP.getValue(((Functor2)element)._arg2);
            }

            if (result.Count <= 0)
            {
                return(null);
            }
            return(result.ToArray());
        }
コード例 #7
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
     }
 }
コード例 #8
0
ファイル: Queens.cs プロジェクト: MatiasNAmendola/YieldProlog
        static IEnumerable <bool> selectq(Variable X, ListPair Arg2, Variable Arg3)
        {
            foreach (bool l1 in X.unify(Arg2._arg1))
            {
                foreach (bool l2 in Arg3.unify(Arg2._arg2))
                {
                    yield return(false);
                }
            }

            ListPair Arg2Tail = YP.getValue(Arg2._arg2) as ListPair;

            if (Arg2Tail != null)
            {
                Variable Zs = new Variable();
                foreach (bool l1 in selectq(X, Arg2Tail, Zs))
                {
                    foreach (bool l2 in Arg3.unify(new ListPair(Arg2._arg1, Zs)))
                    {
                        yield return(false);
                    }
                }
            }
        }
コード例 #9
0
 /// <summary>
 /// If arg is another Functor, 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).
 /// </summary>
 /// <param name="arg"></param>
 /// <returns></returns>
 public IEnumerable <bool> unify(object arg)
 {
     arg = YP.getValue(arg);
     if (arg is Functor)
     {
         Functor argFunctor = (Functor)arg;
         if (_name.Equals(argFunctor._name))
         {
             return(YP.unifyArrays(_args, argFunctor._args));
         }
         else
         {
             return(YP.fail());
         }
     }
     else if (arg is Variable)
     {
         return(((Variable)arg).unify(this));
     }
     else
     {
         return(YP.fail());
     }
 }
コード例 #10
0
 /// <summary>
 /// Create a PrologException with the given Term.  The printable exception message is the full Term.
 /// </summary>
 /// <param name="Term">the term of the exception</param>
 public PrologException(object Term)
     : base(YP.getValue(Term).ToString())
 {
     _term = YP.makeCopy(Term, new Variable.CopyStore());
 }
コード例 #11
0
 public bool termEqual(object term)
 {
     return(Equals(YP.getValue(term)));
 }
コード例 #12
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();
                    }
                }
            }
        }
コード例 #13
0
 public override int GetHashCode()
 {
     // Note: The infrequent collision where changing the order of args gives the same hash value is OK.
     return(_name.GetHashCode() ^ YP.getValue(_arg1).GetHashCode()
            ^ YP.getValue(_arg2).GetHashCode());
 }
コード例 #14
0
 public override int GetHashCode()
 {
     return(_name.GetHashCode() ^ YP.getValue(_arg1).GetHashCode());
 }
コード例 #15
0
 public override string ToString()
 {
     return(_name + "(" + YP.getValue(_arg1) + ")");
 }