public bool Retract(Term t, VarStack varStack, Term where) { string key = t.KbKey; if (predefineds.Contains(key)) PrologIO.Error("retract of predefined predicate {0} not allowed", key); PredicateDescr pd = this[key]; if (pd == null) return false; #if persistent if (pd is PersistentPredDescr) { ((PersistentPredDescr)pd).Retract (t, varStack, where); return true; } #endif ClauseNode c = pd.GetClauseList(null, null); ClauseNode prevc = null; Term cleanTerm; int top; while (c != null) { cleanTerm = c.Term.CleanCopy(); top = varStack.Count; if (cleanTerm.Unify(t, varStack)) // match found -- remove this term from the chain { if (prevc == null) // remove first clause { if (c.NextClause == null) // we are about to remove the last remaining clause for this predicate { predTable.Remove(key); // ... so remove its PredicateDescr as well #if arg1index pd.CreateFirstArgIndex (); // re-create #endif ResolveIndices(); } else pd.SetClauseListHead(c.NextClause); } else // not the first { prevc.NextClause = c.NextClause; prevc = c; pd.AdjustClauseListEnd(); #if arg1index pd.CreateFirstArgIndex (); // re-create #endif } return true; // possible bindings must stay intact (e.g. if p(a) then retract(p(X)) yields X=a) } Term s; for (int i = varStack.Count - top; i > 0; i--) // unbind all vars that got bound by the above Unification { s = (Term)varStack.Pop(); s.Unbind(); } prevc = c; c = c.NextClause; } ResolveIndices(); return false; }
public bool Unifiable(Term t, VarStack varStack) // as Unify, but does not actually bind { int top = varStack.Count; bool result = Unify(t, varStack); for (int i = varStack.Count - top; i > 0; i--) // unbind all varNoSet that got bound by Unify { Term s = (Term)varStack.Pop(); s.Unbind(); } return result; }