質問
それが必要になる状況が思いつきません。
解決
エレガントなシステムが不可欠false/0
ための宣言同義語としてfail/0
を提供しています。
?- between(1,3,N), format("line ~w\n", [N]), false.
line 1
line 2
line 3
その代わりfalse/0
の、あなたも少し短く、たとえば、失敗したすべての目標を使用することができます
?- between(1,3,N), format("line ~w\n", [N]), 0=1.
line 1
line 2
line 3
このように、false/0
が厳密に必要とされていませんが、とてもいいます。
編集:私は時々、「私の関係は、空のリストのために保持していない」とは、例えば状態にしたい初心者を見て、その後、追加します:
my_relation([]) :- false.
。これは、のではありませんの必要、とのないのプログラムで生成された障害スライスの例を除き、false/0
を使用しての良い例。代わりに、あなたの関係についての保留 の事を述べに集中しています。この場合には、単に全体の句を残し、そしてのみ空でないリストの関係を定義する、すなわち、少なくとも1つの要素を有する:
my_relation([L|Ls]) :- etc.
または、のような制約を使用します:
my_relation(T) :- dif(T, []), etc.
を考えるだけのどちらか(あるいは両方)これら2つの句の、クエリ?- my_relation([]).
は自動的に失敗します。その目的のために成功したことがない、追加条項を導入する必要はありません。
他のヒント
明示的な失敗。 fail
多くの場合、cut と組み合わせて使用されます。 ... !, fail.
失敗を強制するため。
すべての構築物に対して。 明示的な使用法 fail
/false
列挙する 経由 バックトラッキングは非常にエラーが発生しやすいアクティビティです。次のようなケースを考えてみましょう。
... ( generator(X), action(X), fail ; true ), ...
したがって、アイデアはすべての人のために行動を「行う」ことです X
. 。しかし、もしそうなったらどうなるでしょうか action(X)
失敗しますか?この構造は、何も起こらなかったかのように、次の候補に単純に続きます。このようにして、特定のエラーが非常に長い間検出されないままになる可能性があります。
このような場合には、使用する方が良いです \+ ( generator(X), \+ action(X) )
失敗した場合は、 action(X)
一部の人にとっては失敗する X
. 。一部のシステムではこれが組み込みとして提供されています forall/2
. 。個人的には、使用することを好みます \+
この場合、 \+
この構造がバインディングを残さないことが少し明確になります。
失敗スライス。 診断目的では、意図的に追加すると便利なことがよくあります。 false
あなたのプログラムに。見る 失敗スライス 詳細については。
フェイルの別の用途は、副作用を持つ述語を使用した場合の代替案を通じてバックトラックを強制することです。
writeall(X) :- member(A,X), write(A), fail.
writeall(_).
一部の人々は、けれども、この特に良いプログラミングスタイルを考慮していない可能性があります。 :)
が一つの場合は(Eclipseのを使用して制約論理プログラミングから採取した)でありますない/ 1の実装ます:
:- op(900, fy, not).
not Q :- Q, !, fail.
not _ .
Qが成功した場合は、は、カット(!)は、第二ではない節が廃棄させ、そして失敗は陰性の結果を保証します。 Qが失敗した場合は、2番目のない句火災最初ます。