我正在阅读Prolog编程(第5版),在第3章中,本书介绍了使用以下语法的列表:
空列表写为
[]
...列表的开头和结尾是函子的名称为“。”的组件,即点(称为期或句号)。因此,该列表由一个元素“a
”组成是“.(a,[])
”,...由原子
a
,b
和c
组成的列表写为.(a,.(b,.(c,[])))
,...
然后在下一页中,它引入了方括号符号,就好像它与前面的语法是加糖的等效符号:
由于点符号在编写复杂列表时通常很笨拙,还有另一种语法可用于在Prolog中编写列表程序。此列表符号由列表的元素组成用逗号分隔,整个列表用方括号括起来括号。例如,上面的列表可以写在列表中表示法为
[a]
和[a,b,c]
。
随后的页面介绍了用于在列表的头部/尾部进行匹配的竖线语法[X|Y]
。
为什么,如果我写这些事实:
a([1,2,3]).
b(.(1,.(2,.(3,[])))).
此作品:
?- a([X|Y]).
X = 1,
Y = [2, 3].
但是不是吗?
?- b([X|Y]).
ERROR: Type error: `dict' expected, found `3' (an integer)
ERROR: In:
ERROR: [11] throw(error(type_error(dict,3),_7636))
ERROR: [9] '$dicts':'.'(3,[],_7676) at /usr/lib/swi-prolog/boot/dicts.pl:46
ERROR: [8] b([_7704|_7706]) at /home/abe/code/programming_in_prolog/ch03/.scratch.pl:2
ERROR: [7] <user>
ERROR:
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.
编辑:此尝试也不起作用:
?- b(.(X,Y)).
ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR: [11] throw(error(instantiation_error,_7856))
ERROR: [9] '$dicts':'.'(_7886,_7888,_7890) at /usr/lib/swi-prolog/boot/dicts.pl:46
ERROR: [8] '<meta-call>'(user:(...,...)) <foreign>
ERROR: [7] <user>
ERROR:
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.
简而言之,例如,因为点表示法已被“采用”以功能表示法支持字典访问器
?- write(_{a:1}.a).
1
true.
有关详细信息,请参见this doc。
手册的整个第5节是关于SWI-prolog语法更改WRT ISO prolog标准。
为了补充CapelliC的答案,在SWI-Prolog中,.
原子被[|]
替换为列表框构造函数:
?- [user].
|: b('[|]'(1,'[|]'(2,'[|]'(3,[])))).
|: % user://2 compiled 0.00 sec, 1 clauses
true.
?- b(X).
X = [1, 2, 3].
?- b([X|Y]).
X = 1,
Y = [2, 3].
?- b([X,Y|Z]).
X = 1,
Y = 2,
Z = [3].