private static Implication RemoveNotDistinctLiteral(Implication rule, Negation notDistinctLiteral) { //Figure out the substitution we want... //If we have two constantsin Either Remove one or //maybe get rid of the ___? //One is a variablein Replace the variable with the other thing //throughout the rule var distinct = (Fact)notDistinctLiteral.Negated; Term arg1 = distinct.GetTerm(0); Term arg2 = distinct.GetTerm(1); if (arg1 == arg2) { //Just Remove that literal var newBody = new List<Expression>(); newBody.AddRange(rule.Antecedents.Conjuncts); newBody.Remove(notDistinctLiteral); return new Implication(rule.Consequent, newBody.ToArray()); } var p1 = arg1 as TermVariable; if (p1 != null) { //What we return will still have the not-distinct literal, //but it will get replaced in the next pass. //(Even if we have two variables, they will be equal next time through.) var sub = new Substitution(); sub.AddMapping(p1, arg2); return (Implication)rule.ApplySubstitution(sub); } var variable = arg2 as TermVariable; if (variable != null) { var sub = new Substitution(); sub.AddMapping(variable, arg1); return (Implication)rule.ApplySubstitution(sub); } if (arg1 is TermObject || arg2 is TermObject) { //We have two non-equal constants, or a constant and a function. //The rule should have no effect. return null; } //We have two functions. Complicated! (Have to replace them with unified version.) //We pass on this case for now. //TODO: Implement correctly. throw new Exception("We can't currently handle (not (distinct <function> <function>))."); }
public override bool Mgu(Term t, Substitution subsSoFar) { if (t is TermObject) { Term replacement = subsSoFar.GetMapping(this); if (replacement != null) { TermVariable termVariable = replacement as TermVariable; if (termVariable != null) { subsSoFar.AddMapping(this, t); subsSoFar.AddMapping(termVariable, t); return true; } return replacement.Equals(t); } // There was no replacement: // Add a mapping for the variable to this term-object subsSoFar.AddMapping(this, t); return true; } var variable = t as TermVariable; if (variable != null) { TermVariable it = variable; Term myReplacement = subsSoFar.GetMapping(this); Term itsReplacement = subsSoFar.GetMapping(it); if (itsReplacement == null) { // just map 'it' to me (or my replacement) if (myReplacement == null) { if (!Equals(it)) subsSoFar.AddMapping(it, this); } else { if (!(myReplacement is TermVariable) || !myReplacement.Equals(it)) subsSoFar.AddMapping(it, myReplacement); } return true; } // At this point, 'it' has a replacement. if (myReplacement == null) { // I don't have a replacement, so map me to it, or to its replacement if (!(itsReplacement is TermVariable) || !itsReplacement.Equals(this)) subsSoFar.AddMapping(this, itsReplacement); return true; } // At this point, both term variables have replacements. // So make sure that they are the same! return myReplacement.Equals(itsReplacement); } var func = t as TermFunction; if (func != null) { Term myReplacement = subsSoFar.GetMapping(this); // Case 1: I have a replacement if (myReplacement != null) // See if my replacement can be unified with the function return myReplacement.Mgu(func, subsSoFar); // Case 2: I have no replacement TermFunction itsReplacement = subsSoFar.GetMapping(func); if (itsReplacement.HasVariable(this)) return false; // just set my replacement to the function subsSoFar.AddMapping(this, itsReplacement); return true; } throw new Exception("TermVariable.mgu: Don't know how to handle term of type " + t.GetType().Name); }