您所指的页面说:“考虑以下事实。
p([H|T], H, T).
"
所以我们必须把这当作一个事实。这意味着,这就像有一个谓词
p([H|T], H, T):- true. % or, p(L,H,T) :- L=[H|T].
现在,当您查询时p([a,b,c], X, Y).
,将一个放在另一个旁边:
p([a,b,c], X, Y). % a query
p([H|T], H, T) :- true. % a rule's clause: _head_ :- _body_.
等价被注明:[a,b,c] = [H|T]
, X = H
,Y = T
并被视为统一方程。第一个被进一步翻译成
a = H % list's head element
[b,c] = T % list's tail
因为[A|B]
代表一个列表,其中包含列表A
的头部元素和B
列表的尾部,即除了头部之外的所有其余元素。H
并且T
是这些逻辑变量的常用助记名称。
所以总的来说,我们得到X = H = a
, Y = T = [b,c]
。
这个过程就是所谓的查询和规则头部的统一p
(这两件事都以“函子”开头,并且都有 3 个“参数”)。
由于查询和规则“子句”的头部匹配(具有相同的函子和相同数量的参数),并且它们的参数都成功地成对地统一,使用上面的替换,我们只需要证明该规则的子句的主体(因此被选中)。
既然是true
,我们立即成功,成功替换为我们的结果。
这就是 Prolog 的工作原理。
TL;DR:是的,当您p(L,H,T)
使用给定的列表调用时L
,它将被解构为它的 headH
和 tail T
。但是您可以使用给定的列表T
、值H
和变量调用它L
,然后将从头部和尾部构造一个新列表。如果L
也给出了,它会检查它的头部是否是H
,它的尾部是否是T
。
这是因为 Prolog 的统一是双向的:A = B
与B = A
. 与变量的统一就像设置该变量,与一个值的统一就像检查与该值的(结构)相等性。
呼唤p(L,H,T)
真的就等于统一L = [H|T]
。