Conditionals and Disjunction

There is an efficiency advantage in using conditionals whose test part consists only of arithmetic comparisons or type tests. Consider the following alternative definitions of the predicate type_of_character/2. In the first definition, four clauses are used to group characters on the basis of arithmetic comparisons.

     type_of_character(Ch, Type) :-
             Ch >= "a", Ch =< "z",
             !,
             Type = lowercase.
     type_of_character(Ch, Type) :-
             Ch >= "A", Ch =< "Z",
             !,
             Type = uppercase.
     type_of_character(Ch, Type) :-
             Ch >= "0", Ch =< "9",
             !,
             Type = digit.
     type_of_character(_Ch, Type) :-
             Type = other.
     

In the second definition, a single clause with a conditional is used. The compiler generates equivalent, optimized code for both versions.

     type_of_character(Ch, Type) :-
             (   Ch >= "a", Ch =< "z" ->
                     Type = lowercase
             ;   Ch >= "A", Ch =< "Z" ->
                     Type = uppercase
             ;   Ch >= "0", Ch =< "9" ->
                     Type = digit
             ;   otherwise ->
                     Type = other
             ).
     

Following is a list of built-in predicates that are compiled efficiently in conditionals:

This optimization is actually somewhat more general than what is described above. A sequence of guarded clauses:

     Head1 :- Guard1, !, Body1.
     ...
     Headm :- Guardm, !, Bodym.
     Headn :- Bodym.
     

is eligible for the same optimization, provided that the arguments of the clause heads are all unique variables and that the "guards" are simple tests as listed above.