2

私はPrologを初めて使用しますが、再帰がどのように機能するかを理解するのに問題があります。

私がやりたいと思うのは、数字のリストを作成することです(後でグラフィックを描くため)。

だから私はこのコードを持っています:

nbClassTest(0, _). 

nbClassTest(X, L) :- 
    numberTestClass(A,X),
    append([A], L, L),
    X is X - 1,
    nbClassTest(X, L).

しかし、それは私に答えとして「偽」を与え続け、なぜそれがリストを満たさないのか理解できません。Xが0になったら終了するはずですよね?

numberTestClass(A、X)は、関数であるかのように、いくつかのXの数値(変数A内)を提供します。

4

3 に答える 3

2

問題は、古いリストと新しいリストに同じ変数を使用することです。今、最初にappend / 3を追加すると、Aの値に等しい要素で構成される無限の長さのリストが作成されます。

?-append([42],L,L).
L = [42|L].

?- append([42],L,L), [A,B,C,D|E]=L.
L = [42|L],
A = B, B = C, C = D, D = 42,
E = [42|L].

次に、次のAが前のAと同じでない場合、失敗します。

?- append([42],L,L), append([41],L,L).
false.

コードにはまだまだ問題があります。基本ケースにはインスタンス化されていない変数があります。あなたはそれが欲しいかもしれませんが、私はあなたが実際に空のリストが欲しいと信じています:

nbClassTest(0, []). 

nbClassTest(X, L) :- 
    numberTestClass(A,X),
    append([A], L, NL),
    X is X - 1,
    nbClassTest(X, NL).

最後に、append / 3はやや非効率的であるため、それを避けてリストを逆に作成する(または差分リストを使用する)ことをお勧めします。

于 2012-05-22T18:42:54.600 に答える
2

かなり非効率的であるため、追加せずにリストを作成する必要があります。このコードは次のことを実行できます。

nbClassTest(0, []). 
nbClassTest(X, [A|R]) :- 
    numberTestClass(A, X),
    X is X - 1,
    nbClassTest(X, R).

または、システムに/ 3の間にある場合は、「すべてのソリューション」のイディオムを使用できます。

nbClassTest(X, L) :-
    findall(A, (between(1, X, N), numberTestClass(A, X)), R),
    reverse(R, L).
于 2012-05-22T18:55:03.937 に答える
1

間違った方法でappendを使用したため、失敗します。

nbClassTest(0, _). 

nbClassTest(X, L) :- 
    numberTestClass(A,X),
    append([A], L, Nl),
    X is X - 1,
    nbClassTest(X, Nl).

連結2つのリストを追加して、要素を追加した後も同じリストになるようなリストがないようにします。

于 2012-05-22T18:36:25.790 に答える