7

次のコードを検討してください。

a(X) :- b(X),!,c(X),fail.
a(X) :- d(X).

b(1).
b(4).
c(1).
c(3).

d(4).

クエリa(X).は生成します

1 ?- a(X).
false.

2 ?-

しかし、このコードで

a(X) :- b(X),!,c(X).
a(X) :- d(X).

b(1).
b(4).
c(1).
c(3).

d(4).

クエリのa(X).結果は次のとおりです。

1 ?- a(X).
X = 1.

だから私の質問は、なぜfail/1生成がfalseになるのですか? バックトラックを強制するはずですよね?次にb(1)c(1).チェックされると思いますが、なぜ失敗するのですか?

4

4 に答える 4

3

fail 失敗する必要があるため、失敗します。

カットは代替を削除し、そうでなければXバインディングによって「返される」値を禁止します。試す

a(X) :- b(X),c(X),fail.
...

あなたが得るでしょう

?- a(X).
X = 4.
于 2013-02-28T15:12:14.117 に答える
1

@CapelliC が言ったように、コンポーネントがあるため、 a(X) :- b(X),!,c(X),fail. mustのルールは失敗しfailます。

最初のコード サンプルでは、​​チェックが開始され1、コンポーネントb(1)が満たされ、その後に到達する!ため、オプションのチェックは実行されません。

についてさらに明確にするために、を最後にcut 置くことを調べることができます!a(X) :- b(X),!,c(X),fail.

このような -

a(X) :- b(X),c(X),fail,!.
a(X) :- d(X).

b(1).
b(4).
c(1).
c(3).

d(4).

そしていま -

?- a(X).
X = 4.

failは の前にあるため!到達できないため、!は影響を受けず、さらに別のオプションのアカウントを考慮します。 cut

編集 :

彼がそこに書いたfailルールにのみ関連するので、a(X) :- b(X),c(X),fail,!.永遠に失敗を引き起こしますが、ルールはそうではありませんa(X) :- d(X).

于 2013-02-28T17:15:50.087 に答える