!/0 — (cut) removes choicepoints
FirstGoal, !, SecondGoal FirstGoal, !; SecondGoal
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,
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.
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((!,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
fail after the
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.
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.