我需要创建一个n个元素的列表,例如:
do_list(5,L1).
应该返回:
L1=[1,2,3,4,5].
这是我拥有的内容,但它没有起作用。
do_list(X,L1):- X1 is X-1, do_list(X1,[X1|L1]).
do_list(0,[]).
我需要创建一个n个元素的列表,例如:
do_list(5,L1).
L1=[1,2,3,4,5].
这是我拥有的内容,但它没有起作用。
do_list(X,L1):- X1 is X-1, do_list(X1,[X1|L1]).
do_list(0,[]).
如果你想创建一个从1到N的连续数字列表,可以使用内置谓词findall/3
和between/3
,如下所示:
do_list(N, L):-
findall(Num, between(1, N, Num), L).
?- do_list(5,L).
L = [1, 2, 3, 4, 5].
SWI还有另一个内置函数可以实现这个功能,numlist/3
:
?- numlist(1,5,L).
L = [1, 2, 3, 4, 5].
do_list/2
递归之前将X1添加到列表中。也就是说,你没有递归锚点,而目标?- do_list(5,L)
永远不会返回。do_list(N, L) :- do_list1(N, [], L).
do_list1(0, L, L) :- !.
do_list1(N, R, L) :- N > 0, N1 is N-1, do_list1(N1, [N|R], L).
do_list(-1,L)
。顺便问一下,哪些系统不需要这个!
? - false另一种类似于twinterer的解决方案,但没有切割或预定义谓词,而是使用累加器。
do_List(Max,L) :- do_ListAcc(1,Max,L). % call Accumulator
do_ListAcc(N,N,[N]). % N=:=N ends recursion
do_ListAcc(Min,Max,[Min|Succs]) :-
Next is Min + 1,
do_ListAcc(Next,Max,Succs).
这仅适用于正整数。
或者,如果你不想使用任何内置函数(就像我一样,在尝试这个问题时遇到了这个问题),你可以使用这个(可行但不太有效)的解决方案:
connect([],X,X).
connect([H|T],C,[H|T2]) :- connect(T,C,T2).
revert([],[]).
revert([H|T],R) :- revert(T,Trev), connect(Trev,[H],R)
do_revlist(0,[]).
do_revlist(X,[X|L]) :- X1 is X-1, do_revlist(X1,L).
do_list(X,L2) :- do_revlist(X,L), revert(L,L2).
注:仅适用于正整数。