2014-02-20 42 views
2

我写了下面的谓词append/3可以实现两个列表组合:覆盖预定义的谓词的Prolog

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]. 

看来,Prolog的是用我自己的附加谓词在第一圈,但因为它进入递归的第二个层次,Prolog有利用自身的谓词在库中定义。

我怎样才能覆盖Prolog的预定义谓词(除了给我自己的谓词另一个名字)?

+0

当我尝试你的例子(在SWI Prolog中)时,我没有得到相同的结果;它使用私有的“附加”版本。您使用的是哪个prolog解释器? – lurker

+0

我也在使用SWI Prolog(版本是6.2.6) – Pingu

+0

我在版本6.0.2上。不知道这是结果不同的原因。你有更大的上下文,还是你看到这些结果只是输入'swipl'并把你的代码放在'[user]'中? – lurker

回答

1

append/3谓词不是SWI-Prolog中的内置谓词,而是库谓词,在模块lists中定义。当您执行代码时,该模块可能会自动加载。有两个标志可以帮助这里。 autoload标志控制库的自动加载。它可以关闭调用set_prolog_flag(autoload, false)。还有另一个标志verbose_autoload,您可以将其设置为true,以便自动加载变得冗长。最后但并非最不重要的,你可以使用listing/1谓词来检查你的代码。尝试listing(append/3)。它应该在你的谓词的子句体中显示对list:append/3的呼叫。

这就是我得到:

?- 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] ?- 

您可以编辑您的文章,并告诉我们调用导致的结果你得到的精确序列?

+0

我已经编辑了我的调用序列的帖子。顺便说一句,当我明确地键入命令'set_prolog_flag(autoload,false).'时,自动加载不会再次发生。 – Pingu

+0

我无法重现您的结果。我注意到你的'lab3'文件似乎包含10个子句,但你只向我们展示了'append/3'子句。也许该文件中的其他内容会导致您获得的结果? –

+0

我刚刚试图删除其他代码,只留下3行,但我仍然得到相同的结果(编辑后)。然而,如果我使用'[user]'方法,即使没有明确调用set_prolog_flag(autoload,false),我也不会遇到这个问题。' – Pingu