Did you know ... | Search Documentation: |
Intercepting the Tracer |
Port denotes the reason to activate the tracer (`port’in the 4/5-port, but with some additions):
redo
port signals resuming a predicate to generate
alternative solutions. If PC is 0 (zero), clause indexing has
found another clause that will be tried next. Otherwise, PC
is the program counter in the current clause where execution continues.
This implies we are dealing with an in-clause choice point left by,
e.g., ;/2. Note that
non-determinism in foreign predicates are also handled using an
in-clause choice point.retry
. Except is the pending exception term.cut_call(PC)
for more
information.Frame is a reference to the current local stack frame, which can be examined using prolog_frame_attribute/3. Choice is a reference to the last choice point and can be examined using prolog_choice_attribute/3. Action must be unified with a term that specifies how execution must continue. The following actions are defined:
Together with the predicates described in section 4.39 and the other predicates of this chapter, this predicate enables the Prolog user to define a complete new debugger in Prolog. Besides this, it enables the Prolog programmer to monitor the execution of a program. The example below records all goals trapped by the tracer in the database.
prolog_trace_interception(Port, Frame, _PC, continue) :- prolog_frame_attribute(Frame, goal, Goal), prolog_frame_attribute(Frame, level, Level), recordz(trace, trace(Port, Level, Goal)).
To trace the execution of‘go’this way the following query should be given:
?- trace, go, notrace.
As of version 9.1.12, unification against variables in the passed data as well as changes to backtrackable global variables persist. The hook should not unify variables in its arguments. One solution to this is to backtrace over the body of the interceptor. Note that the Action needs to be preserved.
user:prolog_trace_interception(Port, Frame, Choice, Action) :- State = state(0), ( my_trace_interception(Port, Frame, Choice, Action), nb_setarg(1, State, Action), fail ; arg(1, State, Action) ).
redo
trace is called for the child, where the skip
level is set to redo_in_skip
. Next, the skip level is set
to skip level of the skipped frame.very_deep
(meaning don't skip) or the atom skip_in_redo
(see prolog_skip_frame/1).
The‘skip level’is a setting of each Prolog thread that
disables the debugger on all recursion levels deeper than the level of
the variable. See also prolog_skip_frame/1.