5

たとえば、 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,[]).
4

4 に答える 4

11

1からNまでの連続した数値のリストを作成する場合は、組み込みの述語findall/3between/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].
于 2012-04-18T12:46:51.970 に答える
2

コードには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).
于 2012-04-18T05:55:52.887 に答える
0

または、組み込み関数を使用したくない場合 (私のように、これを練習として試してからこの質問に出くわしたとき)、この (機能するが効果的ではない) ソリューションを使用できます。

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 正の整数に対してのみ機能します。

于 2018-01-02T10:45:15.703 に答える