|
CutCut (i.e. !) is a predicate which "cuts" away nondeterminism, i.e. "cuts" away the possibility for further solutions (hence the name). The nondeterminism it cuts away can be divided into two groups (though some cuts will fall into both groups):
There are no other (sensible) uses of a cut, except for the two mentioned above. Once these purposes are understood it is easy to put cuts in the right place:
The first purpose can be illustrated by the following example: clauses p(17, X) :- X > 13, !, q(X), ... p(A, X) :- ... In this example we have a cut after the test for X > 13. this is a very typical sound use of the first reason: "Our clauses cases out on the input and now (where now is immediately after the test X > 13), we have found the right case". Such a cut is typically placed just after the head of the clause or after a test close to the head of the clause. The second purpose can be illustrated by the following example: clauses firstMember(X, L) :- member(X, L), !. In this example the cut is placed immediately after a nondeterministic predicate, of which we are only interested in a single solution. Above I have highlighted the word immediately twice, and this is because the keyword in placing cuts is immediately: they should be placed as early in the clause as possible. You should be suspicious about clauses containing more that one cut. More than one cut in a single clause often signals a programming or design error. Red and Green CutsWe do not generally encourage that cuts are turned green, it is perfectly fine with red cuts. The society of traditional Prolog, has defined the notion of red and green cuts. Briefly speaking a green cut is a cut, which does not change the semantics of the predicate in which it occurs, whereas a red one does change the semantics. Clearly all the cuts which cut away further solutions from a nondeterministic predicate are red by nature. So distinguishing between red and green cuts only has a purpose for those cuts, which prevents backtracking to next clauses. Consider the clauses: clauses p(X) :- X > 0, !, ... p(X) :- X <= 0, ... The cut in the predicate above is green, because if we remove it the predicate will behave in the same way. When the cut is present in the first clause, the test X <= 0 in the second clause is not really needed: clauses p(X) :- X > 0, !, ... p(X) :- ... Without this test the cut is, however, turned red, because now the predicate will behave different if we remove the cut. Green cuts might seem superfluous, but in fact they are used to remove superfluous backtrack points (mainly for performance reasons). In Visual Prolog they may however also be needed to "convince" the compiler that some predicate has a specific mode (e.g. procedure). |