retract/1

Synopsis

retract(+*Clause)

Removes the first occurrence of dynamic clause Clause from module M.

Arguments


Clause callable [MOD]
A valid Prolog clause.

Description

retract/1 erases the first clause in the database that matches Clause. Clause is retracted in module M if specified. Otherwise, Clause is retracted in calling module.

retract/1 is nondeterminate. If control backtracks into the call to retract/1, successive clauses matching Clause are erased. If and when no clauses match, the call to retract/1 fails.

Clause must be of one of the forms:

where Head is of type callable and the principal functor of Head is the name of a dynamic procedure. If specified, Module must be an atom.

retract(Head) means retract the unit-clause Head. The exact same effect can be achieved by retract((Head :- true)).

Body may be uninstantiated, in which case it will match any body. In the case of a unit-clause it will be bound to true. Thus, for example,

     | ?- retract((foo(X) :- Body)), fail.
     

is guaranteed to retract all the clauses for foo/1, including any unit-clauses, providing of course that foo/1 is dynamic.

Since retract/1 is nondeterminate it is important if you only want to retract a single clause to use a cut to eliminate the alternatives generated. See ref-mdb-rcd-efu for more information on the use of cuts with retract/1.

retract/1 searches for the clause to remove in the same way that clause/2 does. (And, like clause/2, it uses first argument indexing to speed up this search when possible.) Therefore it is redundant to call clause/2 immediately before calling retract/1 on the clause it returns. That is, the call to clause/2 in the following program fragment can be removed without changing its effect.

     ... clause(H,B), retract((H:-B)), ...
     

The space occupied by a clause that is retracted is reclaimed. The reclamation does not necessarily happen immediately, but is not delayed until backtracking past the call to retract/1, as in some implementations.

WARNING: retract/1 is a nondeterminate procedure. Thus, we can use

     | ?- retract((foo(X) :- Body)), fail.
     

to retract all clauses for foo/1. However, when retract/1 is used determinately; for example, to retract a single clause, it is crucial that you cut away unintended chice points to avoid "freezing" the retracted Clause, disabling tail recursion optimization, or runaway retraction on the unexpected failure of a subsequent goal. See ref-mdb-rcd-efu for further discussion.

Exceptions

Same as assert/1.

See Also:

abolish/[1,2], assert/1, dynamic/1, erase/1, retractall/1.