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

问题描述

假设我有这个 Prolog 程序:

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

使用查询 jealous(A,B). 我对 Prolog 非常陌生,我想知道如何才能看到程序运行的确切顺序以及此查询的方式?我曾尝试使用 trace,jealous(A,B). 命令,但它只给了我:

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

enter image description here

解决方法

你见过Prolog Visualizer吗?

进入页面后,请务必点击右上角的图标以了解更多信息。

enter image description here

享受。


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

enter image description here

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

enter image description here


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

jealous(A,B)?

如果您在左侧的输入区域发布查询,您将收到一个错误,例如

enter image description here

您示例中 Prolog Visualizer 的输入是

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

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

enter image description here


如果您正在使用 SWI-Prolog 并且在您了解 syntactic unificationbacktracking 并编写更高级的代码之后,您会发现它很有用:

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),P,R) :- !,solve(A,H),solve(B,H,R).
solve(H,R) :- functor(H,F,A),sys_rule(F/A,J,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,K,O,R).

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

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

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

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

没有必要追溯修改mgu的,因为a的解决方案
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 新版本的预览 谓词 sys_rule/3,它的灵感来自于新的 SWI-Prolog 的谓词 rule/2,但保留 头和体的子句/2 参数并使用谓词 指标。