4.12.7.1 Example: assertz

Consider the procedure foo/0 defined by

:- dynamic foo/0.
foo :- assertz(foo), fail.

Each call to foo/0 asserts a new last clause for foo/0. After the Nth call to foo/0 there will be N+1 clauses for foo/0. When foo/0 is first called, a virtual copy of the procedure is made, effectively freezing the definition of foo/0 for that call. At the time of the call, foo/0 has exactly one clause. Thus, when fail/0 forces backtracking, the call to foo/0 simply fails: it finds no alternatives. For example,

| ?- compile(user).
| :- dynamic foo/0.
| foo :- assertz(foo), fail.
| ^D
% user compiled in module user, 0.100 sec 2.56 bytes

yes
| ?- foo.  % The asserted clause is not found

no
| ?- foo.  % A later call does find it, however

yes
| ?-

Even though the virtual copy of foo/0 being run by the first call is not changed by the assertion, the Prolog database is. Thus, when a second call to foo/0 is made, the virtual copy for that call contains two clauses. The first clause fails, but on backtracking the second clause is found and the call succeeds.


Send feedback on this subject.