More control structures

## 3.7 More control structures

- Disjunction
- Conditional
- Call
- All Solutions

### 3.7.1 Disjunction

Disjunction is normally specified in Prolog by different clauses of a predicate, but it can also be specified within a single clause by the use of `;/2`. For example,

>     atomic_particle(X) :- (X = proton ; X = neutron ; X = electron).

This is logically equivalent to:

>     atomic_particle(proton).
>     atomic_particle(neutron).
>     atomic_particle(electron).

### 3.7.2 Conditional

Conditionals can be specified using the `->/2` operator. In combination with `;/2`, a conditional similar to `if-then-else' constructs of conventional language can be constructed: `X->Y;Z`, where `X`, `Y` and `Z` can be one or more goals, means that if `X` is true, then `Y` will be executed, otherwise `Z`. Only the first solution of `X` is explored, so that on backtracking, no new solutions for `X` will be tried. In addition, if `X` succeeds, then the `else' part, `Z` will never be tried. If `X` fails, then the `then' part, `Y`, will never be tried. An example of `if-then-else' is:

>     max(X,Y, Max) :-
>        number(X), number(Y),
>        (X > Y -> Max = X ; Max = Y).

where `Max` is the bigger of the numbers `X` or `Y`. Note the use of the brackets to make the scope of the if-then-else clear and correct.

### 3.7.3 Call

One feature of Prolog is the equivalence of programs and data – both are represented as terms. The predicate `call` allows program terms (i.e. data) to be treated as goals: `call(X)` will cause `X` to be treated as a goal and executed. Although at the time when the predicate is executed, `X` has to be instantiated, it does not need to be instantiated (or even known) at compile time. For example, it would in principle be possible to define disjunction (`;`) as follows:

>     X ; Y :- call(X).
>     X ; Y :- call(Y).

### 3.7.4 All Solutions

In the pure computational model of Prolog, alternative solutions are computed one-by-one on backtracking. Only one solution is available at any time, while previous solutions disappear on backtracking:

>     ?- weekday(X).
>     X = mo
>     More
>     X = tu
>     More
>     X = we
>     More
>     ...

Sometimes it is useful to have all solution together in a list. This can be achieved by using one of the all-solutions predicates findall/3, setof/3 or bagof/3:

>     ?- findall(X, weekday(X), List).
>     X = X
>     List = [mo, tu, we, th, fr, sa, su]
>     Yes

⊙
  For the differences between findall/3, setof/3 and bagof/3 see the ECLiPSe Reference Manual.