2012-09-28 37 views
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小时试图抓住它并不能。本幻灯片之前的任何序言概念没有任何问题。没有进一步的解释,没有其他信息。这就是全部。如果有人能够引导我了解这个程序的工作原理,我会爱他们直到死亡我们的一部分。

+0

请考虑查询'append(X,Y,[a,b])'! – false

回答

2

首先要理解的是:-操作符。

this_will_be_true :- if_this_is_true 

基本上,无论是在:-的权利是一个先决条件。一个很好的例子是:

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

这基本上意味着,X和Y是兄弟姐妹,如果存在一个父Ž使得Z既是X的父和Y.

append([ ], A, A). 

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

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

此行意味着追加C到A和B的现有列表返回因为追加C到B返回D.

Build a list: 

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

那么,什么是怎么回事A和d列表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的打算,这样的语句返回true返回的X唯一可能的值。我们来看看第二条规则。所以我们知道[a, b][A|D]。这意味着AaD[b]。我们也知道C[b]。所以现在,我们需要看一下前提条件来确定B是什么。 append(B, C, D)转换为append(B, [b], [b])。现在,使用第一条规则,我们知道B必须是[ ]。所以现在我们知道[A|B][a|[ ]]这与[a]相同。因此,X必须是[a]

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

+0

欢迎来到SE!非常好的答案。我想我只是有点阻碍。当我开始学习编程时,我通过学习命令式编程来放大。无处不在遵循指导流程是小孩子的游戏。但该死的是这个不同。 – Aerovistae

+0

为您修复了一些错别字。 :) –

0

以下是我自己的理解。

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

起初这里是一个abbrevation,可以帮助你了解什么是在序言的列表和什么的|含义:

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

和追加(A,B,C),追加列表B到A的结果在C.

追加空单导致:

append([ ], A, A). 

如果要追加Y到X,说追加(X,Y,_)。除非X是[],否则prolog不会知道任何事情要做。你说要告诉规则序言:

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

然后序言会尽量X分成形式[A|B]。那么Y将是A|D,其中D是由C附加到B定义的列表。append(B, C, D)是我们告诉序言关于这个事实的方式。

+0

最后一个句子出现问题。例如。如果'X = [1,2,3] = [A | B]'和'Y = [4,5] = C',则[A | [B | C]] = [1,[2,3 ],[4,5]]'。 –

+0

这里没问题。只有一种方法可以将X分成[A | B],即[[1,2,3]'(缩写为[1 | [2 | [3 | []]]])到[[1 | [2,3]]'。并且'[A | [B | C]]'将通过append([2,3],[1 | [2,3,4,5]]] [4,5],_))。请注意缩写何时适用。 – chyx

+0

'1? - X = [A | B],X = [1,2,3],C = [4,5],Z = [A | [B | C]]'产生: 'X = [1,2,3], A = 1, B = [2,3], C = [4,5], Z = [1,[2,3],4,5]' –