我最近开始学习Prolog,有些事情我不理解。
这两个句子为什么给出不同的输出?
我了解[[| ]表达式必须位于列表的开头,而右侧则位于列表的末尾。
我怀疑这一定是微不足道的,但最后我不明白为什么,因为在第一种情况下,第二种并没有将两个部分统一为一个列表。
?- X = [2|[1]].
X = [2,1].
?- X = [[1]|2].
X = [[1]|2].
答案 0 :(得分:2)
第二个不是列表,或者至少不是“ Prolog社区”认为的列表。
如果我们看一下您写的内容,第一个表达式可以看成类似于:
+-------+
| cons |
+---+---+ +-------+
| o | o--->| cons |
+-|-+---+ +---+---+
v | o | o---> nil
2 +-|-+---+
v
1
这是一个列表:您基本上构造了一个“ cons”,头为 head 2,尾部为另一个列表。请注意,列表的开头是元素,而列表的末尾是包含其余元素的列表。
在第二个示例中,您可能打了错字,也许您写过:
?- X = [[1]|2].
X = [[1]|2].
在这种情况下,“列表”如下所示:
+-------+
| cons |
+---+---+
| o | o---> 2
+-|-+---+
v
+-------+
| cons |
+---+---+
| o | o---> []
+-|-+---+
v
1
请注意,这实际上不是一个列表:缺点的头部是一个元素,并且这样的元素当然可以是一个列表(因为我们可以构造列表的列表等),但是这里的尾部是只是一个元素。
这意味着人们不能不能使用语法糖,因此用[1,2]
之类的语法糖代替。请注意,[1]
实际上是[1|[]]
的语法糖,而[2,1]
是[2|[1|[]]]
的语法糖(如第一幅图所示)。但是[[1]|2]
没有这样的语法糖当量。
大多数Prolog解释器允许您以规范的方式编写列表,例如在GNU Prolog中:
| ?- write_canonical([1]).
'.'(1,[])
(1 ms) yes
| ?- write_canonical([1,2]).
'.'(1,'.'(2,[]))
(1 ms) yes
| ?- write_canonical([[1]|2]).
'.'('.'(1,[]),2)
yes
因此,我们认为“ cons”函数是点'.'
,它是一个函子。)