Reputation: 2232
I am studying for my AI exam I have coming up tomorrow and I was stuck on a particular Prolog question.
The question is as follows:
Consider the following program:
r([], X, X).
r([X|Y], X2, X3) :-
r(Y, [X|X2], X3).
Trace how Prolog would find the result of the following query:
? - r([1,2,6], [], L).
We have to trace this by hand, I remember small parts, I wrote this in Prolog and got the answer but can't see where the answer came from.
P. S. I've used the trace
operator, it showed me the steps but didn't show which functions were fired.
Thank you all!
Upvotes: 1
Views: 628
Reputation: 24976
If you capture the trace to a file as outlined after this section then add line annotations to your code and correlate the code lines with the trace you will get something like this.
r([1,2,6], [], L) % Goal
r([], X, X). % Line 1
r([X|Y], X2, X3) :- % Line 2
r(Y, [X|X2], X3). % Line 3
Call: (11) r([1, 2, 6], [] , _32640 ) % Goal
Unify: (11) r([1, 2, 6], [] , _32640 ) % Line: 2
Call: (12) r([2, 6] , [1] , _32640 ) % Line: 3
Unify: (12) r([2, 6] , [1] , _32640 ) % Line: 2
Call: (13) r([6] , [2, 1] , _32640 ) % Line: 3
Unify: (13) r([6] , [2, 1] , _32640 ) % Line: 2
Call: (14) r([] , [6, 2, 1], _32640 ) % Line: 3
Unify: (14) r([] , [6, 2, 1], [6, 2, 1]) % Line: 1
Exit: (14) r([] , [6, 2, 1], [6, 2, 1]) % Line: 1
Exit: (13) r([6] , [2, 1] , [6, 2, 1]) % Line: 3
Exit: (12) r([2, 6] , [1] , [6, 2, 1]) % Line: 3
Exit: (11) r([1, 2, 6], [] , [6, 2, 1]) % Line: 3
Using protocol/0 to capture trace to a file.
File: examples.pl
:- module(examples,
[
example/1
]).
r([], X, X).
r([X|Y], X2, X3) :-
r(Y, [X|X2], X3).
example(1) :-
r([1,2,6], [], L),
format('~w~n',[L]).
Example run
Welcome to SWI-Prolog (threaded, 64 bits, version 8.3.28-20-g6f8a68f2b)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.
For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).
?- working_directory(_,'C:/Users/Groot').
true.
?- [examples].
true.
?- set_prolog_flag(color_term,false).
true.
?- leash(-all), visible(+all).
true.
?- protocol("./trace_output.txt").
true.
?- trace.
true.
[trace] ?- example(1).
Call: (10) examples:example(1)
Unify: (10) examples:example(1)
Call: (11) examples:r([1, 2, 6], [], _32640)
Unify: (11) examples:r([1, 2, 6], [], _32640)
Call: (12) examples:r([2, 6], [1], _32640)
Unify: (12) examples:r([2, 6], [1], _32640)
Call: (13) examples:r([6], [2, 1], _32640)
Unify: (13) examples:r([6], [2, 1], _32640)
Call: (14) examples:r([], [6, 2, 1], _32640)
Unify: (14) examples:r([], [6, 2, 1], [6, 2, 1])
Exit: (14) examples:r([], [6, 2, 1], [6, 2, 1])
Exit: (13) examples:r([6], [2, 1], [6, 2, 1])
Exit: (12) examples:r([2, 6], [1], [6, 2, 1])
Exit: (11) examples:r([1, 2, 6], [], [6, 2, 1])
^ Call: (11) format('~w~n', [[6, 2, 1]])
[6,2,1]
^ Exit: (11) format('~w~n', [[6, 2, 1]])
Exit: (10) examples:example(1)
true.
[trace] ?- nodebug.
true.
?- noprotocol.
true.
File: trace_output.txt
true.
?- trace.
true.
[trace] ?- example(1).
Call: (10) examples:example(1)
Unify: (10) examples:example(1)
Call: (11) examples:r([1, 2, 6], [], _32640)
Unify: (11) examples:r([1, 2, 6], [], _32640)
Call: (12) examples:r([2, 6], [1], _32640)
Unify: (12) examples:r([2, 6], [1], _32640)
Call: (13) examples:r([6], [2, 1], _32640)
Unify: (13) examples:r([6], [2, 1], _32640)
Call: (14) examples:r([], [6, 2, 1], _32640)
Unify: (14) examples:r([], [6, 2, 1], [6, 2, 1])
Exit: (14) examples:r([], [6, 2, 1], [6, 2, 1])
Exit: (13) examples:r([6], [2, 1], [6, 2, 1])
Exit: (12) examples:r([2, 6], [1], [6, 2, 1])
Exit: (11) examples:r([1, 2, 6], [], [6, 2, 1])
^ Call: (11) format('~w~n', [[6, 2, 1]])
[6,2,1]
^ Exit: (11) format('~w~n', [[6, 2, 1]])
Exit: (10) examples:example(1)
true.
[trace] ?- nodebug.
true.
?- noprotocol.
Upvotes: 1
Reputation: 22585
If you use SWI prolog tracer you can execute step by step your procedure and it will show you the current goal and the backtrace (sort of call stack) if requested.
Just issue a trace.
followed by the call to your goal r([1,2,6], [], L).
You can follow step by step the execution of the goal by pressing Enter and print the current backtrace by pressing g
You can also use the graphical tracer issuing gtrace.
instead of trace.
. Using the graphical tracer allows you to see the call stack and each frame's variable bindings.
To end tracing you may call nodebug.
Upvotes: 0