Exclamation mark in Prolog

JAN picture JAN · Feb 25, 2013 · Viewed 26.2k times · Source

Given the following facts and predicates:

sound(time1).
sound(time2).
sun(time3).
relax(X):-sound(X),!,sun(X).
relax(_):-sun(_).

When executing relax(S). I'd expect to get S=time1 due to the !, that says (correct me if I'm wrong), that if 'X' is satisfied , then stop the backtracking.

Here is the trace:

3 ?- trace.
true.

[trace] 3 ?- relax(S).
   Call: (6) relax(_G1831) ? creep
   Call: (7) sound(_G1831) ? creep
   Exit: (7) sound(time1) ? creep
   Call: (7) sun(time1) ? creep
   Fail: (7) sun(time1) ? creep
   Fail: (6) relax(_G1831) ? creep
false.

So why does Prolog also checks sun(time1), even though that it met the exclamation mark after being satisfied by sound(X) (because sound(time1) is a fact).

Answer

Smarty77 picture Smarty77 · Apr 3, 2016

To clarify this even more, if somebody still struggles how exclamation operator works (like i did), here is an example:

sound(time3).
sound(time1).
sun(time1).
relax(X):-sound(X),!,sun(X).

For this certain example, if you ask Prolog for ?-relax(S). this results into false. We can describe Prolog working like this:

  1. Prolog searches for asked predicate (relax(SOMEVARIABLE unifiable with S)) in our example).
  2. Prolog finds predicate relax(X). Variables X and S are now bound.
  3. Prolog starts to evaluate clauses:
    • sound(X)
      • Prolog searches the file for fact which satisfies sound(X).
      • it finds the fact sound(time3). and unifies it with our variables X=S=time3.
    • !
      • Prolog continues to next clausule which is operator ! so he will not backtrack back behind this operator.
    • sun(X)
      • Prolog searches the file for the fact which satisfies sun(X). X is already bound so it searches for sun(time3) which does not exists.
  4. Conclusion
    • at this point, if there was no ! operator Prolog would return (backtrack) to sound(X) and it would reassign variable X=S as X=S=time1. Which would eventually result into true since fact sun(time1) exists.
    • Prolog returns false because he could not match relax(S) for any rule.

In opposition like I said in 4. without ! operator it results into success.

sound(time3).
sound(time1).
sun(time1).
relax(X):-sound(X),sun(X).

Feel free to correct me if I am wrong at some point.