たとえば、 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].
コードには3つの問題があります。最初の問題は、句の本文のリストにX1を追加することですが、新しいリストを句の先頭に戻すことは決してありません。つまり、L1はアキュムレータ変数ですが、最終的なリストにバインドされる3番目の引数が必要です。
2つ目は、2番目の句は、入力リストが空の場合にのみ一致するということです。do_list/2
再帰的に呼び出す前にリストにX1を追加するため、これは決して当てはまりません。つまり、再帰アンカーがなく、ゴール?- do_list(5,L)
が戻ることはありません。
3番目の問題は、Xの代わりにX1をリストに追加することです。最大数をスキップします。
これがどのように機能するかです:
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).
または、組み込み関数を使用したくない場合 (私のように、これを練習として試してからこの質問に出くわしたとき)、この (機能するが効果的ではない) ソリューションを使用できます。
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).
PS 正の整数に対してのみ機能します。