Reputation: 11536
Given this:
useAdd(List, What) :-
addToList(List, What, New),
reverseList(New, T),
write("done "),
write(T), nl, !.
addToList(List, What, [ What | List]).
reverseList([], List) :- write(List), nl.
reverseList([H | Old], []) :- reverseList(Old, [ H ]).
reverseList([ H | Old], New) :- reverseList(Old, [ H | New]).
Why does this happen (in swipl)?
?- useAdd([42, 100, ok], hello).
[ok,100,42,hello]
done []
true.
Obviously assigning to New
in useAdd
amounted to something, because the correct list is passed to reverseList
. But then, unlike New
, T
in useAdd
is empty.
T
in useAdd
?Upvotes: 1
Views: 43
Reputation: 71065
Your definition of reverseList/2
uses T
as the reversed list's tail. The reversed list is built and printed at the deepest level of recursion, and then nothing is done with that created value:
2 ?- reverseList( [1,2,3,4], [0]).
[4,3,2,1,0]
true.
Instead, pass it in as a fresh logical variable, as a third parameter, pass it along unchanged between the invocations, and finally set it at the deepest level:
reverseList([], List, T) :- List = T, write(List), nl.
reverseList([H | Old], [], T) :- reverseList(Old, [ H ], T).
reverseList([ H | Old], New, T) :- reverseList(Old, [ H | New], T).
Then call it as reverseList( [1,2,3,4], Newtail, T)
to get your T
set at the deepest level of recursion:
6 ?- reverseList( [1,2,3,4], [0], T).
[4,3,2,1,0]
T = [4, 3, 2, 1, 0].
The definition is all over the place, the naming is terrible, and it used T
probably for "tail", so you should name the new argument something like R
instead, to at least hint at the fact that it will hold the reversed list as the result of an invocation.
Upvotes: 1