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); } }
/// <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()); }
public static TrsTypeDefinitionTerm Convert(this TrsTerm term) { return(new TrsTypeDefinitionTerm(term.Name, term.Arguments.Select(arg => arg.Convert()).ToList())); }