All Prolog procedures are classified as being either static or dynamic procedures. Static procedures can be changed only by completely redefining them using the Load Predicates (see ref-lod). Dynamic procedures can be modified by adding or deleting individual clauses using the assert and retract procedures.
If a procedure is defined by loading source code, it is static by default. If you need to be able to add, delete, or inspect the individual clauses of such a procedure, you must make the procedure dynamic.
There are two ways to make a procedure dynamic:
assert
operation on the procedure automatically makes it dynamic.
A procedure is declared dynamic by preceding its definition with a declaration of the form:
:- dynamic :Pred
where Pred must be a procedure specification of the form Name/Arity, or a sequence of such specifications, separated by commas. For example,
:- dynamic exchange_rate/3, spouse_of/2, gravitational_constant/1.
where ‘dynamic’ is a built-in prefix operator. If Pred is not of the specified form an exception is raised, and the declaration is ignored.
Note that the symbol ‘:- ’
preceding the word ‘dynamic’ is essential.
If this symbol is omitted, a permission error is raised
because it appears that you are trying to
define a
clause for the built-in predicate dynamic/1
. Although dynamic/1
is a
built-in predicate, it may only be used in declarations.
When a dynamic declaration is encountered in a file being loaded, it is considered to be a part of the redefinition of the procedures specified in its argument. Thus, if you load a file containing only
:- dynamic hello/0
the effect will be to remove any previous definition of hello/0
from
the database, and to make the procedure dynamic. You cannot make a
procedure dynamic retroactively.
If you wish to make an already-existing procedure dynamic it must
be redefined.
It is often useful to have a dynamic declaration for a procedure even if it is to be created only by assertions. This helps another person to understand your program, since it emphasizes the fact that there are no pre-existing clauses for this procedure, and it also avoids the possibility of Prolog stopping to tell you there are no clauses for this procedure if you should happen to call it before any clauses have been asserted. This is because unknown procedure catching (see Undefined Predicates) does not apply to dynamic procedures; it is presumed that a call to a dynamic procedure should simply fail if there are no clauses for it.
If a program needs to make an undefined procedure dynamic, this can be achieved
by calling clause/2
on that procedure. The call will fail because the
procedure has no clauses, but as a side-effect it will make the procedure
dynamic and thus prevent unknown procedure catching on that procedure. See
the Reference page for details of clause/2
.
Although you can simultaneously declare several procedures to be dynamic, as shown above, it is recommended that you use a separate dynamic declaration for each procedure placed immediately before the clauses for that procedure. In this way when you reload the procedure using the editor interface, you will be reminded to include its dynamic declaration.
Dynamic procedures are implemented by interpretation, even if they are
included in a file that is compiled. This means that they are
executed more slowly than if they were static, and also that they can be
printed using listing/0
. Dynamic procedures, as well as
static procedures, are indexed on their first argument; see
Indexing.