Вопрос

I have written the following predicate append/3 to implement the combination of two lists:

append([L|Ls],R,[L|Result]):-append(Ls,R,Result).
append([],X,X).

It gives a correct output, yet when I trace the execution flow of the code, here is what I get:

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

It seems that Prolog was using my own append predicate in the first turn, but as it enters the second level of recursion, Prolog has used its own predicate as defined in the library.

How can I override Prolog's predefined predicate (besides giving my own predicate another name)?

Это было полезно?

Решение

The append/3 predicate is not a built-in predicate in SWI-Prolog but a library predicate, defined in the module lists. This module is likely being auto-loaded when you code is executed. There are two flags that can help here. The autoload flag controls auto-loading of libraries. It can be turned off the calling set_prolog_flag(autoload, false). There's also another flag, verbose_autoload, that you can set to true so that auto-loading becomes verbose. Last but not least, you can use the listing/1 predicate to examine you code. Try listing(append/3). It should reveal the call to list:append/3 in the body of clause of your predicate.

This is what I get:

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

Can you edit your post and tell us the exact sequence of calls that lead to the results you get?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top