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。
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。