0

在教授的讲座中举了一个例子:

append([ ], A, A).
append([A|B], C, [A|D]) :- append(B,C,D).

Build a list:

?- append([a],[b],Y).
Y = [ a,b ]

Break a list into constituent parts:

?- append(X,[b],[a,b]).
X = [ a ]
?- append([a],Y,[a,b]).
Y = [ b ]

我花了 3 个小时试图掌握它,但不能。这张幻灯片之前的任何序言概念都没有遇到任何问题。没有提供进一步的解释,也没有其他信息。这就是全部。如果有人能告诉我这个程序是如何工作的,我会爱他们直到死亡将我们分开。

4

2 回答 2

2

首先要了解的是:-操作员。

this_will_be_true :- if_this_is_true

基本上,右边的任何东西都是:-先决条件。一个很好的例子是:

sibling(X, Y) :- parent_child(Z, X), parent_child(Z, Y).

这基本上意味着如果存在父 Z 使得 Z 是 X 和 Y 的父级,则 X 和 Y 是兄弟姐妹。

append([ ], A, A).

这一行基本上意味着将某些内容附加到空列表会返回该内容。这是递归中的基本情况。

append([A|B], C, [A|D]) :- append(B,C,D).

这行意味着将 C 附加到具有 A 和 B 的现有列表会返回具有 A 和 D 的列表,因为将 C 附加到 B 会返回 D。

Build a list:

?- append([a],[b],Y).
Y = [ a,b ]

所以,这里发生的事情是 Prolog 返回唯一可能的值,Y它满足给定两个初始值的两个规则。让我们想想这是如何发生的。这需要首先通过第二条规则进行评估。[A|B]也是如此。[a]_ C_[b]

所以[A|B]我们必须回到第一条规则,因为B它是空列表(它是[ ])。第一条规则基本上表明我们可以写[a][a|[ ]],它们是相同的。所以现在我们可以回到第二条规则。AaB[ ]C[b]

所以现在让我们检查 的前提条件append(B, C, D)。这是append([ ], [b], D). 再一次,使用第一条规则,我们可以看到D也是[b]

所以Y,根据第二个规则定义,是[A|D]。现在我们知道D[b],我们知道那Y[a, b]

我只会做一个分解,因为它们基本上是一样的。

?- append(X,[b],[a,b]).
X = [ a ]

所以在这里,Prolog 将返回唯一可能的值,X以便语句返回 true。我们来看看第二条规则。所以我们知道那[a, b][A|D]。这意味着AisaDis [b]。我们也知道C[b]。所以现在,我们需要看看先决条件来弄清楚是什么Bappend(B, C, D)转换为append(B, [b], [b])。现在,使用第一条规则,我们知道B必须是[ ]。所以现在我们知道[A|B][a|[ ]]相同 [a]。因此,X必须[a]

我希望这是一个足够详细的解释。

于 2012-09-28T05:29:28.640 回答
0

下面是我自己的理解。

您的代码描述了 List 的附加操作。

首先,这里有一个缩写,可以帮助您理解 prolog 中的列表是什么以及它的含义是什么|

[X1|[...[Xn|[]] = [X1,...Xn]

而 append(A, B, C) 表示将列表 B 附加到 A 会导致 C。

将 A 附加到空列表结果 A:

append([ ], A, A).

如果要将 Y 附加到 X,请说 append(X, Y, _)。除非 X 是 [],否则 prolog 将不知道要做什么。你必须通过说来告诉规则序言:

append([A|B], C, [A|D]) := append(B, C, D)

然后 prolog 将尝试将 X 拆分为 form [A|B]。那么 Y 将是A|D其中 D 是由 C 定义的附加到 B 的列表。append(B, C, D)这是我们告诉 prolog 这个事实的方式。

于 2012-09-28T05:27:20.937 回答