在Prolog中重写预定义谓词

在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/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.

[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)
会得到什么?