Esempio n. 1
0
        public bool UnifiesNoUndo(ITerm term, ITerm term2)
        {
            if (term == null && term2 == null)
            {
                return(true);
            }
            if (term == null && term2 != null)
            {
                return(false);
            }
            if (term != null && term2 == null)
            {
                return(false);
            }

            Pred np1 = null;
            Pred np2 = null;

            if (np1.GetType() == typeof(Pred) && np2.GetType() == typeof(Pred))
            {
                np1 = (Pred)term;
                np2 = (Pred)term2;

                // tests when np1 or np2 are variables with annotations
                if (np1.IsVar() && np1.HasAnnot() || np2.IsVar() && np2.HasAnnot())
                {
                    if (!np1.HasSubsetAnnot(np2, this))
                    {
                        return(false);
                    }
                }
            }

            if (term.IsCyclicTerm() && term2.IsCyclicTerm()) // Both are cycled terms
            {
                // Unification of cyclic terms: Remove variables to avoid loops and test the structure, then reintroduce vars
                VarTerm v1 = term.GetCyclicVar();
                VarTerm v2 = term2.GetCyclicVar();
                Remove(v1);
                Remove(v2);
                try
                {
                    return(UnifiesNoUndo(new LiteralImpl((Literal)term), new LiteralImpl((Literal)term2)));
                }
                finally
                {
                    function.Add(v1, term);
                    function.Add(v2, term2);
                }
            }
            else
            {
                if (term.IsCyclicTerm() && Get(term.GetCyclicVar()) == null) // Reintroduce cycles in the unifier
                {
                    function.Add(term.GetCyclicVar(), term);
                }
                if (term2.IsCyclicTerm() && Get(term.GetCyclicVar()) == null)
                {
                    function.Add(term2.GetCyclicVar(), term2);
                }
            }

            // Unify as Term
            bool ok = UnifyTerms(term, term2);

            // If term is a unified variable, clear its annotations
            if (ok && term != null) // Both are predicates
            {
                if (term.IsVar() && ((Pred)term).HasAnnot())
                {
                    term = Deref((VarTerm)term); // ???
                    ITerm termvl;
                    function.TryGetValue((VarTerm)term, out termvl);
                    if (termvl != null && termvl.IsPred())
                    {
                        Pred pvl = (Pred)termvl.Clone();
                        pvl.ClearAnnots();
                        Bind((VarTerm)term, pvl);
                    }
                }
                if (term2.IsVar() && ((Pred)term2).HasAnnot())
                {
                    term2 = Deref((VarTerm)term2);
                    ITerm term2vl;
                    function.TryGetValue((VarTerm)term2, out term2vl);
                    if (term2vl != null && term2vl.IsPred())
                    {
                        Pred pvl = (Pred)term2vl.Clone();
                        pvl.ClearAnnots();
                        Bind((VarTerm)term2, pvl);
                    }
                }
            }
            return(ok);
        }