Prologでは、リストのように、再帰を使用して再帰データ構造体の要素を検査します。パターンマッチングにより、適用する適切なルールを選択できます。あなたの仕事をする簡単な方法:
リスト=[X| Xs]があり、各要素Xについて、奇数(X)の場合はcountOdds(Xs)+1を返し、そうでない場合はcountOdds(Xs)を返します。
countOdds([], 0).
countOdds([X|Xs], C) :-
odd(X),
!, % this cut is required, as rightly evidenced by Alexander Serebrenik
countOdds(Xs, Cs),
C is Cs + 1.
countOdds([_|Xs], Cs) :-
countOdds(Xs, Cs).
if
、はパターン付きの別のルールで処理されることに注意してくださいsame
。Prologが奇数でない要素を見つけると、最後のルールに戻ります。
ISO Prologには、のためのシンタックスシュガーがIf Then Else
あり、それを使って書くことができます
countOdds([], 0).
countOdds([X|Xs], C) :-
countOdds(Xs, Cs),
( odd(X)
-> C is Cs + 1
; C is Cs
).
最初のバージョンでは、再帰呼び出しがテストの後に続き、odd(X)
バックトラックで繰り返される必要のあるリストテールの無駄な訪問を回避します。
編集カットなしでは、複数の実行パスが取得されるため、「すべてのソリューション」述語(findall、setofなど)で誤った結果が生じる可能性があります
この最後のバージョンは、手順がそうではないという証拠を示しましたtail recursive
。末尾再帰プロシージャを取得するには、:を追加しaccumulator
ます。
countOdds(L, C) :- countOdds(L, 0, C).
countOdds([], A, A).
countOdds([X|Xs], A, Cs) :-
( odd(X)
-> A1 is A + 1
; A1 is A
),
countOdds(Xs, A1, Cs).