Yfy-pattern

I’m using: SWI-Prolog version (threaded, 64 bits, version 8.0.3).

Can someone explain to me why yfy is not a meaningful pattern for precedence and position of operators?

Need help fast! Thanks.

While I am looking for an authoritative answer think about what it does? Try to explain what it does to someone and where you would use it? See the point?

Im a full on rookie in Prolog so I don’t know much about the patterns. Isn’t it true that x must be strictly lower than the precedence of the operator and y must be the same or lower than the precedence of the operator? If true, that’s the most I know about it. I still can’t explain to myself why yfy wouldn’t work and I can’t come up with an example. I was looking for someone wo explain it to me in layman’s terms by maybe using an example.

I could explain it but not to the point that it would make perfect sense. In other words I know it well enough to satisfy my needs but you would ask more questions about my answer that I would not be able to feel comfortable in responding, thus the reason I am searching for an authoritative answer.

That looks correct.

From the SWI-Prolog documentation for op/3

Type is one of: `xf` , `yf` , `xfx` , `xfy` , `yfx` , `fy` or `fx` . The‘ `f` ’indicates the position of the functor, while `x` and `y` indicate the position of the arguments.‘ `y` ’should be interpreted as “on this position a term with precedence lower or equal to the precedence of the functor should occur’’. For‘ `x` ’the precedence of the argument must be strictly lower. 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 parentheses `( ... )` has precedence 0.

Thank you for your answer! I will stick around and wait for an authoritative answer from whoever it may come.

That was not meant to be an answer, just letting you know you are on the right track.

Here is an authoritative answer (ref - see page 8), but it will leave you with questions if you don’t work through some exercises to understand why. Still looking for a better answer.

Here is another reference with a bit more of an explanation. Jacc’s LR-Parsing with Dynamic Operators

Note that yfy is not allowed as an operator specifier because that would mean an ambiguous way of parsing the operator by associating either to the left or to the right.

That is the meaning I use but it only makes sense once you work through examples. As working through the examples to make yourself satisfied you do understand it can take hours and I don’t have the necessary examples on hand I will be stopping to seek a better answer at this point.

However one thing that will be of value in working the examples is using write_canonical/1 as noted by @CapelliC in his StackOverflow answer.

1 Like

Yeah it was more like thank you for answering to my topic :).

I understand that it is impossible to use but I do have more questions now yes .

Jacc looks interesting, as well the ‘trick’ Hassan explained.
Thanks

I can’t find what you are referring to.

You’re right, I was referring to shalllow backtracking, but it seems to be an extension of LALR parsing carefully implemented in Jacc, not a ‘trick’ that could be implemented in YACC. Sorry…

If `yfy` were allowed, and you could define `op(500, yfy, myop)`, then `a myop b mypo c` could be parsed as either `myop(a, myop(b,c))` or `myop(myop(a, b), c)`. To avoid this ambiguity, `yfy` is not allowed.
However, `fy` and `yf` are allowed. Exercise for the reader: what should this do:

``````?- op(500, fy, myop).
?- op(500, yf, myop2).
?- X = myop a myop2, write_canonical(X).
``````
2 Likes