Back to trace mode features: Because the tracing output of a Prolog program can often be quite large, sometimes it is useful to start trace mode at a particular point deep in the program. This is what a spy point is for. It specifies a predicate that should turn on trace mode.
A spy point is enabled like this: spy(mypredicate/2)
.
After that command, the first time mypredicate/2 is encountered, trace
mode will turn on and work just like it does normally. This includes
paying attention to the global leash/1
and visible/1
settings. The spy point can be removed using nospy/1
or nospyall/0.
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).
?- spy(is_a/2). % Spy point on is_a/2 true. [debug] ?- noun(X, rock), adjective(X, color, red). * Call: (12) is_a(_1858, rock) ? creep * Exit: (12) is_a(rock1, rock) ? creep Exit: (11) noun(rock1, rock) ? creep 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 ; * Redo: (12) is_a(_1858, 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.
After the spy point is hit, the output above is identical to the traces generated by running trace/0 with the initial query, but is obviously missing all of the traces before the spy point.
Note that after spy/1
is called, there is a new tag in front of ?-
, the [debug]
tag:
?- spy(is_a/2). % Spy point on is_a/2 true. [debug] ?-
This means the system is in "debug mode". Debug mode does two things: it tells the system to watch for spy points and it turns off some optimizations that would make the traces confusing. The ideal 4-port model (Byrd, 1980) as described in many Prolog books (Clocksin & Melish, 1987) is not visible in many Prolog implementations because code optimisation removes part of the choice and exit points. Backtrack points are not shown if either the goal succeeded deterministically or its alternatives were removed using the cut. When running in debug mode, choice points are only destroyed when removed by the cut and last call optimisation is switched off. [Note: This implies the system can run out of stack in debug mode, while no problems arise when running in non-debug mode.]
Debug mode can be turned off again using nodebug/0, but then the spy point will be ignored (but remembered). Turning debug mode back on via debug/0 will hit the spy point again.
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).
?- spy(is_a/2). % Spy point on is_a/2 true. [debug] ?- nodebug. true. ?- noun(X, rock). X = rock1 ; X = rock2. ?- debug. true. [debug] ?- noun(X, rock). * Call: (11) is_a(_47826, rock) ? creep * Exit: (11) is_a(rock1, rock) ? creep Exit: (10) noun(rock1, rock) ? creep X = rock1 ; * Redo: (11) is_a(_47826, rock) ? creep * Exit: (11) is_a(rock2, rock) ? creep Exit: (10) noun(rock2, rock) ? creep X = rock2.
So, debug mode allows Prolog to watch for spy points and enable trace mode when it hits one. The tracing/0 and debugging/0 predicates will report if the system is in either of those modes.