public bool RetractAll(BaseTerm t, VarStack varStack) { // remark: first-argument indexing is not affected by deleting clauses string key = t.Key; if (predefineds.Contains(key)) { IO.Error("retract of predefined predicate {0} not allowed", key); } PredicateDescr pd = this[key]; if (pd == null) { return(true); } ClauseNode c = pd.ClauseList; ClauseNode prevc = null; bool match = false; while (c != null) { BaseTerm cleanTerm = c.Term.Copy(); if (cleanTerm.IsUnifiableWith(t, varStack)) // match found -- remove this head from the chain { match = true; // to indicate that at least one head was found 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 break; } else { pd.SetClauseListHead(c.NextClause); } } else // not the first { prevc.NextClause = c.NextClause; prevc = c; } } else { prevc = c; } c = c.NextClause; } if (match) { #if arg1index pd.DestroyFirstArgIndex(); // rebuilt by ResolveIndices() #endif pd.AdjustClauseListEnd(); ResolveIndices(); } return(true); }
public bool Retract(BaseTerm t, VarStack varStack, BaseTerm where) { string key = t.Key; if (predefineds.Contains(key)) { IO.Error("retract of predefined predicate {0} not allowed", key); } PredicateDescr pd = this[key]; if (pd == null) { return(false); } InvalidateCrossRef(); ClauseNode c = pd.ClauseList; ClauseNode prevc = null; BaseTerm cleanTerm; int top; while (c != null) { cleanTerm = c.Head.Copy(); 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) } Variable s; for (int i = varStack.Count - top; i > 0; i--) // unbind all vars that got bound by the above Unification { s = (Variable)varStack.Pop(); s.Unbind(); } prevc = c; c = c.NextClause; } ResolveIndices(); return(false); }