Prolog中花括号的含义是什么?

4
在Prolog中花括号的含义是集合。花括号内的元素被视为一个无序的集合,可以用于匹配或生成解决方案。
{a,b,c}

我知道我可以使用它们,但它们是描述元组还是什么?

4
这取决于它们所处的位置。在DCG规则中,它们用于告诉Prolog括号内部的内容是“正常”的Prolog代码。 - Fatalize
2个回答

8
Prolog几乎和C语言一样古老…从一开始,它采用了一种独特的语法方法。由于它是一种所谓的同构语言,因此一切都是术语。因此,我们可以确定{a,b,c}也是一个术语。在我的旧Prolog解释器中,我将'{'和'}'处理为一对单独的操作符,因此能够处理DCG规则,如Clocksin/Mellish Programming in Prolog附录D中所述(注意,我是通过谷歌搜索作者和书名来获取这本书的非官方副本,而且我所用的书可能更老,可能是1985年...)。
让我们在SWI-Prolog REPL上探索一些语法。
?- functor({a,b,c},F,N).
F = {},
N = 1.

所以,{a,b,c}只是一个复合体,而a,b,c是它的参数:

?- {a,b,c} =.. Syntax.
Syntax = [{}, (a, b, c)].

同时写规范在探索语法细节时也很有帮助,但在这种情况下,它并不明确函数符号是什么:

?- write_canonical({a,b,c}).
{','(a,','(b,c))}

一个值得注意的 SWI-Prolog 扩展 dicts,使用 {} 来构建一个干净的对象表示形式...

4
请注意,write_canonical({a,b,c}) 应该改为写成{}(','(a,','(b,c)))。这适用于 YAP、SICStus、B、IF、GNU等语言。 - false
@false,是的,我也期望得到规范化的形式。看起来是个bug,但我找不到控制这种行为的标志,在不同条件下进行测试... - CapelliC
3
遗憾的是,这是一个 SWI7 功能 - false
1
嗯...看起来我可以像元组一样使用它...大致上是这样的:'{}'(a,b,c) <=> tuple(a,b,c) - sten

5

花括号 ({}) 可以用来将普通的Prolog目标与确定性子句语法预处理器隔离开来。因此,花括号之间的内容可以是任意的Prolog代码,只是不会被DCG规则预处理。

例如,假设您有以下规则来定义一个非常简单的语法:

sentence -->
    nounPhrase, verbPhrase.

nounPhrase -->
    det, noun,
    { write ('noun was found'), nl }.

verbPhrase -->
    verb, nounPhrase,
    { write ('verb was found'), nl }.

写下 "noun was found" 或者 "verb was found" 的目的与输入序列的消耗无关。因此,Prolog 允许您在花括号之间添加任何非预处理目标。省略非预处理目标的花括号会导致错误。
上面在 DCG 规则末尾添加的 "write" 目标只是说明花括号的作用(在 DCG 中没有实际使用 write 目标的用途)。但是,这里有一个例子可能有助于改进解析器的字典:假设您希望语法区分单数和复数名词。一种选择是添加一个额外的特征参数,例如:
noun(n(boy), singular) --> [boy].
noun(n(boy), plural) --> [boys].

但是,随着词汇量的增加,您添加的名词越多,就会增加不必要的复杂性。相反,您可以在花括号之间编写Prolog规则,以检查您的名词是单数还是复数,类似于以下内容:

n(n(NounSingular), Sgn_or_Pl) -->
    [Noun],
    { isNoun(Noun, NounSingular, Sgn_or_Pl) }.

为了全面描述花括号的有用性,我建议阅读《Prolog编程》一书中第8章“添加额外测试”一节的W.F. Clocksin和C.S. Mellish所述内容。可在此处阅读到该书:Prolog中的花括号

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接