为此:
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]).
为什么会这样(在swipl中)?
?- useAdd([42, 100, ok], hello).
[ok,100,42,hello]
done []
true.
显然,在New
中分配给useAdd
相当了,因为正确的列表已传递给reverseList
。但是,与New
不同,T
中的useAdd
为空。
T
的{{1}}中获取反向列表?答案 0 :(得分:1)
您对reverseList/2
的定义使用 T
作为反向列表的结尾。反向列表是在递归的最深层构建并打印的,然后对创建的值不做任何操作:
2 ?- reverseList( [1,2,3,4], [0]).
[4,3,2,1,0]
true.
相反,将其作为新的逻辑变量传递,作为第三个参数,在调用之间沿原样传递,最后将其设置为最深层次:
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).
然后将其称为reverseList( [1,2,3,4], Newtail, T)
,以将T
设置为最深层次的递归:
6 ?- reverseList( [1,2,3,4], [0], T).
[4,3,2,1,0]
T = [4, 3, 2, 1, 0].
定义无处不在,命名很糟糕,并且它可能将T
用作“ tail”,因此您应该使用诸如R
之类的新参数,至少要暗示一下它会保存 reversed 列表作为调用的 result 。