Cut and fail semantics in Prolog

1.1k Views Asked by At

What does the following code do?

not(P) :- P, !, fail.
not(P).

And how does that work differently from the following 2 codes :

not(P) :- P, !, fail.
not(P) :- P, !.    
1

There are 1 best solutions below

3
David Tonhofer On BEST ANSWER

Here are the trees:

trees

First Program (inverses the success value of P)

If the call to P succeeds:

  1. Enter predicate not(P)
  2. Enter clause 1 of predicate not(P)
  3. Call(P) --> Success
  4. Traverse Cut
  5. Call Fail --> Failure
  6. Try to backtrack to find alternate solutions
  7. There is a Cut in the way of backtracking; exit the whole predicate with Failure (The Cut+Fail force failure of the predicate if P succeeds)

If the call to P fails:

  1. Enter predicate not(P)
  2. Enter clause 1 of predicate not(P)
  3. Call(P) --> Failure
  4. Clause 1 results in --> Failure
  5. Try alternate clause 2
  6. Call True --> Success
  7. There is nothing more to do; exit the predicate with Success

Second Program (always fails)

If the call to P succeeds:

Behaviour is exactly the same as for the First Program, exit the whole predicate with Failure.

If the call to P fails:

  1. Enter predicate not(P)
  2. Enter clause 1 of predicate not(P)
  3. Call(P) --> Failure
  4. Clause 1 results in --> Failure
  5. Try alternate clause 2
  6. Call(P) --> Failure
  7. There is nothing more to do; exit the predicate with Failure. Actually there is a cut to traverse still but it doesn't do anything.

Trying Program 1

Note that not/1 is already a built-in, but I guess we can override it for this exercise.

?- [user].
|: not(P) :- P, !, fail.
|: not(P).

Warning: user://1:9:
Warning:    Singleton variables: [P]
|: % user://1 compiled 0.02 sec, 2 clauses
true.

Okay

?- not(true).
false.

?- not(false).
true.

Looks good.

Trying Program 2

?- [user].
|: not(P) :- P, !, fail.
|: not(P) :- P, !.    
|: % user://1 compiled 0.02 sec, 2 clauses
true.

?- not(true).
false.

?- not(false).
false.

Looks good.