/// <summary> /// <code> /// function UNIFY(x, y, theta) returns a substitution to make x and y identical /// inputs: x, a variable, constant, list, or compound /// y, a variable, constant, list, or compound /// theta, the substitution built up so far (optional, defaults to empty) /// </code> /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="theta"></param> /// <returns><![CDATA[a IDictionary<Variable, ITerm> representing the substitution (i.e. a set /// of variable/term pairs) or null which is used to indicate a /// failure to unify.]]></returns> public IDictionary <Variable, ITerm> Unify(IFOLNode x, IFOLNode y, IDictionary <Variable, ITerm> theta) { // if theta = failure then return failure if (theta == null) { return(null); } else if (x.Equals(y)) { // else if x = y then return theta return(theta); } else if (x is Variable) { // else if VARIABLE?(x) then return UNIVY-VAR(x, y, theta) return(this.UnifyVar((Variable)x, y, theta)); } else if (y is Variable) { // else if VARIABLE?(y) then return UNIFY-VAR(y, x, theta) return(this.UnifyVar((Variable)y, x, theta)); } else if (this.IsCompound(x) && this.IsCompound(y)) { // else if COMPOUND?(x) and COMPOUND?(y) then // return UNIFY(x.ARGS, y.ARGS, UNIFY(x.OP, y.OP, theta)) return(this.Unify((List <IFOLNode>)x.GetArgs(), (List <IFOLNode>)y.GetArgs(), this.UnifyOps(this.Op(x), this.Op(y), theta))); } else { // else return failure return(null); } }
/// <summary> /// <code> /// function UNIFY-VAR(var, x, theta) returns a substitution /// inputs: var, a variable /// x, any expression /// theta, the substitution built up so far /// </code> /// </summary> /// <param name="var"></param> /// <param name="x"></param> /// <param name="theta"></param> /// <returns></returns> private IDictionary <Variable, ITerm> UnifyVar(Variable var, IFOLNode x, IDictionary <Variable, ITerm> theta) { if (!(x is ITerm)) { return(null); } if (theta.Keys.Contains(var)) { // if {var/val} E theta then return UNIFY(val, x, theta) return(this.Unify(theta[var], x, theta)); } if (theta.Keys.Contains((Variable)x)) { // else if {x/val} E theta then return UNIFY(var, val, theta) return(this.Unify(var, theta[(Variable)x], theta)); } if (this.OccurCheck(theta, var, x)) { // else if OCCUR-CHECK?(var, x) then return failure return(null); } // else return add {var/x} to theta this.CascadeSubstitution(theta, var, (ITerm)x); return(theta); }
// Note: You can subclass and override this method in order // to re-implement the OCCUR-CHECK?() to always // return false if you want that to be the default // behavior, as is the case with Prolog. protected bool OccurCheck(IDictionary <Variable, ITerm> theta, Variable var, IFOLNode x) { if (x is Function) { var varsToCheck = _variableCollector.CollectAllVariables((Function)x); if (varsToCheck.Contains(var)) { return(true); } // Now need to check if cascading will cause occurs to happen // e.g. // Loves(SF1(v2),v2) // Loves(v3,SF0(v3)) // or // P(v1,SF0(v1),SF0(v1)) // P(v2,SF0(v2),v2 ) // or // P(v1, F(v2),F(v2),F(v2),v1, F(F(v1)),F(F(F(v1))),v2) // P(F(v3),v4, v5, v6, F(F(v5)),v4, F(v3), F(F(v5))) return(this.CascadeOccurCheck(theta, var, varsToCheck, new HashedSet <Variable>(varsToCheck))); } return(false); }
public IDictionary <Variable, ITerm> Unify(IFOLNode x, IFOLNode y) { return(unifier.Unify(x, y)); }
public IDictionary <Variable, ITerm> Unify(IFOLNode x, IFOLNode y) { return(this.Unify(x, y, new Dictionary <Variable, ITerm>())); }
private bool IsCompound(IFOLNode x) { return(x.IsCompound()); }
private string Op(IFOLNode x) { return(x.GetSymbolicName()); }