[英]Prolog - unifying two lists with/without variables
此Prolog代码返回:
?- [a,b,c,d] = [a|[b,c,d]].
真正
还有这个
?- [X,Y] = [a|[b,c,d]].
返回false。
我并不完全理解为什么[X, Y]
是错误的。 跟踪在这里没有帮助。 我希望以下任务能够举行
X = a
Y = [b,c,d]
这个说法是正确的。
是什么|
除了在头和尾巴上劈开呢?
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 | [] ] ] ]
[a | [b | c | [d | [] ] ] ]
。 逗号分隔的列表是语法糖 :如果您编写[a, b, c, d]
,则Prolog解释器会将其转换为上述表示形式。
由于[b, c, d]
等于:
[ b | [ c | [ d | [] ] ] ]
因此[ a | [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 | [] ] ] ]
[a | [b | c | [d | [] ] ] ]
[a | [b | c | [d | [] ] ] ]
这意味着“外”壳可以被匹配,因此X = a
,但随后Y = b
,和[] = [ c | [ d | [] ] ]
[] = [ c | [ d | [] ] ]
[] = [ c | [ d | [] ] ]
。 最后一部分不匹配,因此返回false
。 因此, X
和Y
并不是问题。 问题是[]
是一个常数,并且与表示[ c | [d] ]
的函子不匹配[ c | [d] ]
[ c | [d] ]
。
例如,如果我们统一[ X | Y ] == [a, b, 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]
1,4,2,5 [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仅对列表执行统一,就像对其他函子和常量一样。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.