0

我不太了解,如何理解这个事实p([H|T], H, T)。我知道 C/C++/Java 等。但这看起来不同。因此,当我将第一个参数传递给“函数”p 时,它将它分成 H 和 T 并使其可以通过这个变量访问?我不知道如何从逻辑上理解这一点。

http://www.doc.gold.ac.uk/~mas02gw/prolog_tutorial/prologpages/lists.html

p([H|T], H, T).


Lets see what happens when we ask some simple queries.

?- p([a,b,c], X, Y).

X=a


Y=[b,c]


yes
4

2 回答 2

1

您所指的页面说:“考虑以下事实。

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 = BB = A. 与变量的统一就像设置该变量,与一个值的统一就像检查与该值的(结构)相等性。

呼唤p(L,H,T)真的就等于统一L = [H|T]

于 2013-04-11T09:05:31.547 回答
1

在 Prolog 中,我们有关系,类似于关系数据库。

然后 p/3 它是一个列表(第一个参数)、它的 head和它的 tail之间的关系HT

教程的作者恰当地使用了描述性和合成符号作为变量。

从语法上讲,变量是以大写字母开头的符号,可以取任何值,但只能取一次(即不能“重新赋值”)。

于 2013-04-11T13:09:38.930 回答