【发布时间】:2015-09-07 06:25:55
【问题描述】:
Prolog中大括号是什么意思:
{a,b,c}
我知道我可以使用它们,但它们是描述元组还是什么?
【问题讨论】:
-
这取决于他们在哪里。在 DCG 规则中,它们用于告诉 Prolog 括号内的内容是“正常”的 Prolog 代码。
标签: syntax prolog curly-braces
Prolog中大括号是什么意思:
{a,b,c}
我知道我可以使用它们,但它们是描述元组还是什么?
【问题讨论】:
标签: syntax prolog curly-braces
Prolog 几乎和 C 一样古老……从一开始,它就采用了一种特殊的语法方法。因为它是一个所谓的homoiconic language,所以一切都是一个术语。因此,我们确信{a,b,c} 也是一个术语。在我的 old Prolog interpreter 中,我将 '{' 和 '}' 作为一对单独的运算符处理,因此能够处理 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 也有助于探索语法细节,但在这种情况下,函子是什么并不那么明显:
?- write_canonical({a,b,c}).
{','(a,','(b,c))}
一个值得注意的 SWI-Prolog 扩展,dicts,使用 {} 构建一个干净的对象表示...
【讨论】:
write_canonical({a,b,c}) 应该写成{}(','(a,','(b,c)))。正如 YAP、SICStus、B、IF、GNU ... 所做的那样
大括号({ 和})可用于将正常的 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) }.
关于花括号的用处的完整描述,我建议阅读 W. F. Clocksin 的 “Prolog 中的编程” 的第 8 章中的段落 “添加额外测试” , C.S. Mellish 在这里Curly Brackets in Prolog.
【讨论】: