Modification of the Program

The predicates defined in this section allow modification of the program as it is actually running. Clauses can be added to the program (asserted) or removed from the program (retracted). At the lowest level, the system supports the asserting of clauses with upto one literal in the body. It does this by allocating a buffer and compiling code for the clause into that buffer. Such a buffer is called a ``clause reference'' (clref). The clref is then added to a chain of clrefs. The chain of clrefs has a header, which is a small buffer called a ``predicate reference'' (prref), which contains pointers to the beginning and end of its chain of clrefs. Clause references are quite similar to ``database references'' of C-Prolog, and can be called.

When clauses are added to the program through assert, an index is normally created on the principal functor of the first argument in the head of the clause. The argument on which the index is being created may be changed via the index/3 directive. In particular, if no index is desired on a predicate, this should be specified using the index/3 directive with the argument number set to zero, e.g. if no index is desired on a predicate foo/3, then the directive

:- index(foo, 3, 0).
should be specified.

The predicates that can be used to modify the program are the following:

assert(C)
assert/1 (L) The current instance of C is interpreted as a clause and is added to the program (with new private variables replacing any uninstantiated variables), at the end of the list of clauses for that predicate. C must be instantiated to a non-variable.

assert(C, Ref)
assert/2 (L) As for assert/1, but also unifies Ref with the clause reference of the clause asserted.

asserti(C,N)
asserti/2 (L) The current instance of C, interpreted as a clause, is asserted to the program with an index on its N$\scriptstyle \em th$ argument. If N is zero, no index is created.

asserta(C)
asserta/1 (L) Similar to assert(C), except that the new clause becomes the first clause of the procedure concerned.

asserta(C, Ref)
asserta/2 (L) Similar to asserta(C), but also unifies Ref with the clause reference of the clause asserted.

assertz(C)
assertz/1 (L) Similar to assert(C), except that the new clause becomes the last clause of the procedure concerned.

assertz(C, Ref)
assertz/2 (L) Similar to assertz(C), but also unifies Ref with the clause reference of the clause asserted.

assert_union(P, Q)
assert_union/2 (L) The clauses for Q are added to the clauses for P. For example, the call
| ?- assert_union(p(X,Y),q(X,Y)).
has the effect of adding the rule
p(X,Y) :- q(X,Y).
as the last rule defining p/2. If P is not defined, it results in the call to Q being the only clause for P.

The variables in the arguments to assert_union/2 are not significant, e.g. the above would have been equivalent to

| ?- assert_union(p(Y,X),q(X,Y)).
or
| ?- assert_union(p(_,_),q(_,_)).
However, the arities of the two predicates involved must match, e.g. even though the goal
| ?- assert_union(p(X,Y), r(X,Y,Z)).
will succeed, the predicate p/2 will not in any way depend on the clauses for r/3.

assert(Clause, AZ, Index,Clref)
assert/4 (L) Asserts a clause to a predicate. Clause is the clause to assert. AZ is 0 for insertion as the first clause, 1 for insertion as the last clause. Index is the number of the argument on which to index (0 for no indexing). Clref is returned as the clause reference of the fact newly asserted. If the main functor symbol of Clause has been declared (by $assertf_alloc_t/2, see below) to have its clauses on the heap, the clref will be allocated there. If the predicate symbol of Clause is undefined, it will be initialized and Clause added. If the predicate symbol has compiled clauses, it is first converted to be dynamic (see symtype/2, Section [*]) by adding a special clref that calls the compiled clauses. Fact, AZ and Index are input arguments, and should be instantiated at the time of call; Clref is an output argument, and should be uninstantiated at the time of call.

clause(P,Q)
clause/2 (L) Pmust be bound to a non-variable term, and the program is searched for a clause Cl whose head matches P. The head and body of the clause Cl is unified with P and Q, respectively. If Cl is a unit clause, Q will be unified with `true'. Only interpreted clauses, i.e. those created through assert, can be accessed via clause/2.

clause(Head, Body, Ref)
clause/3 (L) Similar to clause(Head,Body) but also unifies Ref with the database reference of the clause concerned. clause/3 can be executed in one of two modes: either Head must be instantiated to a non-variable term at the time of the call, or Ref must be instantiated to a database reference. As in the case of clause/2, only interpreted clauses, i.e. those created through assert, can be accessed via clause/3.

retract(Clause)
retract/1 (L) The first clause in the program that unifies with Clause is deleted from the program. This predicate may be used in a non-deterministic fashion, i.e. it will successively backtrack to retract clauses whose heads match Head. Head must be initially instantiated to a non-variable. In the current implementation, retract works only for asserted (e.g. consulted) clauses.

abolish(P)
abolish/1 (L) Completely remove all clauses for the procedure with head P (which should be a term). For example, the goal
| ?- abolish( p(_, _, _) ).
removes all clauses for the predicate p/3.

abolish(P, N)
abolish/2 (L) Completely remove all clauses for the predicate P (which should be an atom) with arity N (which should be an integer).