如何查看 Prolog 查询的详细顺序(执行)?

How do I see a detailed order (execution) for a Prolog query?

假设我有这个 Prolog 程序:

loves(vincent, mia).
loves(marcellus, mia).
jealous(A, B) :- loves(A, C), loves(B, C).

使用查询 jealous(A,B). 我是 Prolog 的新手,我想知道如何才能看到程序的确切顺序 运行 并为此采取它的方式询问?我试过使用 trace, jealous(A,B). 命令,但它只给了我:

没有更详细的解决方案吗? :/

你看过Prolog Visualizer吗?

当您到达该页面时,请务必单击右上角的图标以了解更多信息。

尽情享受吧。


第 10 步(共 49 步)后的屏幕截图。

所有步骤后给出的示例屏幕截图。


Prolog Visualizer 使用稍微不标准的方式输入查询,即以问号 (?) 结束查询,例如

jealous(A,B)?

如果您 post左侧输入区域中的查询,您将收到错误消息,例如

您示例的 Prolog Visualizer 输入是

loves(vincent, mia).
loves(marcellus, mia).
jealous(A, B) :- loves(A, C), loves(B, C).
jealous(A,B)?

当 Prolog Visualizer 完成您的示例时,请注意右侧的四个绿色结果


如果您正在使用 SWI-Prolog and after you understand syntactic unification, backtracking 并编写更高级的代码,您会发现这个有用:

Overview of the SWI Prolog Graphical Debugger


有关其他有用的 Prolog 参考资料,请参阅:Useful Prolog references

如果Prolog系统有callable_property/2和sys_rule/3,那么可以编码
如下所示的智能“统一”端口,显示了最通用的统一器(mgu's`):

:- op(1200, fx, ?-).

% solve(+Goal, +Assoc, +Integer, -Assoc)
solve(true, L, _, L) :- !.
solve((A, B), L, P, R) :- !, solve(A, L, P, H), solve(B, H, P, R).
solve(H, L, P, R) :- functor(H, F, A), sys_rule(F/A, J, B),
   callable_property(J, sys_variable_names(N)),
   number_codes(P, U), atom_codes(V, [0'_|U]), shift(N, V, W),
   append(L, W, M), H = J, reverse(M, Z), triage(M, Z, I, K),
   offset(P), write_term(I, [variable_names(Z)]), nl,
   O is P+1, solve(B, K, O, R).

% triage(+Assoc, +Assoc, -Assoc, -Assoc)
triage([V=T|L], M, R, [V=T|S]) :- var(T), once((member(W=U, M), U==T)), W==V, !,
   triage(L, M, R, S).
triage([V=T|L], M, [V=T|R], S) :-
   triage(L, M, R, S).
triage([], _, [], []).

% shift(+Assoc, +Atom, -Assoc)
shift([V=T|L], N, [W=T|R]) :-
   atom_concat(V, N, W),
   shift(L, N, R).
shift([], _, []).

% offset(+Integer)
offset(1) :- !.
offset(N) :- write('\t'), M is N-1, offset(M).

% ?- Goal
(?- G) :-
   callable_property(G, sys_variable_names(N)),
   shift(N, '_0', M),
   solve(G, M, 1, _).

不需要追溯修改mgu,因为
Prolog查询是mgu的顺序组成。这是一个例子 运行:

?- ?- jealous(A,B).
[A_0 = X_1, B_0 = Y_1]
    [H_1 = mia, X_1 = vincent]
    [Y_1 = vincent]
A = vincent,
B = vincent ;
    [Y_1 = marcellus]
A = vincent,
B = marcellus ;
Etc..

这是新版 Jekejeke Prolog 1.5.0 的预览 predicate sys_rule/3,它的灵感来自于新的 SWI-Prolog 的谓词 rule/2,但保留 clause/2 head 和 body 的参数并使用谓词 指标。