4
votes

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

1
When I tried your example (in SWI Prolog), I didn't get the same result; it used the private append version. Which prolog interpreter are you using?lurker
I am also using SWI Prolog (version is 6.2.6)Pingu
I'm on version 6.0.2. Not sure if that's why the results are different. Do you have a much bigger context, or are you seeing these results just entering swipl and putting your code in as [user]?lurker
Sorry that I can't quite get your final sentence, because I am still very new to Prolog... :( But what I am writing is just a simple quicksort program, and I would usually just double click my file quicksort.pl, type make. and then [quicksort]. in the window that popped up.Pingu
What I was suggesting, to reproduce the problem as I did, (1) enter swipl command, get a prolog prompt, (2) type in [user]. followed by Enter, (3) enter just your append code. Then at the prolog prompt, start trace (enter trace.) and your example query and see if you get the same result.lurker

1 Answers

1
votes

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?