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.