You have already encountered the concept of an operator several
times.
The Prolog clause and term delimiters, `:- , . ; -> ( )`

are all
operators.
We can write terms such as `predicate(Argt1,Argt2,....)`

, and
combine them into clauses because the Prolog interpreter and compiler
recognise the operators and use them to rewrite the file.

You have also encountered the use of an operator in the place of a
functor in
unit Difference Lists and Definite Clause Grammars.
The DCG-operator `-->`

is used an recognised as the main
component of a rule, but we could just as well have written

`rule(s, np, vp).`

and made the DCG-interpreter recognise `-->`

.
As shown by the DCG-example, the operator notation is
essentially equivalent to the normal predicate-argument notation (the
only difference is that you can tell Prolog a little bit more
about how the arguments are related).
The point of using an operator as opposed to a functor is usually to
make the program more readable.
The drawback is that Prolog recognises the functor notation as is,
whereas operators have to be declared specifically.
If you forget to do so, there will be error messages when the program
is loaded.
You declare an operator as follows: first in the file must be something
that Prolog executes automatically and tells it that the operator
exist.
You achieve this by writing it as a goal without a head (meaning
"always make this true").
The goal calls a built in predicate `op/3`

which tells
Prolog to accept the operator by telling it what it needs to know
about it:
what is precedence is, its type, and what it looks like.

To understand how these work, it is helpful to look at the values for the
predefined operators. The procedure `current_op/3`

may be called
to inspect
these, and its arguments are the same of those of
`op/3`

.
The section Predefined Operators
gives a listing of the predefined operators in SICStus
Prolog.

The **precedence** of an operator determines the structure of a
term containing several operators. The lower the precedence, the
tighter an operator binds its arguments.
An operator with a low precedence value will thus be dealt with first
insofar as evaluation is concerned.
Operators which delimit rules, and determine the overall structure of
the program have high precedence values.
To make sure that everything from one full stop to the next is deal
with as a single clause, the full stop has the highest precedence.
For instance, the precedence of
`*`

is `400`

, while
that of `+`

is `500`

. Hence

would bindX is 5 + 3 * 4

`X`

to 17, not 32.
Note how the ``:-`

' and ``?-`

' have the
highest precedences of the operators we have met so far, and comma the
next.
The **position** and **associativity** is given by one of the
following type specifiers:

`xfx`

`xfy`

`yfx`

binary infix operators`fx`

`fy`

unary prefix operators`xf`

`yf`

unary postfix operators

`f`

in the specifier thus determines the position of
the operator in a term; the `x`

and `y`

represent the arguments.
The precedence of an argument is 0 if it is enclosed in brackets or it
is an unstructured object; otherwise it is the precedence of the
principal functor of the argument. `x`

represents an argument
whose precedence is strictly lower than that of the operator, while
`y`

represents an argument whose precedence is lower than or
equal to that of the operator.

Thus, operators which are not usually iterated within an expression,
such as `=`

, `=..`

, and `is`

, are defined as
`xfx`

. Operators which may be iterated, and are intended to be
left associative, like `-`

and `+`

, are `yfx`

. Iterable
right associative operators, like the implication `->`

, are `xfy`

.
Similarly, `fy`

and `yf`

are iterable operators, `fx`

and
`xf`

are
non-iterable.

For example, since `\+`

is defined as `fy`

, we can write
`\+ \+ P`

. If it had been defined as `fx`

, then we would
have to write `\+ (\+ P)`

.

Operator Associativity Precedence`\==`

`xfx`

700`spy`

`fy`

900`,`

`xfy`

1000`-`

`yfx`

500`-`

`fx`

500`+`

`yfx`

500`+`

`fx`

500`/`

`yfx`

400`*`

`yfx`

400`;`

`xfy`

1100`=`

`xfx`

700`<`

`xfx`

700`>`

`xfx`

700`public`

`fx`

1150`is`

`xfx`

700`-->`

`xfx`

1200`mode`

`fx`

1150`^`

`xfy`

200`=..`

`xfx`

700`nospy`

`fy`

900`wait`

`fx`

1150`//`

`yfx`

400`->`

`xfy`

1050`:-`

`xfx`

1200`:-`

`fx`

1200`multifile`

`fx`

1150`=:=`

`xfx`

700`?-`

`fx`

1200`<<`

`yfx`

400`==`

`xfx`

700`@>=`

`xfx`

700`>=`

`xfx`

700`@=<`

`xfx`

700`@<`

`xfx`

700`@>`

`xfx`

700`=<`

`xfx`

700`/\`

`yfx`

500`>>`

`yfx`

400`parallel`

`fx`

1150`\+`

`fy`

900`\/`

`yfx`

500`=\=`

`xfx`

700`dynamic`

`fx`

1150`mod`

`xfx`

300

`<a.von.klopp@bangor.ac.uk>`