对于允许syntactic sugar使用运算符(即中缀)的Java和C等语言,他们使用precedence和associativity。
Prolog也使用了相关性:
左联 - yfx
right-associative - xfy
但为什么有xfx?
我在互联网上发现的唯一更清晰的是
xfx意味着运营商在其分支上“支配”,而xfy 或者yfx代表'列表构造',在允许链接的意义上 表达同样的优先权。
来自:Interpretation of Prolog's operator in an exercise CapelliC
如果答案可以包含需要xfx的示例,因为xfy和yfx失败/没有意义,那将不胜感激。
对于Prolog参考:The Prolog Built-in Directive op
如false所述:
请注意您在上面提供的运营商链接 不同于标准和SWI!它们至少已经过时了 10年。例如,它应该是
current_op(200,fy,-)
。
在CapelliC和false阅读了两个当前答案后,很明显 非关联是找到更多相关信息的关键词。因此,当关注非关联部分时,Operator associativity对于xfx更有意义。
答案 0 :(得分:5)
运算符的说明符表示运算符的类(前缀,中缀,后缀)和关联性。
xfx
表示运营商不允许任何形式的关联。换句话说:它不与具有相同优先级的运算符嵌套。但是,它仍然与较低优先级的运营商嵌套。
这类运算符的最大部分是arity 2的谓词,用于比较式的含义,并且嵌套将具有 - 至少 - 与谓词的含义完全不同的含义。它们都位于优先级700:足够高以允许所有算术运算符在没有包围的情况下工作;足够低,可以使用控制结构和相关的元谓词来预期目标作为参数。想一想(\+)/1
,(;)/2
,(',')/2
。
考虑=<
:如果您想声明X
介于1和3之间,则无法写1 =< X =< 3
因为(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)
而(X^(Y^Z))
表示无法用更简单的运算符表示的术语。
答案 1 :(得分: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, (:-)
答案 2 :(得分:1)
我认为prolog标准op
场景的当前状态不一定是如何使用op的明确指南。将每个操作减少到这些类型代码(xf,fx,yfx等)是一项了不起的发明,但是这种发明更多地是时代精神的产物而不是任何特定理论的产物(结果不一定是定义的)。根据发明者的意图)。
xfy
是一个操作,左侧有一个源,右侧有一个目标。
xfx
是一个操作,左侧有一个源,右侧有一个源。
yfx
是一个操作,左边有一个目标,右边有一个源。
'xfy'(通常)与:
相关联'xfx'(通常)与:
相关联'yfx'(通常)与:
相关联请注意,以下方法有效,因为'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
有关。