22

私はそれが必要になる状況を思い付くことができません。

4

5 に答える 5

23

エレガントなシステム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([]).は自動的に失敗します。その目的のために決して成功しない追加の句を導入する必要はありません。

于 2010-06-08T22:54:58.757 に答える
10

Explicit failure. fail is often used in conjunction with cut: ... !, fail. to enforce failure.

For all construct. Explicit usage of fail/false to enumerate via backtracking is a very error prone activity. Consider a case:

... ( generator(X), action(X), fail ; true ), ...

The idea is thus to "do" action for all X. But what happens, if action(X) fails? This construct simply continues with the next candidate — as if nothing happened. In this manner certain errors may remain undetected for very long.

For such cases it is better to use \+ ( generator(X), \+ action(X) ) which fails, should action(X) fail for some X. Some systems offer this as a built-in forall/2. Personally, I prefer to use \+ in this case because the \+ is a bit clearer that the construct does not leave a binding.

Failure-slice. For diagnostic purposes it is often useful to add on purpose false into your programs. See for more details.

于 2013-01-29T13:30:12.997 に答える
3

1つのケース(Eclipseを使用した制約論理プログラミングから取得)は、not/1の実装です。

:- op(900, fy, not).
not Q :- Q, !, fail.
not _ .

Qが成功した場合、カット(!)により2番目のnot句が破棄され、失敗すると否定的な結果が保証されます。Qが失敗した場合、2番目のnot句が最初に起動します。

于 2010-06-08T22:53:04.300 に答える
3

fail のもう 1 つの用途は、副作用のある述語を使用する場合に代替手段を介してバックトラックを強制することです。

writeall(X) :- member(A,X), write(A), fail.
writeall(_).

ただし、これが特に優れたプログラミング スタイルであるとは考えない人もいるかもしれません。:)

于 2010-06-09T22:04:25.117 に答える