(The notation you use is extremely confusing to me, writing operators without operands, so I will stick to the standard-notation which always shows the operators plus the arguments.)
As for associativity — and this is all about it — there is a simple rule-of-thumb. Look at the y
and x
meaning Yes and No. xfy
"says" on its left side x
. So it does not "want" to associate with operators of the same priority. And on the right side, it "says" y
, thus Yes I want to associate. When there are two operators that both say yes "to each other", it is the first occurring (when reading left-to-right) which takes the second as argument. If you will, that case is handled like right associativity.
For this reason, with op(500,xfy,xfy), op(500,yfx,yfx)
we have:
Unbracketed term Equivalent bracketed term
-----------------------------------------------
1 xfy 2 xfy 3 1 xfy (2 xfy 3) ** right-associative
1 xfy 2 yfx 3 1 xfy (2 yfx 3) ** this is a special!
1 yfx 2 xfy 3 -------------- ** invalid: noone wants association
1 yfx 2 yfx 3 (1 yfx 2) yfx 3 ** left-associative
How well is that implemented? Look at this comparison starting with #147 of a similar situation. So all except SWI implement reading correctly. But for writing, there are some more systems that do not conform.
I think this clearly shows that there is rarely a situation where Prolog programmers depend on this case. In fact, the standard operator table does not have any case related to this problem.
For a real example, consider fy
and yf
intended to denote some bracket-like syntax. In fact, in pre-ISO time several systems had {
and }
defined in such a manner to be used in DCG or CLP(Q). Please note, that those two operators cannot entirely simulate "bracketing". As an example, consider
Unbracketed term Equivalent bracketed term
-----------------------------------------------
fy fy 1 yf yf fy (fy ((1 yf) yf)
On the other hand, if one has a term of the form fy( fy(X) )
(note, it is in canonical syntax!), then X
has to be either (fy)/1
or (yf)/1
. Any other term would have to be rejected.