HANDBOOK / GENTLE PRIMER / Control Structures /

# The Alternative Statement

Assume that we wish to process the maximum of two values by applying a predicate `process` to one of the values. Defining a predicate `processmax`, we can write

       'action' processmax(INT, INT -> INT)
          'rule' processmax(X, Y -> Z): ge(X, Y) process(X -> Z)
          'rule' processmax(X, Y -> Z): lt(X, Y) process(Y -> Z)

and invoke it as in

       get(-> A, B)
       processmax(A, B -> C)
       print(C)

The alternative statement discussed in this section allows us to insert the two rule bodies inline and get rid of the predicate `processmax`:

       get(-> A, B)
       (|
          ge(A, B) process(A -> C)
       ||
          lt(A, B) process(B -> C)
       |)
       print(C)

An alternative statement has the form

- `(|` A1 `||` A2 `||` ... `||` An `|)`

where the Ai are called alternatives and have the same form as a rule body (i.e. an alternative is a sequence of statements).

The alternative statement is elaborated as follows. The alternatives are elaborated in the given order. If an alternative succeeds, then the alternative statement succeeds. If an alternative fails then the next alternative is elaborated. If all alternatives fail, then the whole alternative statement fails.

An alternative is elaborated by elaborating its statements. If one statement fails, then the alternative fails. If all statements succeed, then the alternative succeeds.

Roughly speaking, members of an alternative are connected by and, and alternatives are connected by or, but since we use shallow backtracking, inside an alternative one can assume that the preceding alternatives failed.

Thus the above could have been written as

       get(-> A, B)
       (| ge(A, B) process(A -> C) || process(B -> C) |)
       print(C)