If it is intended that a procedure be altered through the use of assert/1 and retract/1, the system should be informed that the procedure will be dynamic, since these predicates are designed to work on dynamic procedures. If assert/1 is applied on a non-existing procedure, an error is raised, however the default error handler for this error only declares the procedure as dynamic and then makes the assertion.
A procedure is by default static unless it has been specifically declared as dynamic. Clauses of static procedures must always be consecutive, they may not be separated in one or more source files or by the user from the top level. If the static procedure clauses are not consecutive, each of the consecutive parts is taken as a separate procedure which redefines the previous occurrence of that procedure, and so only the last one will remain. However, whenever the compiler encounters nonconsecutive clauses of a static procedure in one file, it raises an exception whose default handler prints a warning but it continues to compile the rest of the file.
If a procedure is to be dynamic the ECLiPSe system should be given a specific dynamic declaration A dynamic declaration takes the form
The predicate is_dynamic/1 may be used to check if a procedure is dynamic::- dynamic SpecList.
When the goalis_dynamic(Name/Arity).
is executed and Somefile contains clauses for procedures that have already been defined in the Prolog database, those procedures are treated in one of two ways: If such a procedure is dynamic, its clauses compiled from Somefile are added to the database (just as would happen if they were asserted), and the existing clauses are not affected. For example, if the following clauses have already been compiled:compile(Somefile)
and the file Somefile contains the following Prolog code::- dynamic city/1. city(london). city(paris).
then compiling Somefile will cause adding the clauses for city/1 to those already compiled, as city/1 has been declared dynamic. Thus the query city(X) will give:city(munich). city(tokyo).
[eclipse 5]: city(X). X = london More? (;) X = paris More? (;) X = munich More? (;) X = tokyo yes.
If, however, the compiled procedure is static, the new clauses in Somefile replace the old procedure. Thus, if the following clauses have been compiled:
and the file Somefile contains the following Prolog code:city(london). city(paris).
when Somefile is compiled, then the procedure city/1 is redefined. Thus the query city(X) will give:city(munich). city(tokyo).
[eclipse 5]: city(X). X = munich More? (;) X = tokyo yes.
When the dynamic/1 declaration is used on a procedure that is already dynamic, which may happen for instance by recompiling a file with this declaration inside, the system raises the error 64, 'procedure already dynamic'. The default handler for this error, however, will only erase all existing clauses for the specified procedure, so that when such a file is recompiled several times during its debugging, the system behaves as expected, the existing clauses are always replaced. The handler for this error can of course be changed if required. If it is set to true/0, for instance, the dynamic/1 declaration is be just silently accepted without erasing any clauses and without printing an error message.