您正在按程序思考,在序言中您无法更改变量。您正在尝试自己构建列表。在序言风格中,您尝试声明所需列表的约束。如果nlist/2
是一个给出 N 个数字列表的谓词,那么它的属性到底是什么?nlist(0, []).
and if nlist(N, Xs)
then nlist(N+1, [N+1 | Xs])
。所以你只需编写这些并让 prolog 负责构建。
nlist(0, []).
nlist(N, [N | Xs]) :-
N>0, N1 is N-1,
nlist(N1, Xs).
如果您对递归调用的发生方式感到困惑,请尝试使用trace/0
or trace/1
。您可以在以下跟踪中看到调用是如何完成的。您可以通过致电获取此信息trace(nlist)
.
?- nlist(3, X).
T Call: nlist(3, _78)
T Call: nlist(2, _902)
T Call: nlist(1, _1464)
T Call: nlist(0, _2026)
T Exit: nlist(0, [])
T Exit: nlist(1, [1])
T Exit: nlist(2, [2, 1])
T Exit: nlist(3, [3, 2, 1])
X = [3, 2, 1]
更程序化的代码如下
addToList(11, A, A).
% Cases 1-10
addToList(Value, List, NewList) :-
Value < 11, append(List, [Value], Temp),
NextVal is Value+1,
addToList(NextVal, Temp, NewList).
这给出了中间参数是累加器。当您达到 11 时,累加器就是答案。
?- addToList(1, [], X).
X = [1, 2, 3, 4, 5, 6, 7, 8, 9|...]
?- addToList(5, [], X).
X = [5, 6, 7, 8, 9, 10]
查看示例跟踪以及它们之间的差异nlist
and addToList
。尝试找出差异以及发生差异的原因。
?- addToList(7, [], X).
T Call: addToList(7, [], _33565254)
T Call: addToList(8, [7], _33565254)
T Call: addToList(9, [7, 8], _33565254)
T Call: addToList(10, [7, 8, 9], _33565254)
T Call: addToList(11, [7, 8, 9, 10], _33565254)
T Exit: addToList(11, [7, 8, 9, 10], [7, 8, 9, 10])
T Exit: addToList(10, [7, 8, 9], [7, 8, 9, 10])
T Exit: addToList(9, [7, 8], [7, 8, 9, 10])
T Exit: addToList(8, [7], [7, 8, 9, 10])
T Exit: addToList(7, [], [7, 8, 9, 10])
X = [7, 8, 9, 10]