2013-10-10 125 views
2

有时候,我看到了如: X = A:B 或 X = AB关于Prolog的语法

我能做的请求像 X = Y位:Z 和编译器相结合Y中一和Z b,如预期。

现在我的回答: 我可以使用哪些字符(或字符序列)来组合两个Prolog原子?

也许你可以给我一些关于这个问题的进一步信息的链接。

感谢您的帮助,并从德国

亲切的问候

回答

2

让我们来看看里面有什么X = Y:Z

?- display(X = Y:Z). 
=(_G3,:(_G1,_G2)) 
true. 

然后我们有一个嵌套的结构,其中仿函数的运营商。

运算符是一个原子,和原子语法规则说,我们有3种考虑:

  • 用单引号
  • 的特殊字符序列的任何可打印字符的序列只有,其中一个特殊字符是`。=: - + * /> <#@〜? (我希望我已经找到了所有的人,从this page你可以检查,如果我忘了一个人!)
  • 的小写/大写字符或下划线组成的序列,开始用小写字母

编辑

A 函数(函数构造函数的简写,我认为,但是函数在Prolog上下文中是误导性的)它是'绑定'几个参数的符号。参数的数量被命名为秩序。在Prolog中,术语是一个原子文字(如数字或原子),递归结构,由函数和一些参数组成,每个参数都是一个词本身(至少为1)。

考虑到适当的声明,即op/3,一元和二元项可以表示为表达式,就像您展示的那样。

运营商的一个例子,使用:特殊字符,是 ': - '

member(X,[X|_]). 
member(X,[_|T]) :- member(X, T). 
+0

要使用ISO Prolog标准'write_canonical/1'谓词来查看术语结构的更便捷的解决方案,您可以使用ISO prolog标准。 –

+0

感谢Paulo,你是对的。我知道今天早上(或昨天?)使用write_canonical/1,我注意到Jan使用了display/1,这是我不知道的。它比write_canonical要容易得多... – CapelliC

+0

首先,感谢您的非常有用的评论!他们帮助了我很多!如果我理解正确,那么在上面的例子中,“:”字符就是一个仿函数?!而在这种情况下,函子(什么是函子恰好?!)是运算符,或者是?现在还有一个问题:我允许在示例中使用哪些其他字符,但“:”除外。 – mrbela

1

的OP,说(我引述):

有时候,我看到了如:X = a:bX = a-b

我可以做像X = Y:Z这样的请求,并且编译器按照预期将y与a和z合并为b。

现在我的回答:我允许哪个字符(或字符序列) 用于合并两个Prolog原子?!

简短的回答是几乎任何你想要的(只要它是一个原子)

较长的答案是这样的:

什么是看到的是中缀(x infix_op b),前缀(pfx_op b)和后缀(b sfx_op运营商。任何具有2的结构可以是中缀运算符。任何arity为1的结构都可以是前缀或后缀运算符。因此,任何原子都可能是操作员。

通过优先驱动的递归下降解析器(自然地写在Prolog中)解析Prolog。定义和枚举运算符,以及它们在operator/3谓词中的优先级和关联性。关联性与分析树的构建方式有关。像a - b - c这样的表达式可以被解析为(a - (b - c))(右关联)或((a - b) - c)(左关联)。

优先级与如何紧密运算符绑定。像a + b * c这样的表达式不会因关联而结合为(a + (b * c),而是因为'*'/ 2(乘法)的优先级高于'+'/ 2(加法)。

您可以添加,删除和更改操作员到您的心脏的内容。这并不是说这让你有很大的空间通过打破序言的语法来打破自己的脚步。

然而,应当指出的是,任何操作者表达也可以通过普通的符号被写成:

a + b * c 

完全相同

'+'(a , '*'(b,c)) 
+0

在+(a,*(b,c))中没有理由引用'+'或'*'' – false

+0

''''''*'/ 2'无效语法,它应该读取'(*)/ 2'。等等 – false

+0

引用原子并没有伤害,它可以提高理解力。 * functor/arity *是指示谓词或结构名称和参数的常用方式,如'foo/2'中所示。它不是序言语法:''''''意思是“名称为'*'的谓词或结构,其格式为2 –

3

哪些字符(或序列字符)我可以用来合并两个Prolog原子吗?!

你在这里问的是Prolog的整个运算符语法定义。要获得完整的答案,请参阅the tag iso-prolog了解如何获得Prolog标准ISO/IEC 13211-1的完整信息。

但作为一个简短的回答开始:

Prolog的语法由

  1. 功能符号,如+(a,b),加上

  2. 动态重新定义运算符的语法,加上

  3. 一些额外的。

看来你想知道哪些“字符”可以用作操作符。

简短的回答是你可以使用所有原子Opcurrent_op(Pri,Fix,Op)成功。这样你就可以动态地询问,其中操作者存在:

 
?- current_op(Pri, Fix, Op). 
Pri = 1, 
Fix = fx, 
Op = ($) ; 
Pri = 1150, 
Fix = fx, 
Op = (module_transparent) ; 
Pri = 700, 
Fix = xfx, 
Op = ([email protected]=) ; 
Pri = 700, 
Fix = xfx, 
Op = (@>=) ; 
Pri = 700, 
Fix = xfx, 
Op = (>=) 
... 

所有这些运营商可以在指定的方式被使用,如前,会,或与所指示的优先级后缀。其中一些运营商是特定于SWI的,一些是由标准定义的。以上,只有@>=>=是标准的运营商。

大多数操作员只包含图形字符#$&*+-./:<=>[email protected]^~或字母,数字和以小写字母开头的下划线。有两个独奏字符!;,然后有,|这些更特别。与上面不同的运算符名称需要引用 - 你很少会遇到它们。

要查看运营商如何嵌套,请使用write_canonical(Term)

长答案是你也可以自己定义这样的操作符。但是,请注意,更改操作符语法往往会带来许多非常难以理解的含义。更是如此,因为许多系统在一些很少使用的配置上有所不同。例如,您提到的系统SWI differs in several ways

我建议避免定义新的操作符,直到您了解了更多关于Prolog语言。