public override TrsTermBase CreateCopyAndReplaceSubTerm(TrsTermBase termToReplace, TrsTermBase replacementTerm) { if (this.Equals(termToReplace)) { return(replacementTerm); } else { // Cant directly invoke child constructor ... otherwise lots of code duplication has to take place, or ugly reflection if (this is TrsNumber) { return(new TrsNumber(Value)); } else if (this is TrsConstant) { return(new TrsConstant(Value)); } else if (this is TrsString) { return(new TrsString(Value)); } else { throw new ArgumentException("this"); } } }
/// <summary> /// Applies a set of substitutions to this term, swapping variables. If no substitution applies to a term, /// the term is returned. /// </summary> /// <param name="substitutions"></param> /// <returns></returns> public TrsTermBase ApplySubstitutions(IEnumerable <Substitution> substitutions) { TrsTermBase retVal = this; foreach (var substitution in substitutions) { retVal = retVal.ApplySubstitution(substitution); } return(retVal); }
public override TrsTermBase CreateCopyAndReplaceSubTerm(TrsTermBase termToReplace, TrsTermBase replacementTerm) { TrsTermProduct product = new TrsTermProduct(new List<TrsTermBase>()); foreach (var term in TermList) { if (term.Equals(termToReplace)) product.TermList.Add(replacementTerm); else product.TermList.Add(term.CreateCopyAndReplaceSubTerm(termToReplace, replacementTerm)); } return product; }
public override TrsTermBase CreateCopyAndReplaceSubTerm(TrsTermBase termToReplace, TrsTermBase replacementTerm) { if (this.Equals(termToReplace)) { return replacementTerm; } else { return new TrsTerm(Name, Arguments.Select(arg => arg.CreateCopyAndReplaceSubTerm(termToReplace, replacementTerm))); } }
public override TrsTermBase CreateCopyAndReplaceSubTerm(TrsTermBase termToReplace, TrsTermBase replacementTerm) { if (this.Equals(termToReplace)) { return(replacementTerm); } else { return(new TrsVariable(Name)); } }
public override TrsTermBase CreateCopyAndReplaceSubTerm(TrsTermBase termToReplace, TrsTermBase replacementTerm) { if (this.Equals(termToReplace)) { return replacementTerm; } else { return new TrsVariable(Name); } }
public InterpreterEvaluationTerm(TrsTermBase root, TrsTermBase subterm, InterpreterTerm cacheSourceTerm, UnificationResult currentUnifier) : base(root) { if (subterm == null) throw new ArgumentException("subterm"); if (cacheSourceTerm == null) throw new ArgumentException("cacheSourceTerm"); if (currentUnifier == null) throw new ArgumentException("currentUnifier"); CurrentSubTerm = subterm; CacheSourceTerm = cacheSourceTerm; Unifier = currentUnifier; }
public override TrsTermBase CreateCopyAndReplaceSubTerm(TrsTermBase termToReplace, TrsTermBase replacementTerm) { if (this.Equals(termToReplace)) { return(replacementTerm); } else { return(new TrsTerm(Name, Arguments.Select(arg => arg.CreateCopyAndReplaceSubTerm(termToReplace, replacementTerm)))); } }
public override TrsTermBase CreateCopyAndReplaceSubTerm(TrsTermBase termToReplace, TrsTermBase replacementTerm) { if (this.Equals(termToReplace)) { return replacementTerm; } else { // Cant directly invoke child constructor ... otherwise lots of code duplication has to take place, or ugly reflection if (this is TrsNumber) return new TrsNumber(Value); else if (this is TrsConstant) return new TrsConstant(Value); else if (this is TrsString) return new TrsString(Value); else throw new ArgumentException("this"); } }
public override TrsTermBase CreateCopyAndReplaceSubTerm(TrsTermBase termToReplace, TrsTermBase replacementTerm) { if (termToReplace != null && this.Equals(termToReplace)) { return((TrsTermBase)replacementTerm.CreateCopy()); } else { return(new TrsAcTerm(Name, OnfArguments.Select(rankedPair => new TrsOnfAcTermArgument { Term = (TrsTermBase)(rankedPair.Term.Equals(termToReplace) ? replacementTerm.CreateCopy() : rankedPair.Term.CreateCopy()), Cardinality = rankedPair.Cardinality }))); } }
public override TrsTermBase CreateCopyAndReplaceSubTerm(TrsTermBase termToReplace, TrsTermBase replacementTerm) { TrsTermProduct product = new TrsTermProduct(new List <TrsTermBase>()); foreach (var term in TermList) { if (term.Equals(termToReplace)) { product.TermList.Add(replacementTerm); } else { product.TermList.Add(term.CreateCopyAndReplaceSubTerm(termToReplace, replacementTerm)); } } return(product); }
public TrsTermBase Evaluate(TrsTermBase termIn) { var tIn = termIn as TrsTerm; var tInAc = termIn as TrsAcTerm; if (tIn != null) { if (tIn.Arguments.Count != 2) return termIn; if (!(tIn.Arguments[0] is TrsNumber) || !(tIn.Arguments[1] is TrsNumber)) return termIn; var numLhs = Convert.ToDouble(((TrsNumber)tIn.Arguments[0]).Value); var numRhs = Convert.ToDouble(((TrsNumber)tIn.Arguments[1]).Value); double retVal; switch (tIn.Name.ToLower()) { case Subtraction: retVal = numLhs - numRhs; break; case Divide: if (numRhs == 0) return tIn; else retVal = numLhs / numRhs; break; default: return tIn; } return new TrsNumber(retVal.ToString()); } else if (tInAc != null) { if (tInAc.TotalCardinality < 2) throw new InvalidProgramException("AC term with less than 2 arguments"); if (tInAc.OnfArguments.Where(arg => arg.Term is TrsNumber).Select(arg => arg.Cardinality).Count() != tInAc.TotalCardinality) return tInAc; if (tInAc.Name == Addition) { return new TrsNumber(tInAc.ExpandedArguments.Select(arg => Convert.ToDouble(((TrsNumber)arg).Value)).Sum().ToString()); } else if (tInAc.Name == Multiply) { double retVal = 1.0; foreach (var number in tInAc.ExpandedArguments.Select(arg => Convert.ToDouble(((TrsNumber)arg).Value))) retVal *= number; return new TrsNumber(retVal.ToString()); } else return tInAc; } else return termIn; }
public InterpreterTerm(TrsTermBase root) { if (root == null) throw new ArgumentException("Root may not be null","root"); RootTerm = root; }
/// <summary> /// Creates a copy of this term, replacing the termToReplace with the replacementTerm. /// Term equality is defined using the overloaded equals method. /// </summary> /// <returns></returns> public abstract TrsTermBase CreateCopyAndReplaceSubTerm(TrsTermBase termToReplace, TrsTermBase replacementTerm);
/// <summary> /// Checks that the given unifier is valid in terms of the type definitions. /// </summary> private bool IsUnifierValid(UnificationResult unifier, TrsTermBase matchedRuleHead) { // Variables at this level must be validated in a way that is sensitive to AC term type definitions // to account for semantics. If it is not add[:x,:y] will not match add[1,2,3] with limit :x,:y to $TrsNumber if (!unifier.Succeed) return false; if (unifier.Unifier.Count == 0) return true; // equal terms, nothing to validate // Keep track of variable parent cases Stack<TrsTermBase> evalStack = new Stack<TrsTermBase>(); Dictionary<TrsVariable, bool> isAcParent = new Dictionary<TrsVariable, bool>(); Dictionary<TrsVariable, bool> isNonAcParent = new Dictionary<TrsVariable, bool>(); Dictionary<TrsVariable, HashSet<string>> variableTermNames = new Dictionary<TrsVariable, HashSet<string>>(); evalStack.Push(matchedRuleHead); Action<TrsVariable, bool, Dictionary<TrsVariable, bool>> updateLookups = delegate(TrsVariable v, bool b, Dictionary<TrsVariable, bool> target) { if (target.ContainsKey(v)) target[v] = b; else target.Add(v, b); }; while (evalStack.Count > 0) { var current = evalStack.Pop(); // Variable only case ... this should not happen unless variable only reduction rule heads are allowed in the future var currentVariable = current as TrsVariable; if (currentVariable != null) { updateLookups(currentVariable, false, isAcParent); updateLookups(currentVariable, false, isNonAcParent); } else { // Check arguments var curTerm = current as TrsTerm; var curAcTerm = current as TrsAcTerm; foreach (var variable in Enumerable.Concat(curTerm == null ? new TrsVariable[0] : curTerm.Arguments.Where(arg => arg is TrsVariable).Cast<TrsVariable>(), curAcTerm == null ? new TrsVariable[0] : curAcTerm.OnfArguments.Where(arg => arg.Term is TrsVariable).Select(arg => arg.Term).Cast<TrsVariable>())) { updateLookups(variable, curTerm != null, isNonAcParent); updateLookups(variable, curAcTerm != null, isAcParent); if (curAcTerm != null) { HashSet<string> termNames; if (!variableTermNames.TryGetValue(variable, out termNames)) variableTermNames.Add(variable, termNames = new HashSet<string>()); termNames.Add(curAcTerm.Name); } } } } bool isValid = true; foreach (var substitution in unifier.Unifier) { // It is possible that the variable being tested does not occur in the term head ... if (!isNonAcParent.ContainsKey(substitution.Variable) && !isAcParent.ContainsKey(substitution.Variable)) { isValid = isValid && typeChecker.IsSubstitutionValid(substitution); continue; } // AC term case if (isNonAcParent.ContainsKey(substitution.Variable) && isNonAcParent[substitution.Variable]) isValid = isValid && typeChecker.IsSubstitutionValid(substitution); // Non-AC term case if (isAcParent.ContainsKey(substitution.Variable) && isAcParent[substitution.Variable]) { var acSubstitutionTerm = substitution.SubstitutionTerm as TrsAcTerm; if (acSubstitutionTerm == null || !variableTermNames[substitution.Variable].Contains(acSubstitutionTerm.Name)) { isValid = isValid && typeChecker.IsSubstitutionValid(substitution); } else { // In this case, test each nested argument of the AC substitution term to match the term head variable. // This is due to the ONF convertion for AC terms. It keeps type checking in line with AC semantics. foreach (var argTerm in acSubstitutionTerm.OnfArguments.Select(arg => arg.Term)) { var testSubstitution = new Substitution { Variable = substitution.Variable, SubstitutionTerm = argTerm }; isValid = isValid && typeChecker.IsSubstitutionValid(testSubstitution); } } } } return isValid; }
public TrsReductionRule(TrsTermBase head, TrsTermBase tail) : this(head, tail, null) { }
/// <summary> /// NB: this is not a general solution, only for c = b + x where + can be -, / or * and, b and x can be swapped arround. /// c is the match term. The rest is the head term. /// </summary> public List<UnificationResult> GetUnifier(TrsTermBase termHead, TrsTermBase matchTerm) { UnificationResult result = new UnificationResult(); result.Succeed = false; // Check input Substitution sRhs = new Substitution { Variable = new TrsVariable("exp_r"), SubstitutionTerm = termHead }; Substitution sLhs = new Substitution { Variable = new TrsVariable("exp_l"), SubstitutionTerm = matchTerm }; var headTerm = termHead as TrsTerm; if (!interpreter.TypeChecker.IsSubstitutionValid(sLhs) || !interpreter.TypeChecker.IsSubstitutionValid(sRhs)) { return new List<UnificationResult> { result }; } // Load problem interpreter.ClearExecutionCache(); interpreter.LoadTerms(new [] { new TrsTerm("rhs",new [] { termHead }), new TrsTerm("lhs",new [] { matchTerm }) }); // Solve while (interpreter.ExecuteRewriteStep()) { }; // Extract answer var runResults = interpreter.GetCurrentRewriteResult(); foreach (var stm in runResults.ProgramOut.Statements) { var resEq = stm as TrsTerm; if (resEq != null && resEq.Name == "eq" && resEq.Arguments.Count == 2 && resEq.Arguments[0] is TrsNumber && resEq.Arguments[1] is TrsVariable) { result.Succeed = true; result.Unifier = new List<Substitution>(); result.Unifier.Add(new Substitution() { Variable = resEq.Arguments[1] as TrsVariable, SubstitutionTerm = resEq.Arguments[0] }); } } return new List<UnificationResult> { result }; }
public override TrsTermBase CreateCopyAndReplaceSubTerm(TrsTermBase termToReplace, TrsTermBase replacementTerm) { if (termToReplace != null && this.Equals(termToReplace)) return (TrsTermBase)replacementTerm.CreateCopy(); else { return new TrsAcTerm(Name, OnfArguments.Select(rankedPair => new TrsOnfAcTermArgument { Term = (TrsTermBase)(rankedPair.Term.Equals(termToReplace) ? replacementTerm.CreateCopy() : rankedPair.Term.CreateCopy()), Cardinality = rankedPair.Cardinality })); } }
public List<UnificationResult> GetUnifier(TrsTermBase termHead, TrsTermBase matchTerm) { return GetMgu(new Equation { Lhs = termHead, Rhs = matchTerm }, matchTerm.GetVariables()); }
public override TrsTermBase CreateCopyAndReplaceSubTerm(TrsTermBase termToReplace, TrsTermBase replacementTerm) { return this; }
public TrsReductionRule(TrsTermBase head, TrsTermBase tail, AstReductionRule astSource) { Head = head; Tail = tail; AstSource = astSource; }