Esempio n. 1
0
        private static void Bind(
            Set <StdTerm> allVars,
            EquivalenceRelation <StdTerm> eqs,
            Stack <Tuple <StdTerm, StdTerm> > pending,
            StdTerm bindee,
            StdTerm binding)
        {
            if (eqs.Equals(bindee, binding))
            {
                return;
            }

            var index = bindee.term.Owner;

            Contract.Assert(bindee.term.Symbol == index.SelectorSymbol || bindee.term.Symbol.IsVariable);
            Contract.Assert(binding.term.Symbol == index.SelectorSymbol || binding.term.Symbol.IsVariable || binding.term.Symbol.IsDataConstructor || binding.term.Symbol.IsNonVarConstant);

            RegisterSelectors(allVars, eqs, bindee);
            if (binding.term.Symbol.IsDataConstructor || binding.term.Symbol.IsNonVarConstant)
            {
                var crntBinding = eqs.SetTracker(bindee, Track_FreeApply, binding);
                if (StdTerm.Compare(crntBinding, binding) != 0)
                {
                    pending.Push(new Tuple <StdTerm, StdTerm>(crntBinding, binding));
                }

                binding.term.Visit(
                    x => x.Groundness == Groundness.Variable && x.Symbol.IsDataConstructor ? x.Args : null,
                    x =>
                {
                    if (x.Symbol.IsVariable || x.Symbol == index.SelectorSymbol)
                    {
                        RegisterSelectors(allVars, eqs, x.Standardize(binding.label));
                        eqs.AddToTrackSet(bindee, Track_FreeOccurs, x.Standardize(binding.label));
                    }
                });
            }
            else
            {
                RegisterSelectors(allVars, eqs, binding);
            }

            eqs.Equate(bindee, binding);
        }
Esempio n. 2
0
        public static bool IsUnifiable(Term tA, Term tB, bool standardize = true)
        {
            Contract.Requires(tA != null && tB != null);
            Contract.Requires(tA.Owner == tB.Owner);

            var eqs           = new EquivalenceRelation <StdTerm>(StdTerm.Compare, 1, 1);
            var success       = new SuccessToken();
            var relabelSymbol = tA.Owner.SymbolTable.GetOpSymbol(ReservedOpKind.Relabel);
            var pending       = new Stack <Tuple <StdTerm, StdTerm> >();

            pending.Push(new Tuple <StdTerm, StdTerm>(tA.Standardize(0), tB.Standardize(standardize ? 1 : 0)));

            int  lblA, lblB;
            Term trmA, trmB;
            Tuple <StdTerm, StdTerm> top;
            Set <StdTerm>            allVars = new Set <StdTerm>(StdTerm.Compare);

            while (pending.Count > 0)
            {
                top = pending.Pop();
                if (StdTerm.Compare(top.Item1, top.Item2) == 0)
                {
                    continue;
                }

                top.GetComponents(out trmA, out lblA, out trmB, out lblB);
                trmA.Compute <Unit>(
                    trmB,
                    (xA, xB, s) =>
                {
                    if (xA.Symbol == relabelSymbol)
                    {
                        xA = EliminateRelabel(xA);
                    }

                    if (xB.Symbol == relabelSymbol)
                    {
                        xB = EliminateRelabel(xB);
                    }

                    if (xA.Groundness == Groundness.Ground && xB.Groundness == Groundness.Ground)
                    {
                        //// If x1 and x2 are ground, then just check equality.
                        if (xA != xB)
                        {
                            success.Failed();
                        }

                        return(null);
                    }
                    else if ((xA.Symbol.IsDataConstructor || xA.Symbol.IsNonVarConstant) &&
                             (xB.Symbol.IsDataConstructor || xB.Symbol.IsNonVarConstant))
                    {
                        //// If x1 and x2 are both data constructors,
                        //// then check symbol equality and unroll.
                        if (xA.Symbol != xB.Symbol)
                        {
                            success.Failed();
                            return(null);
                        }

                        return(new Tuple <IEnumerable <Term>, IEnumerable <Term> >(xA.Args, xB.Args));
                    }
                    else if (xA.Symbol.IsVariable || xA.Symbol == xA.Owner.SelectorSymbol)
                    {
                        Bind(allVars, eqs, pending, xA.Standardize(lblA), xB.Standardize(lblB));
                        return(null);
                    }
                    else
                    {
                        Bind(allVars, eqs, pending, xB.Standardize(lblB), xA.Standardize(lblA));
                        return(null);
                    }
                },
                    (xA, xB, ch, s) =>
                {
                    return(default(Unit));
                },
                    success);
            }

            if (!success.Result)
            {
                return(false);
            }

            return(OccursCheck(allVars, eqs));
        }
Esempio n. 3
0
        private static Term MkMGU(StdTerm t, EquivalenceRelation <StdTerm> eqs, Func <int, Term> varCreator)
        {
            Term    normVar;
            StdTerm stdRep, stdX;
            int     i, label;
            bool    wasAdded;
            var     varMap     = new Map <StdTerm, Term>(StdTerm.Compare);
            var     labelStack = new Stack <int>();

            labelStack.Push(t.label);
            var result = t.term.Compute <Term>(
                (x, s) =>
            {
                if (x.Groundness == Groundness.Ground)
                {
                    labelStack.Push(labelStack.Peek());
                    return(null);
                }
                else if (!x.Symbol.IsVariable)
                {
                    labelStack.Push(labelStack.Peek());
                    return(x.Args);
                }

                stdX = x.Standardize(labelStack.Peek());
                if (eqs.GetTracker(stdX, Track_FreeApply, out stdRep))
                {
                    labelStack.Push(stdRep.label);
                    return(EnumerableMethods.GetEnumerable <Term>(stdRep.term));
                }
                else if (StdTerm.Compare(stdRep = eqs.GetRepresentative(stdX), stdX) == 0)
                {
                    labelStack.Push(labelStack.Peek());
                    return(null);
                }
                else
                {
                    labelStack.Push(stdRep.label);
                    return(EnumerableMethods.GetEnumerable <Term>(stdRep.term));
                }
            },
                (x, c, s) =>
            {
                label = labelStack.Pop();
                if (x.Groundness == Groundness.Ground)
                {
                    return(x);
                }
                else if (!x.Symbol.IsVariable)
                {
                    i        = 0;
                    var args = new Term[x.Symbol.Arity];
                    foreach (var tp in c)
                    {
                        args[i++] = tp;
                    }

                    return(x.Owner.MkApply(x.Symbol, args, out wasAdded));
                }

                if (c.IsEmpty <Term>())
                {
                    if (!varMap.TryFindValue(x.Standardize(label), out normVar))
                    {
                        normVar = varCreator(varMap.Count);
                        varMap.Add(x.Standardize(label), normVar);
                    }

                    return(normVar);
                }
                else
                {
                    return(c.First <Term>());
                }
            });

            Contract.Assert(labelStack.Count == 1);
            return(result);
        }