add_advice/3 development

Synopsis

add_advice(+Goal,+Port,+Action)

Associate an action with entry to a port of a procedure.

Arguments


Goal callable [MOD]
a term to be unified against a calling goal.
Port one of [call,exit,done,redo,fail]
an atom indicating the port at which to check advice.
Action callable [MOD]
a goal to be called when advice is checked at the given port.

Description

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 predicates.

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.

Exceptions


instantiation_error
if an argument is not sufficiently instantiated.
type_error
if Goal or Action is not a callable, or a module prefix is not an atom, or Port is not an atom.
domain_error
if Port is not a valid port.
permission_error
if a specified procedure is built-in.

Tips

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.

See Also

remove_advice/3, current_advice/3, check_advice/[0,1], nocheck_advice/[0,1] dbg-adv