4.12.1 Introduction

The family of assertion and retraction predicates described below enables you to modify a Prolog program by adding or deleting clauses while it is running. These predicates should not be overused. Often people who are experienced with other programming languages have a tendency to think in terms of global data structures, as opposed to data structures that are passed as procedure arguments, and hence they make too much use of assertion and retraction. This leads to less readable and less efficient programs.

An interesting question in Prolog is what happens if a procedure modifies itself, by asserting or retracting a clause, and then fails. On backtracking, does the current execution of the procedure use new clauses that are added to the bottom of the procedure?

Historical note: In some non-ISO-conforming implementations of Prolog, changes to the Prolog database become globally visible upon the success of the built-in predicate modifying the database. An unsettling consequence is that the definition of a procedure can change while it is being run. This can lead to code that is difficult to understand. Furthermore, the memory performance of the interpreter implementing these semantics is poor. Worse yet, the semantics rendered ineffective the added determinacy detection available through indexing.

SICStus Prolog implements the “logical” view in updating dynamic predicates, conforming to the ISO standard. This means that the definition of a dynamic procedure that is visible to a call is effectively frozen when the call is made. A procedure always contains, as far as a call to it is concerned, exactly the clauses it contained when the call was made.

A useful way to think of this is to consider that a call to a dynamic procedure makes a virtual copy of the procedure and then runs the copy rather than the original procedure. Any changes to the procedure made by the call are immediately reflected in the Prolog database, but not in the copy of the procedure being run. Thus, changes to a running procedure will not be visible on backtracking. A subsequent call, however, makes and runs a copy of the modified Prolog database. Any changes to the procedure that were made by an earlier call will now be visible to the new call.

In addition to being more intuitive and easy to understand, the new semantics allow interpreted code to execute with the same determinacy detection (and excellent memory performance) as static compiled code (see Indexing for more information on determinacy detection).

Send feedback on this subject.