Consider the following code:
a(X) :- b(X),!,c(X),fail.
a(X) :- d(X).
b(1).
b(4).
c(1).
c(3).
d(4).
The query a(X).
produces
1 ?- a(X).
false.
2 ?-
but with this code
a(X) :- b(X),!,c(X).
a(X) :- d(X).
b(1).
b(4).
c(1).
c(3).
d(4).
The query a(X).
results in :
1 ?- a(X).
X = 1.
So my question is, why does the fail/1
produces false? it is supposed to force backtracking, right ? then b(1)
and c(1).
would be checked, I think, so why does it fail?
it fails because fail
must fail.
The cut removes alternatives, then forbids values that otherwise would be 'returned' by means of X
binding. Try
a(X) :- b(X),c(X),fail.
...
you'll get
?- a(X).
X = 4.
example :
a(X):- b(X),!,fail. %is the same as \+ a(X):- b(X).
the merge of "!" and "fail" gives you the negative of a(X).
its called the Negation by Failure.
As @CapelliC said , the rule of a(X) :- b(X),!,c(X),fail.
must fails because he has fail
component .
At the 1st code sample - the checking starts on 1
, the component b(1)
satisfied and after that it get to !
, therefore no more optional checking would execute .
For more clarification about the cut
, you can examine putting the !
at end of a(X) :- b(X),!,c(X),fail.
like this -
a(X) :- b(X),c(X),fail,!.
a(X) :- d(X).
b(1).
b(4).
c(1).
c(3).
d(4).
And now -
?- a(X).
X = 4.
Because the fail
is before the !
so the !
is unreachable therefore the cut
does not affect and still another optional taking account .
Edit :
The fail
is relevant only for the rule he written there , so a(X) :- b(X),c(X),fail,!.
would forever causes the failure , but not the a(X) :- d(X).
rule .
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With