Prolog programs can modify themselves while running: clauses can be added and removed at runtime. Normally this is not allowed, and clauses which will be changed must be marked specifically, in order for the system to compile them in a special way. This very powerful feature must be used very carefully, as reasoning about a program which changes while it is running is not easy at all. Sometimes this is quite useful, but most of the times this is a mistake: the code becomes hard to maintain, and, since (a part of) the compiler has to be invoked, it is quite slow. Furthermore, the standard semantics for program modification states that no modification to a predicate becomes active until the calls to that predicate have finitely failed.
Program modifications can be justified, however, when used as a global switch: for example, asserting a fact which drives some options in a program, and which is consulted scarcely at some points in the program. There is also a logical justification (which might be used sometimes) to self-modification of code: when the clauses asserted are logical consequences from the program (this is called memoization), or when the clauses retracted are redundant.
The two main predicates (but there are more) for assertion and retraction are called assert/1 and retract/1. Their use is exemplified in the code below:
:- dynamic related/2. relate_terms(X, Y):- assert(related(X, Y)). unrelate_terms(X, Y):- retract(related(X, Y)).
The first clause is called with two terms as arguments, and it simply adds the fact related(X, Y), where X and Y are the terms. The second clause just retrieves the fact:
?- related(X, Y). no ?- relate_terms(a, b). yes ?- related(X, Y). X = a, Y = b ? yes ?- unrelate_terms(a, b). yes ?- related(X, Y). no ?- relate_terms(a, b). yes ?- relate_terms(c, f). yes ?- related(X, Y). X = a, Y = b ? ; X = c, Y = f ? ; no
Rules can also be asserted and retracted; in this case, for syntactical reasons, they must be surrounded with parentheses, e.g., assert((a:- b, c)). Asserted code is usually slower than normal, compiled code.