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

.

Prec. | Type | Operator |
---|---|---|

1200 | xfx | -->, :- |

1200 | fx | :-, ?- |

1150 | fx | dynamic, discontiguous, initialization, module_transparent, multifile, thread_local, volatile |

1100 | xfy | ;, | |

1050 | xfy | ->, op*-> |

1000 | xfy | , |

954 | xfy | \ |

900 | fy | \+ |

900 | fx | ~ |

700 | xfx | <, =, =.., =@=, =:=, =<, ==, =\=, >, >=, @<, @=<, @>, @>=, \=, \==, is |

600 | xfy | : |

500 | yfx | +, -, /\, \/, xor |

500 | fx | +, -, ?, \ |

400 | yfx | *, /, //, rdiv, <<, >>, mod, rem |

200 | xfx | ** |

200 | xfy | ^ |

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

Bill Wilson's contact info

Last updated: