1

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, !.    
false
  • 10,264
  • 13
  • 101
  • 209
sai_varshittha
  • 193
  • 1
  • 12

1 Answers1

1

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.

David Tonhofer
  • 14,559
  • 5
  • 55
  • 51
  • is not(p) used as a procedure here or else as a keyword? and what do you mean by sucess and failure of call to p ?(the bold highlighted ones) – sai_varshittha Jun 11 '20 at 15:24
  • @sai_varshittha. `not(P)` is a predicate - you call it, passing it some term `P`. If `P` later appears in a clause at predicate position (generally in between `,`, as here, instead of enclosed by a function symbol as in `f(P)`) Prolog regards it a an expression to be executed. For example, `not(member(1,[1,2])` will result in a call to `member(1,[1,2])`, which succeeds. `not(false)` will result in a call to `false`, which fails. `not(foo)` will result in a call to `foo`, which is not defined as a predicate and cause an exception. – David Tonhofer Jun 11 '20 at 15:32
  • I am getting the following results , `?- not(member(1,[1,2])). false.` `?- not(false). false.` `?- not(true). false.` So is the result always false? And why is it so? – sai_varshittha Jun 11 '20 at 16:21