跟踪 Prolog 如何找到查询结果

Trace how Prolog finds result for query

我正在准备明天的 AI 考试,但我被困在一个特定的 Prolog 问题上。

问题如下:

考虑以下程序:

r([], X, X).
r([X|Y], X2, X3) :- 
   r(Y, [X|X2], X3).

跟踪 Prolog 如何找到以下查询的结果:

? - r([1,2,6], [], L).

我们必须手工追踪这个,我记得小部分,我在 Prolog 中写了这个并得到了答案,但看不到答案来自哪里。

P. S. 我使用了 trace 运算符,它向我展示了步骤但没有显示触发了哪些函数。

谢谢大家!

如果您使用 SWI prolog tracer,您可以逐步执行您的程序,如果需要,它会向您显示当前目标和回溯(某种调用堆栈)。

只需发出一个 trace. 然后调用您的目标 r([1,2,6], [], L).

您可以按 Enter 逐步执行目标,并按 g[=16 打印当前回溯=]

您还可以使用发出 gtrace. 而不是 trace. 的图形跟踪器。使用图形跟踪器允许您查看调用堆栈和每个帧的变量绑定。

要结束跟踪,您可以调用 nodebug.

如果您按照本节之后的概述将跟踪捕获到文件,然后将行注释添加到您的代码并将代码行与跟踪相关联,您将得到类似这样的结果。

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

使用 protocol/0 将跟踪捕获到文件。

文件: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]).

示例运行

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.

文件: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.