For languages such as Java and C which allow syntactic sugar with operators, i.e. infix, they use precedence and associativity.
Prolog also uses associativity:
left-associative - yfx
right-associative - xfy
but why is there xfx?
The only thing I have found on the internet giving any more clarity is
xfx means that the operator 'dominates' upon its branches, while xfy or yfx stand for 'list construction', in sense that allow chaining expressions of same priority.
from: Interpretation of Prolog's operator in an exercise by CapelliC
If the answer can include examples where xfx is needed because xfy and yfx fail/don't have meaning, that would be appreciated.
For Prolog reference: The Prolog Built-in Directive op
As false notes:
Please note that the operators you give in above link differ from both the standard and SWI! They are outdated by at least 10 years. As an example, it should be
current_op(200,fy,-)
.
After reading the two current answers by CapelliC and false it became clear that non-associative was the key word to locating more relevant information. So Operator associativity now make more sense with regards to xfx when paying attention to non-associative section.
The specifier of an operator denotes the class (prefix, infix, postfix) and associativity of an operator.
xfx
means that the operator does not permit any form of associativity. In other words: it does not nest with operators of the same priority. However, it does still nest with operators of a lower priority.
The largest part of such operators are predicates of arity two that are used for comparison-like meaning and where nesting would have - at least - an entirely different meaning than what the predicate is about. They are all located at priority 700: High enough to allow all arithmetic operators to work without bracketing ; low enough to work with control constructs and related meta-predicates that expect goals as arguments. Think of (\+)/1
, (;)/2
, (',')/2
.
Consider =<
: If you want to state that X
is between 1 and 3 you cannot write 1 =< X =< 3
because neither (1 =< X) =< 3
nor 1 =< (X =< 3)
make sense in Prolog. In fact, both would lead to an evaluation error. You have to write 1 =< X, X =< 3
. which means =<(1, X), =<(X, 3)
.
For some cases it might make sense to nest, think of (A = B) = P
. Here, the first =
is just a functor like any other of arity 2, while the second =
is the built-in predicate (=)/2
for equality/unification. But such cases are rare and it is worth highlighting them with an extra pair of round brackets.
Note also that :- :- a.
is invalid syntax, because (:-)/1
again does not nest.
Arithmetic operators are typically left associative since you process them left-to-right like 1+2+4
, first computing 1+2
and only then adding 4
. The notable exception is (^)/2
: This is so, because (X^Y)^Z =:= X^(Y*Z)
whereas (X^(Y^Z))
denotes a term that cannot be expressed with simpler operators.
For instance, (:-)/2 it's clearly an operator that can used only once, because it separates the head from the body.
The separation is 'relative', you could have in a rule, for instance
my_rule :- assertz((a :- b, c)).
Here is the full list of (default) xfx operators from SWI-Prolog
?- setof((X,Y), current_op(X,xfx,Y), L), maplist(writeln, L).
200, (**)
700, (<)
700, (=)
700, (=..)
700, (=:=)
700, (=<)
700, (==)
700, (=@=)
700, (=\=)
700, (>)
700, (>=)
700, (@<)
700, (@=<)
700, (@>)
700, (@>=)
700, (\=)
700, (\==)
700, (\=@=)
700, (as)
700, (is)
1200, (-->)
1200, (:-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With