As we have seen, the goals in the body of a sentence are linked
by the operator ,
, which can be interpreted as conjunction (and
).
It is sometimes convenient to use an additional operator |
, standing
for disjunction (or
). (The precedence of |
is such that it
dominates ,
but is dominated by :-
.) An example is the clause (A), which can be read as (B).
grandfather(X, Z) :- ( mother(X, Y) | father(X, Y) ), father(Y, Z). (A)
``For any X, Y, and Z, X has Z as a grandfather if either the mother of X is Y or the father of X is Y, and the father of Y is Z.'' (B)
Such uses of disjunction can usually be eliminated by defining an extra predicate. For instance, (A) is equivalent to (C)
grandfather(X, Z) :- parent(X, Y), father(Y, Z). parent(X, Y) :- mother(X, Y). parent(X, Y) :- father(X, Y). (C)
Therefore, disjunction will not be mentioned further in the following more formal description of the semantics of clauses.
For historical reasons, the token |
, when used outside a list, is
actually an alias for ;
. The aliasing is performed when terms
are read in, so that (D) is read as if it were (E) thus you can use
;
instead of |
for disjunction if you like.
a :- b | c. (D)
a :- b ; c. (E)
Note the double use of the .
character. Here it is used as
a sentence terminator, while in other instances it may be used in a string of
symbols that make up an atom (for example, the list functor .
). The
rule used to disambiguate terms is that a .
followed by a
layout-character is regarded as the sentence
terminator full-stop
, where a
layout-character is defined to be any character less than or equal to ASCII 32
(this includes space, tab, newline, and all control characters).