Overview

Operators in Prolog are simply a notational convenience. For example, + is an infix operator, so

     2 + 1
     

is an alternative way of writing the term +(2, 1). That is, 2 + 1 represents the data structure

                +
              /   \
             2     1
     

and not the number 3. (The addition would only be performed if the structure were passed as an argument to an appropriate procedure, such as is/2; see ref-ari-eae.)

Prolog syntax allows operators of three kinds: infix, prefix, and postfix. An infix operator appears between its two arguments, while a prefix operator precedes its single argument and a postfix operator follows its single argument.

Each operator has a precedence, which is a number from 1 to 1200. The precedence is used to disambiguate expressions in which the structure of the term denoted is not made explicit through the use of parentheses. The general rule is that the operator with the highest precedence is the principal functor. Thus if + has a higher precedence than /, then

     a+b/c     a+(b/c)
     

are equivalent, and denote the term +(a,/(b,c)). Note that the infix form of the term /(+(a,b),c) must be written with explicit parentheses:

     (a+b)/c
     

If there are two operators in the expression having the same highest precedence, the ambiguity must be resolved from the types of the operators. The possible types for an infix operator are

Operators of type xfx are not associative: it is required that both of the arguments of the operator be subexpressions of lower precedence than the operator itself; that is, the principal functor of each subexpression must be of lower precedence, unless the subexpression is written in parentheses (which gives it zero precedence).

Operators of type xfy are right-associative: only the first (left-hand) subexpression must be of lower precedence; the right-hand subexpression can be of the same precedence as the main operator. Left-associative operators (type yfx) are the other way around.

An atom named Name is declared as an operator of type Type and precedence Precedence by the command

     :-op(Precedence, Type, Name).
     

An operator declaration can be cancelled by redeclaring the Name with the same Type, but Precedence 0.

The argument Name can also be a list of names of operators of the same type and precedence.

It is possible to have more than one operator of the same name, so long as they are of different kinds: infix, prefix, or postfix. An operator of any kind may be redefined by a new declaration of the same kind. Declarations for all these built-in operators can be found in ref-syn-ops-bop.

For example, the built-in operators + and - are as if they had been declared by (A) so that (B) is valid syntax, and means (C) or pictorially (D).

     :-op(500, yfx, [+,-]). (A)
     
     a-b+c (B)
     
     (a-b)+c (C)
     
                  +
                /   \
               -     c
              / \
             a   b (D)
     

The list functor ./2 is not a standard operator, but we could declare it to be (E) then (F) would represent the structure (G).

     :-op(600, xfy, .). (E)
     
     a.b.c (F)
     
                .
               / \
              a   .
                 / \
                b   c (G)
     

Contrasting this with the diagram above for a-b+c shows the difference between yfx operators where the tree grows to the left, and xfy operators where it grows to the right. The tree cannot grow at all for xfx operators; it is simply illegal to combine xfx operators having equal precedences in this way.

The possible types for a prefix operator are:

and for a postfix operator they are:

     xf
     
     yf
     

If these precedence and associativity rules seem rather complex, remember that you can always use parentheses when in any doubt.