此Prolog代码返回:
?- [a,b,c,d] = [a|[b,c,d]].
true
和这个
?- [X,Y] = [a|[b,c,d]].
返回假。
我不完全理解[X, Y]
为何为假。跟踪在这里没有帮助。我希望以下任务能够保持
X = a
Y = [b,c,d]
并且该陈述为真。
|
除了在头和尾巴上分开之外还做什么?
答案 0 :(得分:2)
Prolog中的列表被实现为函子的链接列表。如果您编写类似[a, b, c, d]
的列表。在现实中看起来像:
+-------+
| (|)/2 |
+---+---+ +-------+
| o | o---->| (|)/2 |
+-|-+---+ +---+---+ +-------+
v | o | o---->| (|)/2 |
a +-|-+---+ +---+---+ +-------+
v | o | o---->| (|)/2 |
b +-|-+---+ +---+---+
v | o | o----> []
c +-|-+---+
v
d
或Prolog表示法[a | [b | c | [d | [] ] ] ]
。逗号分隔的列表是语法糖:如果您输入[a, b, c, d]
,则Prolog解释器会将其转换为上述表示形式。
由于[b, c, d]
等于:
[ b | [ c | [ d | [] ] ] ]
,因此[ a | [b, c, d] ]
等于
[a | [b | c | [d | [] ] ] ]
但是列表[X, Y]
等于
[X, Y] == [ X | [ Y | [] ] ]
或以结构方式:
+-------+
| (|)/2 |
+---+---+ +-------+
| o | o---->| (|)/2 |
+-|-+---+ +---+---+
v | o | o----> []
X +-|-+---+
v
Y
如果我们随后将其与[a | [b | c | [d | [] ] ] ]
进行匹配,则意味着可以匹配“外部”外壳,因此X = a
,然后是Y = b
和[] = [ c | [ d | [] ] ]
。最后一部分不匹配,因此返回false
。 X
和Y
因此不是问题。问题在于[]
是一个常数,它与表示[ c | [d] ]
的函子不匹配。
例如,如果我们将[ X | Y ] == [a, b, c, d]
统一,则会得到:
?- [ X | Y ] = [a, b, c, d].
X = a,
Y = [b, c, d].
总而言之,可以说|
本身什么也不做。就像f(1, 2)
一样,它是一个函子。在Lisp中,他们为此使用cons
[wiki],并为空白列表使用nil
。因此[1, 4, 2, 5]
在Lisp中看起来像cons 1 (cons 4 (cons 2 (cons 5 nil)))
,或者在Prolog中看起来像cons(1, cons(4, cons(2, cons(5, nil))))
。写起来有点麻烦。实际上,逗号分隔的符号更像是“魔术”部分。 Prolog只是对列表执行统一,就像对其他函子和常量一样。