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).