4

对于 Java 和 C 等允许带有运算符的语法糖(即中缀)的语言,它们使用优先级关联性

Prolog 还使用关联性:
左关联 - yfx
右关联 - xfy

但为什么会有 xfx?

我在互联网上发现的唯一更清楚的是

xfx 意味着运算符“支配”其分支,而 xfy 或 yfx 代表“列表构造”,在某种意义上允许链接相同优先级的表达式。

来自:CapelliC的练习中对 Prolog 运算符的解释

如果答案可以包括需要 xfx 的示例,因为 xfy 和 yfx 失败/没有意义,那将不胜感激。

Prolog 参考:Prolog 内置指令操作

作为错误的注释:

请注意,您在上面链接中提供的运算符与标准和 SWI 不同!它们至少已经过时了 10 年。例如,它应该是current_op(200,fy,-).

在阅读CapelliCfalse的两个当前答案后,很明显非关联是查找更多相关信息的关键词。因此,当关注非关联部分时,运算符关联性现在对 xfx 更有意义。

4

3 回答 3

5

运算符的说明符表示运算符的类(前缀、中缀、后缀)和关联性。

xfx意味着运算符不允许任何形式的关联性。换句话说:它不会与具有相同优先级的运算符嵌套。但是,它仍然与较低优先级的运算符嵌套。

此类运算符的最大部分是用于类似比较的含义的二元谓词,其中嵌套将具有 - 至少 - 与谓词的含义完全不同的含义。它们都位于优先级 700: 高到足以让所有算术运算符在没有括号的情况下工作;低到足以与期望目标作为参数的控制结构和相关元谓词一起使用。想想(\+)/1,,,。(;)/2_(',')/2

考虑一下=<:如果你想说明X介于 1 和 3 之间,你不能写1 =< X =< 3,因为在 Prolog 中既没(1 =< X) =< 3有意义1 =< (X =< 3)也没有意义。事实上,两者都会导致评估错误。你必须写1 =< X, X =< 3。这意味着=<(1, X), =<(X, 3)

在某些情况下,嵌套可能是有意义的,想想(A = B) = P. 在这里,第一个=只是一个仿函数,就像任何其他 arity 2 一样,而第二个=是相等/统一的内置谓词(=)/2。但是这种情况很少见,值得用一对额外的圆括号来突出它们。

另请注意,这 :- :- a.是无效的语法,因为(:-)/1又不嵌套。

算术运算符通常是左结合的,因为您像 一样从左到右处理它们1+2+4,首先计算1+2,然后才添加4。值得注意的例外是(^)/2: 之所以如此,是因为 (X^Y)^Z =:= X^(Y*Z)While(X^(Y^Z))表示无法用更简单的运算符表示的术语。

于 2013-11-12T18:15:59.930 回答
2

例如, (:-)/2 它显然是一个只能使用一次的运算符,因为它将头部与身体分开。

分隔是“相对的”,例如,您可以在规则中使用

my_rule :- assertz((a :- b, c)).

这是来自 SWI-Prolog 的(默认)xfx 运算符的完整列表

?- 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, (:-)
于 2013-11-12T17:30:47.357 回答
1

我认为 prolog 标准op场景的当前状态不一定是如何使用 op 的权威指南。将每个操作减少到这些类型代码(xf、fx、yfx 等)是一项了不起的发明,但这样的发明更多是时代精神的产物,而不是任何特定原理的产物(即结果不一定是定义的)由发明者的意图)。

xfy是一个左侧有源,右侧有目标的操作。 xfx是一个左侧有源,右侧有源的操作。 yfx是一个左侧有目标,右侧有源的操作。

'xfy' (通常)与:

  • 左到右
  • 从上到下
  • 统治
  • 第一
  • 声明性的
  • 对“yfx”一无所知

“xfx”(通常)与:

  • 操作数的判断
  • 同类事物的比较
  • 这就是我对这个怪人的全部

“yfx”(通常)与:

  • 右到左
  • 自下而上
  • 平等主义
  • 在最后(从而最终实现真正的统治)
  • 程序化
  • 容忍“xfy”的恶作剧

请注意,由于 'x' 和 'y' 在整个过程中是合作的,所以下面的结果是可行的:

  xfy xfx yfx

但相比之下,这行不通:

  yfx xfx xfy

一些例子(未经测试,只是草图)......

  (term_expansion((_a),(true)):-(asserta(_a))) .
  (term_expansion((_a | _b),(_b)):-(expand_term(_a,_c),asserta(_c))) .

  :-
  (op(10'1200,'xfy',':='))
  ,
  (op(10'1200,'xfx',':~'))
  ,
  (op(10'1200,'yfx',':-'))
  .

  (term_expansion((_a := _b :- _c),(term_expansion(_a,_b):-_c))) .
  (term_expansion((_a :~ _b :- _c),(goal_expansion(_a,_b):-_c))) .
  (term_expansion((_a := _b1 :~ _b2 :- _c),((_a := _b1 :- _c) | (_a :~ _b2 :- _c)))) .

在那个例子中:-yfx. 语法是___consequent___ :- ___precedent___; 右边是,也就是(因此首先评估),左边是目标,也就是codomain(因此第二次评估)。

在那个例子中:~xfx. 语法是___goal_1___ :~ ___goal_2__. 它对应于一个goal_expansion。

在那个例子中:=xfy. 语法是___precedent___ := ___consequence__. 它对应于 term_expansion。

  :-
  (op(10'700,'xfy','@='))
  ,
  (op(10'700,'xfx','\\='))
  ,
  (op(10'700,'yfx','#='))
  .

  (_x @= _y) :- ('='(_x,_y)) . % .i.e. term equality
  % (_x1 \= _x2)   % prolog builtin, not equal
  % (_y #= _x)   % via clpfd, math is generally simplification/\answer is left

在我看来,这是运算符\=的明确示例xfx

术语source | domain, target | codomain来自这里:https ://en.wikipedia.org/wiki/Morphism#Definition 。

我对范畴论知之甚少(目前),但我确实想xfx知道identity morphism.

于 2017-05-21T19:57:02.870 回答