<< >> Up Title Contents

3.3. Cut

One very important, and very tricky, predicate is the 'cut', written !. This is quite dangerous in inexperienced hands (such as yours!). It is an instruction to Prolog not to back-track looking for other solutions. Here is an example:

In dealing with data-base Prolog, we discovered that the correct definition of brother/2 and sister/2 require a test for inequality:

sister(X,Y):-
	female(X),
	parent(P, X),
	parent(P, Y),
	different(X,Y).

We know how to check that two terms are the same (by unification, using =/2), but how do we check that they are different? In principle by checking that they do NOT unify. In fact, Prolog has a built-in predicate \+/1 which allows this to be done:[6]

e.g.

| ?- \+ a=b.
yes

So different/2 could be programmed as:

different(X, Y):-
	\+ X=Y.

The interesting thing from the present perspective is how \+/1 itself is programmed. The standard definition is this:

\+ X:- X, !, fail.
\+ X.

These clauses MUST occur in this order, if the definition is to work. When \+ term is called, X is instantiated to term, and the first call in the body of the first clause of \+/1 tests to see if term is true. If it is known to the Prolog data-base, this call will succeed and control will pass to !/0 ('cut'). Cut always succeeds, so control passes to the built-in predicate fail/0. fail/0 always fails. (Surprise, surprise.)

Normally, when a goal fails, Prolog backtracks to see if there are any alternative solutions. Here, to see if term has any more solutions. It will then repeat the procedure until all the possibilities have been exhausted, at which point control would pass to the second clause of \+/1, which (since it has no conditions) would succeed.

However, the presence of the cut in the first clause prevents this behaviour. Instead, when the call to cut has succeeded, Prolog cuts away all the information about alternative choices before the cut. Therefore, when fail/0 is encountered, there is nowhere else to go and the call \+ term fails straightaway.

The only situation in which the second clause will be reached is if term itself fails. This will be the case if term can't be found in the Prolog database, or proved.

So, \+ a=b will fail if a=b; and will succeed if a=b fails.

Read carefully a Prolog textbook before using the cut yourself. (Using \+/1 is OK, provided you realise that when it fails its 'meaning' is 'Prolog was unable to find a solution'. I.e. 'don't know', rather than false. This definition of negation is called 'negation by failure'.


[6] \+/1 is defined as a prefix operator, so the normal brackets are not needed (unless what you are negating is a compound expression containing conjunctions or disjunctions.



<< >> Up Title Contents