为什么没有脱糖的“。”列表的仿函数语法与 []?

Why doesn't the desugared "." functor syntax for lists work the same as []?

我正在阅读 Prolog 编程(第 5 版),本书第 3 章介绍了使用以下语法的列表:

The empty list is written as [] ... The head and tail of a list are components of the functor named ".", which is the dot (called the period or full stop). Thus, the list consisting of one element "a" is ".(a,[])", ...

the list consisting of the atoms a, b and c is written .(a,.(b,.(c,[]))), ...

然后在下一页介绍了方括号符号,就好像它是对前面语法的加糖等效:

As the dot notation is often awkward for writing complicated lists, there is another syntax that can be used for writing lists in a Prolog program. This list notation consists of the elements of the list separated by commas, and the whole list is enclosed in square brackets. For example, the above lists can be written in the list notation as [a] and [a,b,c].

之后的页面介绍了用于匹配列表 heads/tails 的竖线语法 [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.

ver.7之后,你应该写这个笨拙的语法:

?- [user].
|: b('[|]'(1,'[|]'(2,'[|]'(3,[])))).
|: ^D% user://1 compiled 0.01 sec, 1 clauses
true.

?- b([X|Y]).
X = 1,
Y = [2, 3].

这是因为,简而言之,点符号已经 'coopted' 支持函数符号中的字典访问器,例如

?- write(_{a:1}.a).
1
true.

详情见this doc

手册的全部内容 section 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].