次の Prolog 述語プロトタイプがあります: solution(+InputVector)。ここで、InputVector は不明な長さの値のリストです。リスト内のすべての値が 0 より大きい場合、メッセージを出力します。どうすればいいですか?
4 に答える
学習を「高次」の述語に拡張することに興味がある場合は、maplist /2を検討してください。
3 ?- maplist(<(0), [1,2,3]).
true.
4 ?- maplist(<(0),[0,1,2,3]).
false.
リストが [] または [X|Xs] であるかどうかを確認し、それに応じて対処してください。
あなたはもうすぐそこにいました。以下を検討してください(@aBathologistのおかげで更新されました):
1| solution([X]) :-
2| X > 0,
3| !,
4| write_ln('Success!').
5| solution([X|Y]) :-
6| X > 0,
7| solution(Y).
これが実際にどのように機能するかを行ごとに考えてみましょう。
- 単一要素リストを引数として
solution/1
取る述語の最初の句を定義します。X
X
itemが である数値かどうかをテストし> 0
ます。そうでない場合、述語はここで終了し、失敗します。それ以外の場合、Prolog は次の行に進みます。- 厳密には必要ではありませんが、ここでのカット (
!
) は、(6) 行目の 2 番目の句も入力で実行できた場合、(1) で Prolog が生成したであろう選択ポイントを削除します。これはwhere =[X]
と同等であるためです。したがって、これはいわゆる「グルー」カットであり、効率のみを目的としています。[X|Y]
Y
[]
- リスト
[X]
にはすべてゼロより大きい要素が含まれているため、述語はメッセージを出力して成功します。 - 1 つまたは複数の項目
solution/1
を含むリストを受け取る述語の 2 番目の節を定義します。X
Y
[]
- 行 (2) と同じ。
- リストの残りの部分を再帰的にテストし
Y
ます。
上記の定義は、ゼロより大きい数値の空でないsolution/1
リストでのみ成功する必要があると想定していることに注意してください。この述語が空のリストで成功することを許可したい場合は、実装をさらに簡単にすることができます。
solution([]) :-
write_ln('Success!').
solution([X|Y]) :-
X > 0,
solution(Y).
このバージョンでは、 の 2 つの句のいずれかsolution/1
が引数に基づいて実行されます。最初の句は空のリストを処理し、2 番目の句はゼロより大きい数値の空でないリストを処理します。!
述語引数は単一化不可能 ( []
\= [X|Y]
) であり、Prolog は最初の句の呼び出しに対して選択ポイントを生成しないため、ここではカット ( ) は必要ありません。
これが役に立ち、Prolog 構文のセマンティクスの一部がより明確になったことを願っています。
述語を次のように書きます。
all_greater_than_zero([]).
all_greater_than_zero([H|T]) :-
H > 0,
all_greater_than_zero(T).
空のリストは受け入れられると思いました。そうでない場合は、最初の句を削除できます。