We use the Prolog notation for operator declarations even though, unlike Prolog, QuLog’s syntax cannot be extended by adding application specific operators and the QuLog parser is not an operator precedence parser.
op is not a system predicate of QuLog. Using Prolog
op statements gives us a succint way of summarising the precedence
relationship between the operators that is implicit in the formal syntax rules.
op statement the number is the ’binding’ power of the operator, called the precedece of the operator. The higher the precedence, the higher up the parse tree, so the less binding the operator. For example,
+ has higher precedence than
* , so
X+Y*Z is really
X+(Y*Z) and we have to use brackets if we want to have the expression
fx means the operator is prefix and cannot be followed immediately by an expression with top operator of the same precedence unless that expression is bracketed.
xfx means that the operator is an infix non-associative operator and must have expression arguments for which the top operator has lower precedence, or the expressions arguments are bracketed. So,
(X**Y)**Z needs the brackets.
xfy means that the operator is an infix right associative operator, and
yfx means that the operator is an infix left associative operator. More specically, a
xfy operator can have an expression to the right with a top operator of equal or lower precedence and that expression being implicitly bracketed. For a
yfx this implicit bracketing applies to the expression on the left hand side. So,
X*5 mod 6 is implicitly
(X*5) mod 6.
? has two precedences as an infix operator. One is for its use in an interpreter query after the required initial number of solutions and/or variable bindings have been given. For this use it must have higher precedence than
&. The second use is in
++ patterns when giving a single condition constraint on a sub-string or sub-list. For this use it must have lower precedence than
The mode annotations are not in the table as prefix or infix operators as they will always be inside a bracketed sequence of annotated types.
We have not included
exists as they are both prefix operators taking two arguments, the sequence of variables that immediately follows and then some operator expression. This is an
~>> implication in the case of
forall and possibly an
& conjunction in the case of
start_agent are just reserved words and are never followed by an operator expression.
In QuLog comma is not treated as an operator. It is just an expression separator.
op(1100, xfx, [ <=, ~>>, ->, ~>, =>]) op(1050, xfx, [ ::= ]) op(1030, xfx, [ |, || ]) op(1030, xfx, [ .. ]) op(1020, xfx, [ ::, ? ]) <op(1020, xfy, [ while, until ]) op(1000, xfy, [ &, ; ]) op(900, fx, [not , once, watch , watchC, unwatch, show, types, stypes, remember, forget, call, do, wait]) op(850, xfx, [ for, after ]) op(800, xfx, [ ? ]) op(700, xfx, [= , \= , :=, +:=, -:=, =? , == , \== , @< , @=< , @> , @>= , @.. , in , =:= , =\= , < , =< , > , >= ]) op(600, xfy, [ ++, <> ]) op(550, xfx, [ ? ]) op(500, yfx, [ + , - , /\ , \/, union, diff ]) op(450, yfx, [ to, from ]) op(400, yfx, [ * , / , // , rem , mod , inter, << , >> ]) op(200, xfx, [ ** ]) op(200, fy, [ + , - , \ ]) op(100, xfx, [ .. ]) op(50, xfx, [ : ]) op(50, fx, [ $, # ])