The Prolog Built-in Directive `op`

Reference: Bratko, pages 74-80

`:- op(+Precedence, +Type, :Name)`

The Prolog built-in predicate `op` serves to define the Type and Precedence of infix and postfix, and prefix operators in Prolog terms. Prolog terms normal begin with the functor (e.g. `likes`, in `likes(mary, pizza)`) but exceptions exist - for example, arithmetic expressions are written in the usual infix way (i.e. as `X + 1`, rather than `+(X, 1)`), and negation can be written without parentheses, as a prefix operator: `not P`.

The table below lists the predefined infix operators in SWI-Prolog. You may wish to add infix operators of your own. For example, you might wish to define an infix `and`. This can be done as follows:

`:- op(700, xfy, and).`

This declares `and` to be an operator with precedence 700 and type `xfy`.

Note two things: (1) the fact that these things are referred two as operators does not mean that an operation is performed when they are encountered. This is not usually the case; and (2) the declaration of an operator only affects the external appearance of the operator in your program - internally, the standard representation is used - for example `X + 1` really is internally represented by Prolog as `+(X, 1)`.

`Precedence` is an integer between 0 and 1200. `Precedence` 0 removes the declaration. `Type` is one of: `xf`, `yf`, `xfx`, `xfy`, `yfx`, `yfy`, `fy` or `fx`. The `f` indicates the position of the functor, while `x` and `y` indicate the position of the arguments. Thus `xfx`, `xfy`, and `yfx` all indicate an infix operator. `y` should be interpreted as "in this position a term with precedence equal to or less than the precedence of the functor should occur". For `x` the precedence of the argument must be strictly less than that of the functor. The precedence of a term is 0, unless its principal functor is an operator, in which case the precedence is the precedence of this operator. A term enclosed in brackets (...) has precedence 0.

To see how this works, consider the arithmetic expression `a - b - c`. In normal maths, this is interpreted as `(a - b) - c`, rather than `a - (b - c)`. To achieve this, the binary infix operator `-` must be declared as type `yfx` so that the first argument has precedence over the second. Then, internally, `a - b - c` will be represented as `-(-(a, b), c)` rather than `-(a, -(b, c))`.

Built-in Operators (SWI-Prolog)

Prec.TypeOperator
1200xfx-->, :-
1200 fx:-, ?-
1150 fxdynamic, discontiguous, initialization, module_transparent, multifile, thread_local, volatile
1100xfy;, |
1050xfy->, op*->
1000xfy,
954xfy\
900 fy\+
900 fx~
700xfx<, =, =.., =@=, =:=, =<, ==, =\=, >, >=, @<, @=<, @>, @>=, \=, \==, is
600xfy:
500 yfx+, -, /\, \/, xor
500 fx+, -, ?, \
400 yfx*, /, //, rdiv, <<, >>, mod, rem
200xfx**
200xfy^

Note that all operators can be redefined by the user, most commonly accidentally and with disastrous results.

Bill Wilson's contact info
Last updated: