【发布时间】:2013-10-10 17:28:58
【问题描述】:
有时我会看到以下术语: X = a:b 或者 X = a-b
我可以做类似的请求 X = Y:Z 正如预期的那样,编译器将 Y 与 a 和 Z 与 b 统一起来。
现在我的答案是: 我可以使用哪些字符(或字符序列)来组合两个 Prolog 原子?!
也许你可以给我一些关于这个问题的更多信息的链接。
感谢您的帮助和来自德国的亲切问候
【问题讨论】:
标签: prolog iso-prolog
有时我会看到以下术语: X = a:b 或者 X = a-b
我可以做类似的请求 X = Y:Z 正如预期的那样,编译器将 Y 与 a 和 Z 与 b 统一起来。
现在我的答案是: 我可以使用哪些字符(或字符序列)来组合两个 Prolog 原子?!
也许你可以给我一些关于这个问题的更多信息的链接。
感谢您的帮助和来自德国的亲切问候
【问题讨论】:
标签: prolog iso-prolog
我可以使用哪些字符(或字符序列)来组合两个 Prolog 原子?!
您在这里要求的是 Prolog 的整个运算符语法定义。要获得此问题的完整答案,请参阅the tag iso-prolog 了解如何获取 Prolog 标准 ISO/IEC 13211-1 的完整信息。
但作为一个简短的答案开始:
Prolog 语法包括
函数符号,如+(a,b),加号
动态可重新定义的运算符语法,加上
一些额外的。
您似乎想知道哪些“字符”可以用作运算符。
简短的回答是您可以使用所有原子Op 成功用于current_op(Pri,Fix,Op)。因此,您可以动态询问存在哪些运算符:
所有这些运算符都可以以指定的方式使用,作为具有指定优先级的前、中或后缀。其中一些运算符是特定于 SWI 的,有些是由标准定义的。以上,只有@>= 和>= 是标准运算符。
大多数运算符仅由图形字符#$&*+-./:<=>?@^~ 或以小写字母开头的字母、数字和下划线组成。有两个单独的字符!;,然后是,|,它们更加特别。与上述不同的运算符名称需要引用 - 您很少会遇到它们。
要查看运算符如何嵌套,请使用write_canonical(Term)。
长答案是您也可以自己定义此类运算符。但是,请注意,更改运算符语法通常会产生许多难以理解的含义。更重要的是,因为许多系统在一些很少使用的配置上有所不同。比如你提到的系统,SWI differs in several ways。
我建议在您了解更多有关 Prolog 语言的信息之前避免定义新的运算符。
【讨论】:
让我们看看X = Y:Z里面有什么
?- display( X = Y:Z ).
=(_G3,:(_G1,_G2))
true.
然后我们有一个嵌套结构,其中函子是运算符。
操作符是一个原子,原子语法规则说我们有 3 种需要考虑:
编辑
A functor(我认为是函数构造函数的简写,但函数在 Prolog 上下文中具有误导性)它是“绑定”多个参数的符号。参数的数量被命名为 arity。在 Prolog 中,术语是原子文字(如数字或原子), 或 是递归结构,由 functor 和多个参数组成,每个参数都是术语本身(至少 1 个)。
给定适当的声明,即 op/3,一元和二元项可以表示为 表达式,就像您展示的那样。
使用 : 特殊字符的运算符示例是 ':-'
member(X,[X|_]).
member(X,[_|T]) :- member(X, T).
【讨论】:
write_canonical/1 谓词。
: 不是您所写的“特殊”字符。它是一个图形字符,如#$&*+-./:<=>?@^~
O.P. 说(我引用):
有时我会看到类似这样的术语:
X = a:b或X = a-b我可以执行
X = Y:Z之类的请求,并且编译器将 Y 与 a 和 Z 与 b 统一起来,正如预期的那样。现在我的答案是:我允许使用哪些字符(或字符序列) 用来组合两个 Prolog 原子?!
简短的回答是几乎是你想要的任何东西(只要它是一个原子)。
更长的答案是这样的:
看到的是中缀 (x infix_op b)、前缀 (pfx_op b) 和后缀 (b sfx_op)运算符。任何元数为 2 的结构都可以是中缀运算符。任何元数为 1 的结构都可以是前缀或后缀运算符。因此,任何原子都可以是运算符。
Prolog 是通过优先驱动的递归下降解析器(自然是用 Prolog 编写的)解析的。在operator/3 谓词中定义和枚举运算符,以及它们的优先级和关联性。关联性与解析树的构造方式有关。像a - b - c 这样的表达式可以解析为( a - ( b - c ) )(右关联)或( ( a - b ) - c )(左关联)。
优先级与 紧密 运算符的绑定方式有关。像a + b * c 这样的表达式绑定为( a + ( b * c ) 不是因为关联性,而是因为'*'/2(乘法)比'+'/2(加法)具有更高的优先级。
您可以随心所欲地添加、删除和更改运算符。并不是说这会给你很大的空间来打破 prolog 的语法。
需要注意的是,任何操作符表达式也可以用普通的符号来写:
a + b * c
与完全相同
'+'( a , '*'(b,c) )
【讨论】:
+(a, *(b,c)) 中引用+ 或*
'*'/2 表示“名为 * 的谓词或结构,数量为 2。