2.10.2 Trace Mode Example
The trace/0 predicate turns on "trace mode", which, by default, produces a trace and pauses at every port of every predicate to allow inspection of the state of the program. This is normally done from the Prolog console window, but for embedded Prolog systems or when Prolog runs as a daemon it can also be done by getting a prompt via the libssh package.
Note: If the native graphics plugin (XPCE) is available, the commands gtrace/0 and gspy/1 activate the graphical debugger while tdebug/0 and tspy/1 allow debugging of arbitrary threads.
Each goal is printed using the Prolog predicate write_term/2.
The style is defined by the Prolog flag debugger_write_options
and can be modified using this flag or using the w
, p
and d
commands of the tracer (section
2.10.4.3).
Here's an example debugging session that shows the basic flow. The
unify
port is off by default since it doesn't add a lot of
information in most cases for the command line debugger.
is_a(rock1, rock). is_a(rock2, rock). color(rock1, red). noun(X, Type) :- is_a(X, Type). adjective(X, color, Value) :- color(X, Value).
?- trace. true. [trace] ?- noun(X, rock), adjective(X, color, red). Call: (11) noun(_9774, rock) ? creep
The trace/0
predicate turned on trace mode, which is now indicated at every prompt
by [trace] ?-
. The initial query provided by the user was
noun(X, rock), adjective(X, color, red)
which is asking to
find a "red rock". Finally: the first port triggered was a Call
to the first predicate in the initial query, indicating the engine is
about to look for the first rule that matches noun(_9774, rock)
.
Pressing spacebar
, c
, or enter
caused the tracer to print creep
followed by the next
trace. There are many additional commands available that are described
later in the overview.
is_a(rock1, rock). is_a(rock2, rock). color(rock1, red). noun(X, Type) :- is_a(X, Type). adjective(X, color, Value) :- color(X, Value).
[trace] ?- noun(X, rock), adjective(X, color, red). ... Call: (12) is_a(_9774, rock) ? creep Exit: (12) is_a(rock1, rock) ? creep Exit: (11) noun(rock1, rock) ? creep ...
Next, the first clause of noun/2 gets a call
trace since
the engine is trying to find the next rule that matches is_a(_9774, rock)
.
Since there is a fact that can unify: is_a(rock1, rock)
,
the trace shows exit
(i.e. succeeded) along with that
value. Since that was the final predicate in the body of noun/2 , noun/2
also gets an
exit
trace that shows the unified value of its head:
noun(rock1, rock)
.
is_a(rock1, rock). is_a(rock2, rock). color(rock1, red). noun(X, Type) :- is_a(X, Type). adjective(X, color, Value) :- color(X, Value).
[trace] ?- noun(X, rock), adjective(X, color, red). ... Call: (11) adjective(rock1, color, red) ? creep Call: (12) color(rock1, red) ? creep Exit: (12) color(rock1, red) ? creep Exit: (11) adjective(rock1, color, red) ? creep X = rock1 ; ...
Prolog then moved to the next predicate in the initial query:
adjective/3 and solved it in a similar way. Since that was the last
predicate in the query, an answer was returned. Pressing ;
requested the next answer and began Prolog backtracking.
is_a(rock1, rock). is_a(rock2, rock). color(rock1, red). noun(X, Type) :- is_a(X, Type). adjective(X, color, Value) :- color(X, Value).
[trace] ?- noun(X, rock), adjective(X, color, red). ... Redo: (12) is_a(_9774, rock) ? creep Exit: (12) is_a(rock2, rock) ? creep Exit: (11) noun(rock2, rock) ? creep Call: (11) adjective(rock2, color, red) ? creep Call: (12) color(rock2, red) ? creep Fail: (12) color(rock2, red) ? creep Fail: (11) adjective(rock2, color, red) ? creep false.
The only choice point to redo
(i.e. backtrack over) was
the is_a/2 clause of noun/2 since there was one potential match left to
attempt to unify: is_a(rock2, rock)
. This succeeds with an exit
trace since it does unify with the redo
predicate and
causes noun(rock2, rock)
to also succeed with exit
just as above.
As the traces continue, you can see the fail
port get
activated for
color(rock2, red)
since there is no way to prove that
predicate and thus the whole query returns false
.
Tracing will continue for every query you pose until you enter
notrace.
to turn off trace mode.