2

在试图理解类型的中缀运算符xfyyfx具有相同的优先级和顺序时,我看到只有四种组合。

使用

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运算符是左结合的。如果我理解正确,Prolog 会将其评估为:

使用优先级500x意义<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,与在该运算符 (yfx) 之前的左关联运算符具有相同优先级 (500)的操作数 (xfy)b 才需要括起来a

我理解正确吗?如果是这样,为什么 (xfy yfx)ab需要括号,而 (yfx xfy)ba不需要?

我还寻找了两个具有相同优先级的运算符的实际示例,一个是 xfy,另一个是 yfx,但只找到了Seed7 mult 和 tiimes的一个案例。如果有人可以提供一个更实际的例子abba那将不胜感激。

编辑

在阅读了错误的答案后,这是我的理解。

由于这仅与关联性有关,因此使用 < 和 <= 的规则不适用。
相反,我们使用 Y = Yes, X = No 的含义。

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

编辑

在寻找具有相同优先级的示例时,xyfyfx发现Meta-Interpreters定义了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

虽然带有括号的示例是有效的,但您必须使用括号来选择哪个有意义。

4

1 回答 1

6

(你使用的符号让我非常困惑,编写没有操作数的运算符,所以我将坚持标准符号,它总是显示运算符和参数。)

至于关联性——这就是全部——有一个简单的经验法则。查看左侧的yandx表示 Yes 和 No。 “说” 。所以它“不想”与具有相同优先级的运算符相关联。在右侧,它“说” ,因此是的,我想关联。当有两个运算符都“对彼此”说“是”时,它是第一个出现的(当从左到右阅读时)将第二个作为参数。如果你愿意,这种情况会像右关联一样处理。xfyxy

出于这个原因,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 之外的所有设备都可以正确读取。但是对于写作来说,还有一些不符合的系统。

我认为这清楚地表明 Prolog 程序员很少依赖这种情况。事实上,标准的算子表并没有任何与这个问题相关的案例。

对于一个真实的例子,考虑fyyf打算表示一些类似括号的语法。事实上,在 ISO 之前的时间里,有几个系统以这种方式定义{}用于 DCG 或 CLP(Q)。请注意,这两个运算符不能完全模拟“包围”。例如,考虑

   Unbracketed term   Equivalent bracketed term
  -----------------------------------------------
    fy fy 1 yf yf       fy (fy ((1 yf) yf)

另一方面,如果一个术语具有以下形式fy( fy(X) )(注意,它是规范语法!),则X必须是(fy)/1or (yf)/1。任何其他条款都必须被拒绝。

于 2013-12-19T23:21:33.223 回答