Prolog control constructs

### 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-2012 Daniel Diaz Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved. More about the copyright