Пролог инфиксных операторов с одинаковым приоритетом один xfy, а другой yfx с двумя последовательными операторами
В попытке понять просто инфиксные операторы типа xfy
а также yfx
с тем же приоритетом и в последовательности я вижу, что есть только четыре комбинации.
с помощью
a = xfy right-associative
b = yfx left-associative
Есть
aa e.g. 1 xfy 2 xfy 3 e.g. 1 ^ 2 ^ 3
ab e.g. 1 xfy 2 yfx 3
ba e.g. 1 yfx 2 xfy 3
bb e.g. 1 yfx 2 yfx 3 e.g. 1 - 2 - 3
Теперь для (xfy xfy) aa
операторы оба являются ассоциативными справа.
Для (YFX YFX) bb
операторы оба остаются ассоциированными.
Однако для (xfy yfx) ab
(xfy) a
оператор является ассоциативным справа и (YFX) b
Оператор остается ассоциативным. Если я правильно понимаю, Пролог оценит это следующим образом:
Используя приоритет 500
а также x
имея в виду <
а также y
имея в виду <=
xfy
500
<500 <=500
/ \
1 yfx
500
/ \
2 3
и для (yfx xfy) ba
Я бы ожидал
500
yfx
<=500 <500
/ \
xfy 3
500
/ \
1 2
но стандарт ISO Prolog гласит:
Операнд с таким же приоритетом, как у левоассоциативного оператора, который предшествует этому оператору, должен заключаться в квадратные скобки, только если главный функтор операнда является правоассоциативным оператором.
С обозначением:
Операнд (xfy)
a
с тем же приоритетом (500), что и у левоассоциативного оператора, предшествующего этому оператору (yfx)b
нужно заключать в скобки, только если главный функтор операнда (xfy)a
является правоассоциативным оператором.
Я правильно понял? Если да, то почему (xfy yfx) ab
надо заключать в скобки (yfx xfy) ba
не?
Также я искал практический пример двух операторов с одинаковым приоритетом, один из которых был xfy, а другой - yfx, и нашел только один случай для Seed7 mult и tiimes. Если бы можно было привести более практический пример ab
а также ba
это будет оценено.
РЕДАКТИРОВАТЬ
После прочтения ответа ложным, это мое понимание.
Поскольку речь идет только об ассоциативности, правила, использующие <и <=, не применяются.
Вместо этого мы используем значение Y = Да, X = Нет.
Unbracketed term Yes/No Equivalent bracketed term
--------------------------------------------------------------------------------------
1 xfy 2 xfy 3 1 No|Yes 2 No|Yes 3 1 xfy (2 xfy 3) ** right-associative
1 xfy 2 yfx 3 1 No|Yes 2 Yes|No 3 1 xfy (2 yfx 3) ** this is a special!
1 yfx 2 xfy 3 1 Yes|No 2 No|Yes 3 -------------- ** invalid: noone wants association
1 yfx 2 yfx 3 1 Yes|No 2 Yes|No 3 (1 yfx 2) yfx 3 ** left-associative
РЕДАКТИРОВАТЬ
В поисках примера, который имеет xyf
а также yfx
с тем же приоритетом, что имеет смысл, я нашел мета-интерпретаторы, которые определяют op(500,xfy,<==).
Valid
3 <== 1 + 2
3 xfy 1 yfx 2
3 No|Yes 1 Yes|No 2
Invalid
1 + 2 <== 3
1 yfx 2 xfy 3
1 Yes|No 2 No|Yes 3
Valid and makes sense.
(1 + 2) <== 3
Prec 0 xfy Prec 0
Valid but does not make sense.
1 + (2 <== 3)
Prec 0 yfx Prec 0
Хотя примеры с паренами действительны, имеет смысл использовать парены, чтобы выбрать, какой из них будет иметь смысл.
1 ответ
(Используемая вами запись крайне запутывает меня, когда я пишу операторы без операндов, поэтому я буду придерживаться стандартной нотации, которая всегда показывает операторы плюс аргументы.)
Что касается ассоциативности - и это все о ней - есть простое правило. Посмотрите на y
а также x
то есть да и нет xfy
"говорит" на левой стороне x
, Поэтому он не "хочет" связываться с операторами того же приоритета. И на правой стороне, это "говорит" y
При этом да я хочу ассоциироваться. Когда есть два оператора, которые оба говорят "да" друг другу, это первый случай (при чтении слева направо), который принимает второй в качестве аргумента. Если хотите, этот случай обрабатывается как правильная ассоциативность.
По этой причине с op(500,xfy,xfy), op(500,yfx,yfx)
у нас есть:
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
Насколько хорошо это реализовано? Посмотрите на это сравнение, начиная с #147 аналогичной ситуации. Так что все, кроме SWI, осуществляют чтение правильно. Но для написания есть еще несколько систем, которые не соответствуют.
Я думаю, что это ясно показывает, что редко бывают ситуации, когда программисты Пролога зависят от этого случая. На самом деле, стандартная таблица операторов не имеет ни одного случая, связанного с этой проблемой.
Для реального примера рассмотрим fy
а также yf
предназначен для обозначения некоторого подобного скобкам синтаксиса. На самом деле, в период до ISO несколько систем имели {
а также }
определяется таким образом, чтобы использоваться в DCG или CLP(Q). Обратите внимание, что эти два оператора не могут полностью имитировать "брекетинг". В качестве примера рассмотрим
Unbracketed term Equivalent bracketed term
-----------------------------------------------
fy fy 1 yf yf fy (fy ((1 yf) yf)
С другой стороны, если один имеет член вида fy( fy(X) )
(обратите внимание, это в каноническом синтаксисе!), затем X
должен быть либо (fy)/1
или же (yf)/1
, Любой другой термин должен быть отклонен.