在Prolog中重写预定义谓词
我编写了以下谓词append/3来实现两个列表的组合:在Prolog中重写预定义谓词,prolog,swi-prolog,Prolog,Swi Prolog,我编写了以下谓词append/3来实现两个列表的组合: append([L|Ls],R,[L|Result]):-append(Ls,R,Result). append([],X,X). 它给出了正确的输出,但当我跟踪代码的执行流时,我得到的是: 1 ?- edit. true. 2 ?- make. % //dougal/cs0u$/cyw03u/desktop/lab3 compiled 0.00 sec, 3 clauses true. 3 ?- trace. true. [tra
append([L|Ls],R,[L|Result]):-append(Ls,R,Result).
append([],X,X).
它给出了正确的输出,但当我跟踪代码的执行流时,我得到的是:
1 ?- edit.
true.
2 ?- make.
% //dougal/cs0u$/cyw03u/desktop/lab3 compiled 0.00 sec, 3 clauses
true.
3 ?- trace.
true.
[trace] 3 ?- append([a,b,c],[d,e],X).
Call: (6) append([a, b, c], [d, e], _G554) ? creep
Call: (7) lists:append([b, c], [d, e], _G636) ? creep
Exit: (7) lists:append([b, c], [d, e], [b, c, d, e]) ? creep
Exit: (6) append([a, b, c], [d, e], [a, b, c, d, e]) ? creep
X = [a, b, c, d, e].
?- set_prolog_flag(verbose_autoload, true).
true.
?- [user].
append([L|Ls],R,[L|Result]):-append(Ls,R,Result).
|: append([],X,X).
|: % user://1 compiled 0.00 sec, 3 clauses
true.
?- listing(append/3).
% autoloading user:listing/1 from /Users/pmoura/lib/swipl-7.1.8/library/listing
% autoloading system:append/3 from /Users/pmoura/lib/swipl-7.1.8/library/lists
lists:append([], A, A).
lists:append([A|B], C, [A|D]) :-
append(B, C, D).
system:append([], A, A).
system:append([A|B], C, [A|D]) :-
append(B, C, D).
append([A|B], C, [A|D]) :-
append(B, C, D).
append([], A, A).
true.
?- trace.
true.
[trace] ?- append([a,b,c],[d,e],X).
Call: (6) append([a, b, c], [d, e], _G354) ? creep
Call: (7) append([b, c], [d, e], _G436) ? creep
Call: (8) append([c], [d, e], _G439) ? creep
Call: (9) append([], [d, e], _G442) ? creep
Exit: (9) append([], [d, e], [d, e]) ? creep
Exit: (8) append([c], [d, e], [c, d, e]) ? creep
Exit: (7) append([b, c], [d, e], [b, c, d, e]) ? creep
Exit: (6) append([a, b, c], [d, e], [a, b, c, d, e]) ? creep
X = [a, b, c, d, e].
[trace] ?-
似乎Prolog在第一轮中使用了我自己的附加谓词,但当它进入第二级递归时,Prolog使用了库中定义的自己的谓词
如何覆盖Prolog的预定义谓词(除了给我自己的谓词起另一个名称)谓词不是SWI Prolog中的内置谓词,而是在模块
列表中定义的库谓词。执行代码时,此模块可能会自动加载。这里有两个标志可以提供帮助。autoload
标志控制库的自动加载。它可以关闭调用set\u prolog\u标志(autoload,false)
。还有另一个标志,verbose\u autoload
,您可以将其设置为true
,以便自动加载变为verbose。最后,您可以使用清单/1
谓词检查代码。尝试列表(追加/3)
。它应该在谓词的of子句体中显示对list:append/3
的调用
这就是我得到的:
1 ?- edit.
true.
2 ?- make.
% //dougal/cs0u$/cyw03u/desktop/lab3 compiled 0.00 sec, 3 clauses
true.
3 ?- trace.
true.
[trace] 3 ?- append([a,b,c],[d,e],X).
Call: (6) append([a, b, c], [d, e], _G554) ? creep
Call: (7) lists:append([b, c], [d, e], _G636) ? creep
Exit: (7) lists:append([b, c], [d, e], [b, c, d, e]) ? creep
Exit: (6) append([a, b, c], [d, e], [a, b, c, d, e]) ? creep
X = [a, b, c, d, e].
?- set_prolog_flag(verbose_autoload, true).
true.
?- [user].
append([L|Ls],R,[L|Result]):-append(Ls,R,Result).
|: append([],X,X).
|: % user://1 compiled 0.00 sec, 3 clauses
true.
?- listing(append/3).
% autoloading user:listing/1 from /Users/pmoura/lib/swipl-7.1.8/library/listing
% autoloading system:append/3 from /Users/pmoura/lib/swipl-7.1.8/library/lists
lists:append([], A, A).
lists:append([A|B], C, [A|D]) :-
append(B, C, D).
system:append([], A, A).
system:append([A|B], C, [A|D]) :-
append(B, C, D).
append([A|B], C, [A|D]) :-
append(B, C, D).
append([], A, A).
true.
?- trace.
true.
[trace] ?- append([a,b,c],[d,e],X).
Call: (6) append([a, b, c], [d, e], _G354) ? creep
Call: (7) append([b, c], [d, e], _G436) ? creep
Call: (8) append([c], [d, e], _G439) ? creep
Call: (9) append([], [d, e], _G442) ? creep
Exit: (9) append([], [d, e], [d, e]) ? creep
Exit: (8) append([c], [d, e], [c, d, e]) ? creep
Exit: (7) append([b, c], [d, e], [b, c, d, e]) ? creep
Exit: (6) append([a, b, c], [d, e], [a, b, c, d, e]) ? creep
X = [a, b, c, d, e].
[trace] ?-
您能否编辑您的帖子,并告诉我们导致您得到结果的调用的确切顺序?当我尝试您的示例(在SWI Prolog中)时,我没有得到相同的结果;它使用了私有的append
版本。你用的是哪种prolog解释器?我也用的是SWI prolog(版本是6.2.6),我用的是版本6.0.2。不确定这是否是结果不同的原因。您是否有一个更大的上下文,或者您只是在输入swipl
并将您的代码作为[user]
输入时看到这些结果?很抱歉,我不能完全理解您的最后一句话,因为我对Prolog还是很陌生…:(但我写的只是一个简单的快速排序程序,我通常只需双击我的文件quicksort.pl,键入make.
,然后在弹出的窗口中键入[quicksort]。
。
。我的建议是,要像我一样重现问题,(1)输入swipl
命令,获得一个prolog提示符,(2)输入[user].
然后是Enter,(3)只输入您的追加
代码。然后在prolog提示符下,启动跟踪(输入trace.
)和示例查询,看看是否得到相同的结果。我已经用调用序列编辑了文章。顺便说一句,当我显式键入命令设置prolog\u标志(autoload,false)时.
,自动加载不会再次发生。我无法复制您的结果。我注意到您的lab3
文件似乎包含10个子句,但您只向我们显示了append/3
子句。可能该文件中的其他内容导致了您得到的结果?我刚刚尝试删除了其他代码,只留下了3行,但我仍然得到相同的结果(后期编辑)。但是如果我使用[user]
方法,即使我没有显式调用set\u prolog\u标志(autoload,false),我也不会遇到这个问题.
如何启动SWI Prolog,以便调用edit/0
知道要编辑哪个文件?如果在调用make
前后调用listing(append/3)
会得到什么?