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