PLOGHELP DYNAMIC Robert Duncan, March 1988 Revised July 1993 Dynamic predicates. CONTENTS - (Use g to access required sections) 1 Introduction 2 Dynamic and Static Predicates 3 Using the Dynamic Declaration 4 Finding Out if a Predicate is Dynamic 5 Related Documentation ----------------------------------------------------------------------- 1 Introduction ----------------------------------------------------------------------- :- op(254, fx, dynamic). ?- dynamic PredicateSpec. Declares all the predicates identified by PredicateSpec to be dynamic, meaning that their definitions are likely to change during the course of the program, usually because of clauses being asserted or retracted. PredicateSpec must be a conjunction of simple specifications of the form Fn/Arity where Fn is an atom (the functor name of the predicate) and Arity an integer (its arity). For example, the directive: :- dynamic global_value/2, search_path/1. declares that both global_value/2 and search_path/1 are to be asserted or retracted. ----------------------------------------------------------------------- 2 Dynamic and Static Predicates ----------------------------------------------------------------------- The Poplog Prolog compiler maintains two different forms of procedure compiled from a predicate definition. In the first form, called the static form, all the clauses in the definition are compiled into a single procedure. In the second form, the dynamic form, a separate procedure is compiled for each clause and a special "interpreting" procedure is used to execute each of these clause procedures in turn. A given predicate can be compiled in either form, but the static version will run considerably faster than its dynamic equivalent. The reason for the dynamic form is that it supports the operations of assert and retract: individual clause procedures can be added or removed from the set of clauses associated with a predicate without disruption. In normal operation, a predicate when first defined is always compiled in the static form. If the predicate is ever then used as the argument to an assert or retract, or if extra clauses are added to the definition by consulting, it has to be recompiled in the dynamic form before the operation can be performed. This has two drawbacks. Firstly it can be costly in time, as the recompilation can be a lengthy process if the existing static definition is big; this time penalty is added to the cost of the first assert or retract done on the predicate. Secondly it is possible to introduce inconsistencies in certain circumstances: for example, if the predicate is recompiled into the dynamic form at a point where a call to the static form is still active, two inconsistent views of the predicate can be created, as any changes made to the dynamic form will not be reflected in the still-active static version. To avoid these problems, the declaration dynamic/1 should be used to specify in advance those predicates which are to be asserted or retracted. Predicates so declared are compiled from the first in the dynamic form, so side-stepping the problems caused by recompilation on the fly. The declaration also serves a documentation function, indicating to readers of a program those predicates which can be expected to change during the course of running the program. A similar declaration is now standard in many other Prolog systems. The presence of this declaration does not restrict the use of assert and retract to dynamic predicates. Static predicates will still be re-compiled automatically where necessary as this is required for compatibility with existing programs, but this practice is now discouraged. ----------------------------------------------------------------------- 3 Using the Dynamic Declaration ----------------------------------------------------------------------- The declaration dynamic/1 should be used to declare any predicate which satisfies one or more of the following conditions: o it is to be the subject of any form of assert or retract operation o the clauses defining the predicate are to be assembled from separate files compiled in consult mode o the clauses defining the predicate are all located in the same file but are not contiguous A system predicate (see PLOGHELP * SYSTEM_PREDICATE) can't be made dynamic. The effect of the dynamic/1 declaration on a predicate depends on the status of the predicate at the time the declaration is evaluated: o if the predicate is undefined, an initial dynamic definition for that predicate is automatically created with no clauses: the effect is the same as if a single dummy clause were asserted and then immediately retracted. Such a definition will fail if called. o if the predicate has an existing static definition, it will be recompiled immediately to the dynamic form. If in addition the predicate has been declared no_clauses there will be no clauses from which the definition can be recompiled, so the existing definition will be lost. (The no_clauses declaration is subsequently ignored for dynamic predicates.) o if the predicate is already dynamic, the declaration has no effect. It follows that a dynamic predicate is never undefined: predicate_info/2 will never report both dynamic and undefined for a predicate, and calling a dynamic predicate will never raise an 'UNDEFINED PREDICATE' error. This in turn means that dynamic predicates are unaffected by the current handling of undefined predicate errors set by unknown/2. Once a predicate has become dynamic, it remains so until either it is explicitly declared static again, or until it is abolished. Reconsulting the definition of a dynamic predicate just deletes any existing clauses from the database and compiles the new definition in dynamic mode. The companion declaration static/1 can be used to force a procedure back into static form. This is only useful at a point in a program where a predicate has been made dynamic because of any of the reasons given above, but is not going to change any more during the course of the program. The static declaration causes the predicate to be recompiled as a static procedure which will then run faster. Whether this extra speed will outweigh the cost of the recompilation will depend on the particular application. ----------------------------------------------------------------------- 4 Finding Out if a Predicate is Dynamic ----------------------------------------------------------------------- Use predicate_info/2 to determine whether a predicate is dynamic: if so, the list of attributes reported for the predicate will contain the atom 'dynamic'. For example: ?- predicate_info(search_path/1, Info). Info = [user_predicate, dynamic] ? See PLOGHELP * PREDICATE_INFO. ----------------------------------------------------------------------- 5 Related Documentation ----------------------------------------------------------------------- PLOGHELP * NO_CLAUSES, * SYSTEM_PREDICATE Other declaration forms. PLOGHELP * DATABASE A summary of operations available on the Prolog database. PLOGHELP * EFFICIENCY Hints on making Prolog programs more efficient. --- C.all/plog/help/dynamic --- Copyright University of Sussex 1993. All rights reserved.