Prolog control constructs
Author: Daniel Diaz
Keywords: GNU Prolog, manual, Prolog, compiler, constraints, finite domains

### 7.2 Prolog control constructs

- true/0, fail/0, !/0
- (’,’)/2 - conjunction, (;)/2 - disjunction, (->)/2 - if-then, (*->)/2 - soft-cut (soft if-then)
- call/1
- catch/3, throw/1

GNU Prolog follows the ISO notion of control constructs.

#### 7.2.1 true/0, fail/0, !/0

Templates

  true
  fail
  !

Description

true always succeeds.

fail always fails (enforces backtracking).

! always succeeds and the for side-effect of removing all choice-points created since the invocation of the predicate activating it.

Errors

None.

Portability

ISO control constructs.

#### 7.2.2 (’,’)/2 - conjunction, (;)/2 - disjunction, (->)/2 - if-then, (*->)/2 - soft-cut (soft if-then)

Templates

  ’,’(+callable_term, +callable_term)
  ;(+callable_term, +callable_term)
  ->(+callable_term, +callable_term)
  *->(+callable_term, +callable_term)

Description

Goal1 , Goal2 executes Goal1 and, in case of success, executes Goal2.

Goal1 ; Goal2 first creates a choice-point and executes Goal1. On backtracking Goal2 is executed.

Goal1 -> Goal2 first executes Goal1 and, in case of success, removes all choice-points created by Goal1 and executes Goal2. This control construct acts like an if-then (Goal1 is the test part and Goal2 the then part). Note that if Goal1 fails ->/2 fails also. ->/2 is often combined with ;/2 to define an if-then-else as follows: Goal1 -> Goal2 ; Goal3. Note that Goal1 -> Goal2 is the first argument of the (;)/2 and Goal3 (the else part) is the second argument. Such an if-then-else control construct first creates a choice-point for the else-part (intuitively associated with ;/2) and then executes Goal1. In case of success, all choice-points created by Goal1 together with the choice-point for the else-part are removed and Goal2 is executed. If Goal1 fails then Goal3 is executed.

Goal1 *-> Goal2 ; Goal3 implements the so-called soft-cut. It acts as the above if-then-else except that if Goal1 succeeds only Goal3 is cut (the alternative solutions of Goal1 are preserved and can be found by backtracking). Note that Goal1 *-> Goal2 alone (i.e. without an else branch Goal3) is equivalent to (Goal1 , Goal2).

’,’, ;, -> and *-> are predefined infix operators (section 8.14.10).

Errors

Goal1 or Goal2 is a variable |  | instantiation_error
Goal1 is neither a variable nor a callable term |  | type_error(callable, Goal1)
Goal2 is neither a variable nor a callable term |  | type_error(callable, Goal2)
The predicate indicator Pred of Goal1 or Goal2 does not correspond to an existing procedure and the value of the unknown Prolog flag is error (section 8.22.1) |  | existence_error(procedure, Pred)

Portability

ISO control constructs except (*->)/2 which is GNU Prolog specific.

#### 7.2.3 call/1

Templates

  call(+callable_term)

Description

call(Goal) executes Goal. call/1 succeeds if Goal represents a goal which is true. When Goal contains a cut symbol ! (section 7.2.1) as a subgoal, the effect of ! does not extend outside Goal.

Errors

Goal is a variable |  | instantiation_error
Goal is neither a variable nor a callable term |  | type_error(callable, Goal)
The predicate indicator Pred of Goal does not correspond to an existing procedure and the value of the unknown Prolog flag is error (section 8.22.1) |  | existence_error(procedure, Pred)

Portability

ISO control construct.

#### 7.2.4 catch/3, throw/1

Templates

  catch(?callable_term, ?term, ?term)
  throw(+nonvar)

Description

catch(Goal, Catcher, Recovery) is similar to call(Goal) (section 7.2.3). If this succeeds or fails, so does the call to catch/3. If however, during the execution of Goal, there is a call to throw(Ball), the current flow of control is interrupted, and control returns to a call of catch/3 that is being executed. This can happen in one of two ways:

- implicitly, when an error condition for a built-in predicate is satisfied.
- explicitly, when the program executes a call of throw/1 because the program wishes to abandon the current processing, and instead to take an alternative action.

throw(Ball) causes the normal flow of control to be transferred back to an existing call of catch/3. When a call to throw(Ball) happens, Ball is copied and the stack is unwound back to the call to catch/3, whereupon the copy of Ball is unified with Catcher. If this unification succeeds, then catch/3 executes the goal Recovery using call/1 (section 7.2.3) in order to determine the success or failure of catch/3. Otherwise, in case the unification fails, the stack keeps unwinding, looking for an earlier invocation of catch/3. Ball may be any non-variable term.

Errors

Ball is a variable |  | instantiation_error

If Ball does not unify with the Catcher argument of any call of catch/3, a system error message is displayed and throw/1 fails.

When catch/3 calls Goal or Recovery it uses call/1 (section 7.2.3), an instantiation_error, a type_error or an existence_error can then occur depending on Goal or Recovery.

Portability

ISO control constructs.

Copyright (C) 1999-2021 Daniel Diaz Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved. More about the copyright