Ejemplo n.º 1
0
        public static TrsTypeDefinitionTermBase Convert(this TrsTermBase termIn)
        {
            TrsAtom     atom     = termIn as TrsAtom;
            TrsVariable variable = termIn as TrsVariable;
            TrsTerm     term     = termIn as TrsTerm;
            TrsAcTerm   acTerm   = termIn as TrsAcTerm;

            if (atom != null)
            {
                return(atom.Convert());
            }
            else if (variable != null)
            {
                return(variable.Convert());
            }
            else if (term != null)
            {
                return(term.Convert());
            }
            else if (acTerm != null)
            {
                return(acTerm.Convert());
            }
            else
            {
                throw new Exception("Unexpected type: " + termIn.GetType().FullName);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Returns empty list if the terms in the equation cannot be unified or if Lhs = Rhs with no variables,
        /// otherwise a list of substitutions defining the MGU
        ///
        /// Based on Unification chapter from Handbook of Automated Reasoning.
        /// </summary>
        private List <UnificationResult> GetMgu(Equation unificationProblem, List <TrsVariable> variableNamesToPreserve)
        {
            if (unificationProblem == null)
            {
                throw new ArgumentException();
            }
            if (unificationProblem.Lhs == null)
            {
                throw new ArgumentException();
            }
            if (unificationProblem.Rhs == null)
            {
                throw new ArgumentException();
            }
            if (variableNamesToPreserve == null)
            {
                throw new ArgumentException();
            }

            Equation initialEquation = unificationProblem.CreateCopy();
            UnificationContinuation currentProblem = new UnificationContinuation
            {
                CurrentEquations     = new List <Equation>(),
                CurrentSubstitutions = new List <Substitution>()
            };

            currentProblem.CurrentEquations.Add(initialEquation);
            Queue <UnificationContinuation> currentContinuations = new Queue <UnificationContinuation>();

            currentContinuations.Enqueue(currentProblem);
            HashSet <UnificationResult> results = new HashSet <UnificationResult>();

            Func <UnificationContinuation, Equation, bool> processFail = delegate(UnificationContinuation curr, Equation currEq)
            {
                var failResult = CustomFail(currentProblem, currEq, variableNamesToPreserve);
                var succeed    = true;
                if (failResult.Count == 0)
                {
                    succeed = false;
                }
                else if (failResult.Count == 1)
                {
                    currentProblem = failResult.First();
                }
                else
                {
                    foreach (var continuation in failResult)
                    {
                        currentContinuations.Enqueue(continuation);
                    }
                }
                return(succeed);
            };

            while (currentContinuations.Count > 0)
            {
                currentProblem = currentContinuations.Dequeue();
                bool fail = false;
                while (currentProblem.CurrentEquations.Count > 0 && !fail)
                {
                    var currEq = currentProblem.CurrentEquations[currentProblem.CurrentEquations.Count - 1];
                    currentProblem.CurrentEquations.RemoveAt(currentProblem.CurrentEquations.Count - 1);
                    if (currEq.Lhs.Equals(currEq.Rhs))
                    {
                        // Elimination by omission (this is a "succeed" case)
                    }
                    else if (currEq.Lhs is TrsAtom && currEq.Rhs is TrsAtom)
                    {
                        if (!currEq.Lhs.Equals(currEq.Rhs))
                        {
                            fail = !processFail(currentProblem, currEq);
                        }
                    }
                    else if (currEq.Lhs is TrsAtom && currEq.Rhs is TrsTerm ||
                             currEq.Lhs is TrsTerm && currEq.Rhs is TrsAtom ||
                             currEq.Lhs is TrsAtom && currEq.Rhs is TrsAcTerm ||
                             currEq.Lhs is TrsAcTerm && currEq.Rhs is TrsAtom ||
                             currEq.Lhs is TrsTerm && currEq.Rhs is TrsAcTerm ||
                             currEq.Lhs is TrsAcTerm && currEq.Rhs is TrsTerm)
                    {
                        fail = !processFail(currentProblem, currEq);
                    }
                    else if (currEq.Lhs is TrsTerm && currEq.Rhs is TrsTerm)
                    {
                        TrsTerm lhs = currEq.Lhs as TrsTerm;
                        TrsTerm rhs = currEq.Rhs as TrsTerm;
                        if (lhs.Name != rhs.Name || lhs.Arguments.Count != rhs.Arguments.Count)
                        {
                            fail = !processFail(currentProblem, currEq);
                        }
                        else
                        {
                            currentProblem.CurrentEquations.AddRange(Enumerable.Range(0, lhs.Arguments.Count).
                                                                     Select(i => new Equation {
                                Lhs = lhs.Arguments[i], Rhs = rhs.Arguments[i]
                            }));
                        }
                    }
                    else if (currEq.Lhs is TrsAcTerm && currEq.Rhs is TrsAcTerm)
                    {
                        // Note: Failure is already processed internally in the next function call (ie. custom unifiers are called)
                        fail = ProcessAcUnificationStep(currentProblem, currentContinuations, processFail, currEq);
                    }
                    else if (!(currEq.Lhs is TrsVariable) && (currEq.Rhs is TrsVariable))
                    {
                        TrsTermBase lhsSwap = currEq.Lhs;
                        currEq.Lhs = currEq.Rhs;
                        currEq.Rhs = lhsSwap;
                        currentProblem.CurrentEquations.Add(currEq);
                    }
                    else if (currEq.Lhs is TrsVariable)
                    {
                        // Occurs check
                        if (currEq.Rhs.ContainsVariable((TrsVariable)currEq.Lhs))
                        {
                            fail = !processFail(currentProblem, currEq);
                        }
                        else
                        {
                            ProcessSubstitutionStep(currentProblem, currEq, variableNamesToPreserve);
                        }
                    }
                    else
                    {
                        throw new Exception("Invalid program state");
                    }
                }
                if (!fail)
                {
                    results.Add(new UnificationResult
                    {
                        Succeed = true,
                        Unifier = currentProblem.CurrentSubstitutions
                    });
                }
            }
            return(results.ToList());
        }
Ejemplo n.º 3
0
 public static TrsTypeDefinitionTerm Convert(this TrsTerm term)
 {
     return(new TrsTypeDefinitionTerm(term.Name,
                                      term.Arguments.Select(arg => arg.Convert()).ToList()));
 }