Prolog中大括号的含义

Meaning of curly brakets in Prolog

Prolog中大括号的含义是什么:

{a,b,c}

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

Prolog 几乎和 C 一样古老...从一开始,它就采用了一种特殊的语法方法。因为它是所谓的 homoiconic language, everything is a term. Therefore, we are sure that {a,b,c} is also a term. In my old Prolog interpreter, I handled '{' and '}' as a separate pair of operators, so being able to process DCG rules, as explained in 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 有助于探索语法细节,但在这种情况下,函子是什么并不那么明显:

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

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

大括号({})可用于将正常的 Prolog 目标与 Definite Clause Grammar 预处理器隔离开来。所以花括号之间的东西可以是任意的 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) }.

有关大括号用途的完整说明,我建议阅读 “Prologing in Prolog”第 8 章中的段落 “添加额外测试” W. F. Clocksin, C. S. Mellish 可在此处获得 Curly Brackets in Prolog