Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cut and Fail in Prolog

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?

like image 384
JAN Avatar asked Feb 28 '13 15:02

JAN


3 Answers

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.
like image 50
CapelliC Avatar answered Nov 13 '22 08:11

CapelliC


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.

like image 3
Z.D.E Informaticien Avatar answered Nov 13 '22 08:11

Z.D.E Informaticien


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 .

like image 1
URL87 Avatar answered Nov 13 '22 09:11

URL87