Dynamic predicates
Author(s): Daniel Cabeza, The CLIP Group.The package dynamic_clauses provides the assert/retract family of predicates to manipulate dynamic predicates.
The defined predicates allow modification of the program as it is actually running. Clauses can be added to the program (asserted) or removed from the program (retracted), as well as inspected. Note that in Ciao only the dynamic predicates of the current module (or accessible dynamic multifile predicates) can be accessed and modified. This limits the bad impact to global analysis of this dynamic modification of the program. Thus, if dynamic predicates are exported, to be able to inspect or modify them externally some accessing predicates need to be implemented and exported alongside.
For the inspecting/manipulating predicates, the argument which corresponds to the clause head must be instantiated to an atom or a compound term. The argument corresponding to the clause must be instantiated either to a term Head :- Body or, if the body part is empty, to Head. An empty body part is represented as true.
Note that using this library is very detrimental to global analysis, and that for most uses the predicates listed in Fast/concurrent update of facts suffice.
Usage and interface
- Library usage:
To be able to handle dynamic predicates in a module, load the library package dynamic_clauses, either by putting it in the package list of the module or using the use_package/1 directive. Do not load directly the dynamic_rt module. - Exports:
- Predicates:
asserta/1, asserta/2, assertz/1, assertz/2, assert/1, assert/2, retract/1, retractall/1, abolish/1, clause/2, mfclause/2, current_predicate/1, current_predicate/2, dynamic/1, data/1, wellformed_body/3. - Multifiles:
do_on_abolish/1.
- Predicates:
- Imports:
- System library modules:
prolog_sys, iso_misc. - Packages:
prelude, nonpure, assertions, isomodes, regtypes.
- System library modules:
Documentation on exports
Usage:ISOasserta(Clause)
The current instance of Clause is interpreted as a clause and is added to the current program. The predicate concerned must be dynamic. The new clause becomes the first clause for the predicate concerned. Any uninstantiated variables in Clause will be replaced by new private variables.
- The following properties should hold at call time:
(term_typing:nonvar/1)Clause is currently a term which is not a free variable.
(dynamic_rt:clause/1)Clause is a well-formed clause - The following properties should hold globally:
(basic_props:native/1)This predicate is understood natively by CiaoPP.
Usage:asserta(Clause,Ref)
Like asserta/1. Ref is a unique identifier of the asserted clause.
- The following properties should hold at call time:
(term_typing:nonvar/1)Clause is currently a term which is not a free variable.
(term_typing:var/1)Ref is a free variable.
(dynamic_rt:clause/1)Clause is a well-formed clause - The following properties should hold globally:
(basic_props:native/1)This predicate is understood natively by CiaoPP.
Usage:ISOassertz(Clause)
Like asserta/1, except that the new clause becomes the last clause for the predicate concerned.
- The following properties should hold at call time:
(term_typing:nonvar/1)Clause is currently a term which is not a free variable.
(dynamic_rt:clause/1)Clause is a well-formed clause - The following properties should hold globally:
(basic_props:native/1)This predicate is understood natively by CiaoPP.
Usage:assertz(Clause,Ref)
Like assertz/1. Ref is a unique identifier of the asserted clause.
- The following properties should hold at call time:
(term_typing:nonvar/1)Clause is currently a term which is not a free variable.
(term_typing:var/1)Ref is a free variable.
(dynamic_rt:clause/1)Clause is a well-formed clause - The following properties should hold globally:
(basic_props:native/1)This predicate is understood natively by CiaoPP.
Usage:assert(Clause)
Identical to assertz/1. Included for compatibility.
- The following properties should hold at call time:
(term_typing:nonvar/1)Clause is currently a term which is not a free variable.
(dynamic_rt:clause/1)Clause is a well-formed clause - The following properties should hold globally:
(basic_props:native/1)This predicate is understood natively by CiaoPP.
Usage:assert(Clause,Ref)
Identical to assertz/2. Included for compatibility.
- The following properties should hold at call time:
(term_typing:nonvar/1)Clause is currently a term which is not a free variable.
(term_typing:var/1)Ref is a free variable.
(dynamic_rt:clause/1)Clause is a well-formed clause - The following properties should hold globally:
(basic_props:native/1)This predicate is understood natively by CiaoPP.
Usage:ISOretract(Clause)
The first clause in the program that matches Clause is erased. The predicate concerned must be dynamic.
The predicate retract/1 may be used in a non-determinate fashion, i.e., it will successively retract clauses matching the argument through backtracking. If reactivated by backtracking, invocations of the predicate whose clauses are being retracted will proceed unaffected by the retracts. This is also true for invocations of clause for the same predicate. The space occupied by a retracted clause will be recovered when instances of the clause are no longer in use.
- The following properties should hold at call time:
(term_typing:nonvar/1)Clause is currently a term which is not a free variable.
(dynamic_rt:clause/1)Clause is a well-formed clause - The following properties should hold globally:
(basic_props:native/1)This predicate is understood natively by CiaoPP.
Usage:retractall(Head)
Erase all clauses whose head matches Head, where Head must be instantiated to an atom or a compound term. The predicate concerned must be dynamic. The predicate definition is retained.
- The following properties should hold at call time:
(term_typing:nonvar/1)Head is currently a term which is not a free variable.
(basic_props:callable/1)Head is a term which represents a goal, i.e., an atom or a structure. - The following properties should hold globally:
(basic_props:native/1)This predicate is understood natively by CiaoPP.
Usage:ISOabolish(Spec)
Erase all clauses of the predicate specified by the predicate spec Spec. The predicate definition itself is also erased (the predicate is deemed undefined after execution of the abolish). The predicates concerned must all be user defined.
- The following properties should hold at call time:
(term_typing:nonvar/1)Spec is currently a term which is not a free variable.
(basic_props:predname/1)Spec is a Name/Arity structure denoting a predicate name:predname(P/A) :- atm(P), nnegint(A).
- The following properties should hold globally:
(basic_props:native/1)This predicate is understood natively by CiaoPP.
Usage:ISOclause(Head,Body)
The clause 'Head :- Body' exists in the current module. The predicate concerned must be dynamic.
- The following properties should hold at call time:
(term_typing:nonvar/1)Head is currently a term which is not a free variable.
(basic_props:callable/1)Head is a term which represents a goal, i.e., an atom or a structure. - The following properties should hold upon exit:
(dynamic_rt:body/1)Body is a clause body - The following properties should hold globally:
(basic_props:native/1)This predicate is understood natively by CiaoPP.
Usage:ISOmfclause(Head,Body)
There is a clause 'Head :- Body' of a dynamic multifile predicate accessible from this module.
- The following properties should hold at call time:
(term_typing:nonvar/1)Head is currently a term which is not a free variable.
(basic_props:callable/1)Head is a term which represents a goal, i.e., an atom or a structure. - The following properties should hold upon exit:
(dynamic_rt:body/1)Body is a clause body - The following properties should hold globally:
(basic_props:native/1)This predicate is understood natively by CiaoPP.
Usage:ISOcurrent_predicate(Spec)
A predicate in the current module is named Spec.
- The following properties should hold upon exit:
(basic_props:predname/1)Spec is a Name/Arity structure denoting a predicate name:predname(P/A) :- atm(P), nnegint(A).
- The following properties should hold globally:
(basic_props:native/1)This predicate is understood natively by CiaoPP.
Usage:current_predicate(Spec,Module)
A predicate in Module is named Spec. Module never is an engine module.
- The following properties should hold upon exit:
(basic_props:predname/1)Spec is a Name/Arity structure denoting a predicate name:predname(P/A) :- atm(P), nnegint(A).
(system_info:internal_module_id/1)Module is an internal module identifier - The following properties should hold globally:
(basic_props:native/1)This predicate is understood natively by CiaoPP.
Spec is of the form F/A. The predicate named F with arity A is made dynamic in the current module at runtime (useful for predicate names generated on-the-fly). If the predicate functor name F is uninstatiated, a new, unique, predicate name is generated at runtime.
Usage:dynamic Spec
- The following properties should hold at call time:
(term_typing:nonvar/1)Spec is currently a term which is not a free variable.
(basic_props:predname/1)Spec is a Name/Arity structure denoting a predicate name:predname(P/A) :- atm(P), nnegint(A).
Spec is of the form F/A. The predicate named F with arity A is made data in the current module at runtime (useful for predicate names generated on-the-fly). If the predicate functor name F is uninstatiated, a new, unique, predicate name is generated at runtime.
Usage:data Spec
- The following properties should hold at call time:
(term_typing:nonvar/1)Spec is currently a term which is not a free variable.
(basic_props:predname/1)Spec is a Name/Arity structure denoting a predicate name:predname(P/A) :- atm(P), nnegint(A).
BodyIn is a well-formed clause body. BodyOut is its counterpart with no single-variable meta-goals (i.e., with call(X) for X). Env denotes if global cuts are admissible in BodyIn (+ if they are, - if they are not).
Documentation on multifiles
A hook predicate which will be called when the definition of the predicate of Head is abolished.
(Trust) Usage:do_on_abolish(G)
- The following properties should hold at call time:
(basic_props:callable/1)G is a term which represents a goal, i.e., an atom or a structure.
Known bugs and planned improvements
- Package dynamic_clauses cannot be loaded into the shell.