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.