我编写了以下谓词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的预定义谓词(除了给我自己的谓词另一个名字)?
答案 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] ?-
你能编辑你的帖子并告诉我们你得到结果的确切电话顺序吗?