Behaviour of trace/0 and trace/1

Hi!

I’m working on a software analysis tool for Prolog and using trace/1. However, there is some information I need that is included in trace/0 but not trace/1. For example in this program:

dl([_], []) :- !.
dl([H | T], L) :- dl([], L1), L = [H | L1].
dl([H | T], L) :- dl(T, L1), L = [H | L1].
?- dl([1,2,3], [1,2]).

With trace/0:

   Call: (12) dl([1, 2, 3], [1, 2]) ? creep
   Call: (13) dl([], _20282) ? creep
   Fail: (13) dl([], _20282) ? creep
   Redo: (12) dl([1, 2, 3], [1, 2]) ? creep
   Call: (13) dl([2, 3], _22978) ? creep
   Call: (14) dl([], _23878) ? creep
...

With trace/1:

 T [12] Call: dl([1, 2, 3], [1, 2])
 T [19] Call: dl([], _49970)
 T [19 +0.1ms] Fail: dl([], _49970)
 T [19] Call: dl([2, 3], _51926)
 T [26] Call: dl([], _52998)
...

The Redo information in this example is of particular interest to me.

I understand that trace/0 is a low level feature of the interpreter, while trace/1 modifies the predicate to print the trace. But could someone help me understand why it doesn’t show the Redo in this example and if there is a way to get it to show?

I think the issue is that trace/1 only monitors the “outside” of the box. ?- dl([1,2,3], [1,2]). succeeds deterministically, so it is never subject to a “redo” when looking at the outside.

Note that prolog_trace_interception/4 allows you to interact with the debugger from your program in the same way you can as a user. But, the VM based SWI-Prolog debugger is also not perfect due to opimizations. If you want the real theoretical model showing up you probably need a meta-interpreter.

Thanks for the quick reply! I’ll look into prolog_trace_interception/4, but from a quick glance it seems I can use it to replace trace/1 with trace/0 in my use case.

It worked perfectly! Thanks again!

1 Like

Keep in mind you can very easily make the system misbehave or crash using this hook. It has no safety belts :slight_smile:

1 Like