Associate an action with entry to a port of a procedure.
add_advice/3 associates an advice action (a goal to be called)
with a port of the standard Prolog debugger model (see dbg-bas-pbx). Variable bindings made when Goal matches the incoming
call carry across to the advice action, so incoming arguments can be
verified or processed by advice checking. Any number of advice
actions can be associated with a given Goal, Port, or
Goal-Port combination. Putting advice on a procedure
does not automatically turn on checking of advice, so advice can be
built into a program and checked only when necessary. At each port,
advice is checked before interaction with the Prolog debugger, so the
advice action can be used to control the debugger. It is not
currently possible to associate advice with Prolog system built-in
Advice added using a call to
add_advice/3 will be
checked after all preexisting advice for that predicate and port.
This predicate is not supported in runtime systems.
Using advice can streamline debugging of deep recursions and other situations where a given call is made correctly many times but eventually goes amiss. Use of the Prolog debugger's spypoints is inconvenient because of the many calls before the error. If, for instance, it is known that a certain bad datum is present in the particular call producing the error, it is possible to use advice to set a spypoint only when that datum is seen:
:- add_advice(recurse(X,Y), call, (bad_data(X), spy recurse/2)).
When advice checking is enabled, this piece of advice will take effect
only if the first argument passed to
recurse/2 is bad. When that
is so, a spypoint will be placed on
recurse/2 and execution will
continue at the call port of
recurse/2. Since advice is checked
before debugger interaction at the port, the debugger will immediately
stop. There is no need to interact with the debugger for all the calls
that have valid data.
Advice can also provide a simple and flexible profiling tool by associating a counter with various ports of each "interesting" predicate. The advice associated with each port and predicate might map the name, arity, module and port to a counter value held in a dynamic table. When advice checking is on and an advised predicate port is reached, the advice action simply increments the counter. The counter table can then be inspected to determine the number of times each predicate-port combination was reached.
Advice can also be used to associate "pre-conditions" and "post-conditions" to predicates. "pre-conditions" can be associated with the "call" port of a predicate and "post-conditions" can be associated with the "done" or "exit" port of a predicate. Checking for "pre" and "post" conditions will be done only when checking advice is turned on.