在Prolog中覆盖预定义谓词

时间:2014-02-20 16:21:22

标签: 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.

[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的预定义谓词(除了给我自己的谓词另一个名字)?

1 个答案:

答案 0 :(得分: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]  ?- 

你能编辑你的帖子并告诉我们你得到结果的确切电话顺序吗?