!/0

Module: builtins

!/0 — (cut) removes choicepoints

ISO Standard Predicate

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.

SEE ALSO