!/0
Module: builtins
!/0
— (cut) removes choicepoints
FORMS
FirstGoal, !, SecondGoal
FirstGoal, !; SecondGoal
DESCRIPTION
Discards all choicepoints made since the parent goal started execution, including the choicepoints, if any, created by calling the parent goal. In the following two cases, a cut in Condition
will remove all choicepoints created by the Condition
, any subgoals to the left of the Condition
, and the choicepoint for the parent goal.
Condition = (Things, !, MoreThings)
Condition -> TrueGoal; FalseGoal
call(Condition)
In other words,
->
call/1
;
:
,
are all transparent to cut. The ISO Prolog Standard requires that call/1
be opaque to cut. At this time, ALS Prolog deviates from the standard.
EXAMPLES
In the following example, the solution eats(chris, pizza) causes a cut to be executed. This removes the choicepoint for the goal eats/2
. As a result, the solution eats(mick, pizza) is not found, even though Mick will eat anything.
?- listing.
eats(chris,pizza):-!.
eats(mick,Anything).
yes.
?- eats(Person,pizza).
Person=chris;
no.
The next example shows that not/1
is opaque to cut. This means that a ‘!’ inside the call to not/1
will not cut out the choicepoint for not/1
, or any other choicepoints created by goals to the left of not/1
.
?- not((!,fail)).
yes.
Notice the extra pair of parentheses above. This is to prevent the parser from creating a goal to not/2
instead of not/1
. In the next example, the transparency of call/1
with respect to cut is shown:
?- listing.
cool(peewee):-call((!,fail)).
cool(X).
yes.
?- cool(peewee).
no.
?- cool(bugsbunny).
yes.
peewee
is not cool because the '!'
removed the choicepoint for cool/1
. The fail
after the '!'
prevented cool/1
from succeeding. The rationale for having cut behave this way is so that:
cool(peewee) :- call(( !,fail)).
will be equivalent to
cool(peewee) :- !, fail.
The next example shows the transparency of -> with respect to cut.
?- listing.
cool(X):-(X=peewee,!)->fail.
cool(X).
yes.
?- cool(peewee).
no.
Again, peewee is not considered cool. In the goal
?- cool(peewee).
no.
the '!'
after X = peewee
cuts the choicepoint for cool/1
. The condition succeeds, causing fail to be executed. However, the second clause is never reached because the choicepoint has been cut away. Consequently, the goal fails. The goal
?- cool(daffyduck).
yes.
succeeds because the ‘!’ is never reached in the condition of ->. The -> fails because there is no else subgoal. This causes the next clause for cool/1
to be executed. This clause always succeeds, therefore daffyduck
is considered cool.