Exemple #1
0
            public bool MoveNext(
                EquivalenceRelation <StdTerm> eqs,
                Map <StdTerm, bool> history,
                out StdTerm u,
                out bool violated)
            {
                bool isVisited;

                while (freeOccIt.MoveNext())
                {
                    u = eqs.GetRepresentative(freeOccIt.Current);
                    if (history.TryFindValue(u, out isVisited))
                    {
                        if (!isVisited)
                        {
                            violated = true;
                            return(false);
                        }

                        continue;
                    }

                    violated = false;
                    return(true);
                }

                u        = default(StdTerm);
                violated = false;
                return(false);
            }
Exemple #2
0
        private static void RegisterSelectors(Set <StdTerm> allVars, EquivalenceRelation <StdTerm> eqs, StdTerm stdterm)
        {
            var index = stdterm.term.Owner;
            var t     = stdterm.term;

            eqs.Add(stdterm);
            while (t.Symbol == index.SelectorSymbol)
            {
                eqs.AddToTrackSet(
                    t.Args[0].Standardize(stdterm.label),
                    Track_FreeOccurs,
                    t.Standardize(stdterm.label));
                t = t.Args[0];
            }

            Contract.Assert(t.Symbol.IsVariable);
            allVars.Add(t.Standardize(stdterm.label));
        }
Exemple #3
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);
        }
Exemple #4
0
        private static bool OccursCheck(Set <StdTerm> vars, EquivalenceRelation <StdTerm> eqs)
        {
            //// History[v] is false if the occurs check is visiting v.
            //// History[v] is true if the occurs check visited v and did not find violations.
            var history = new Map <StdTerm, bool>(StdTerm.Compare);
            var stack   = new Stack <OccursState>();

            StdTerm     u, rep;
            OccursState top;
            bool        isVisited, violated;

            foreach (var v in vars)
            {
                rep = eqs.GetRepresentative(v);
                if (history.TryFindValue(rep, out isVisited))
                {
                    Contract.Assert(isVisited);
                    continue;
                }

                stack.Push(new OccursState(rep, history, eqs));
                while (stack.Count > 0)
                {
                    top = stack.Peek();
                    if (top.MoveNext(eqs, history, out u, out violated))
                    {
                        stack.Push(new OccursState(u, history, eqs));
                    }
                    else if (violated)
                    {
                        return(false);
                    }
                    else
                    {
                        stack.Pop().Finished(history);
                    }
                }
            }

            return(true);
        }
Exemple #5
0
 public OccursState(StdTerm rep, Map <StdTerm, bool> history, EquivalenceRelation <StdTerm> eqs)
 {
     this.rep       = rep;
     this.freeOccIt = eqs.GetTrackSet(rep, Track_FreeOccurs).GetEnumerator();
     history.Add(rep, false);
 }
Exemple #6
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));
        }
Exemple #7
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);
        }