4

要素がリストに表示される回数を数えようとしていますが、これまでに思いついた

rate(X,[H|T],N):-
  X == H,
  N is N+1,
  rate(X,T,N).
rate(X,[_|T],N) :-
  rate(X,T,N).  
rate(_,[],N) :-
  N is 0.

一致が見つかった場合、一致がない場合、およびリストの最後に到達した場合について説明しました。しかし、私がテストすると、

43 ?- rate(4,[4,2,3,4,4,2],X).
ERROR: is/2: Arguments are not sufficiently instantiated
Exception: (6) frequency(4, [4, 2, 3, 4, 4, 2], _G393) ?     

正確に欠落している引数は何ですか?

4

3 に答える 3

4

X が数値の場合にのみis/2(のように)を使用できます。X が自由変数の場合N is Xは使用できません。is/2最初の句には次のものがありますN is N+1。N は自由変数なので、これは悪いことです (この時点では値を持たず、N+1 の場合も同様です)。

別のエラーがあります。の:

rate(X,[_|T],N) :-
  rate(X,T,N).

X がリストの最初の要素ではない場合にのみこれを使用するため、これが true であることを確認する必要があります。コードは次のとおりです。

count(_, [], 0) :- !. /* empty list, base case */

count(X, [X|T], N) :- /* if X is in the head of the list */
    count(X, T, N2), /* count on the tail (let this N2) */
    N is N2 + 1.     /* and N is N2 + 1  */

count(X, [Y|T], N) :- 
    X \= Y,          /* if X is not in the head */
    count(X, T, N).  /* just count the rest */
于 2012-08-12T16:42:51.610 に答える
2

句を相互に排他的にする必要があります。2 番目の句は、最初の句がどこでも成功します。

あなたのエラーに関しては、それは情報の流れに関するものです。次のように、最初の句の行を交換する必要があります。

rate(X,[H|T],N):-
  X == H,
  rate(X,T,N1),
  N is N1+1.

ただし、この変更により、述語は末尾再帰ではなくなります。末尾再帰的であるためには、現在のように途中で情報を受け取るのではなく、呼び出しチェーンに情報を渡す必要があります。

rate(X,[H|T],N):-
  X == H,
  N1 is N+1,
  rate(X,T,N1).

ここで最終値を受け取っていないことがわかりますが、初期値を指定します。基本ケースに到達すると、結果が得られます。

rate(X, [], N).

これNが結果です。それを取り戻す方法は?追加の引数、インスタンス化されていない変数を使用して、底に達したときにこの結果と統合します。

rate(X, [], N, V) :- V is N.

ここで、再帰句はこの変数に対応する必要があり、それを変更せずに呼び出しチェーンに渡します。

于 2012-08-12T16:42:42.953 に答える
1

機能的なスタイルが好きなら、SWIPrologでそれを書くことができます:

:- use_module(library(lambda)).


rate(X,L,N) :-
    foldl(\Y^V0^V1^((X = Y->V1 is V0+1; V1 = V0)), L, 0, N).
于 2012-08-14T14:36:36.763 に答える