27

如何在 Prolog 中附加列表?我在互联网上搜索过,我发现了这个(来自http://www.csupomona.edu/~jrfisher/www/prolog_tutorial/2_7.html

append([X|Y],Z,[X|W]) :- append(Y,Z,W).  
append([],X,X).

所以它Z通过删除 in 的元素来[X|Y]获得[X|W]。但是如何将两个列表附加在一起?

例子,

appendlist([1,2],[3,4,5],X).

结果将是X = [1,2,3,4,5]

我也不知道递归中发生了什么。(我追踪了但不明白)

编辑:我想知道的是它应该如何编码以像append()Prolog 中预定义的那样运行。

4

2 回答 2

37

您发布的代码(几乎)没问题。子句的顺序只需要交换(为了使这个谓词定义有效,当以生成方式使用时):

append( [], X, X).                                   % (* your 2nd line *)
append( [X | Y], Z, [X | W]) :- append( Y, Z, W).    % (* your first line *) 

A这定义了三个参数之间的关系,比如说BC

你的第一行说,C是附加的结果,A如果BA是非C空列表,它们都有相同的头部(即第一个元素),尾部C附加A相同第二个参数的尾部的结果,B

  a        a
  ----------
  b        b
  c        c
  .    d   d
       e   e
       .   .

或者从左到右:

         a | b c .
           |     d e .
         a | b c d e .

append(         [], 
                 Z,
                 Z ).       
append( [X | Y   ],
                 Z,
        [X |         W ] ) :- append(
             Y,  Z,  W).

想一想,这完全有道理。它所做的是,我们想要定义这种append/3关系,并且我们知道我们想要它是什么,所以我们只是写下一些我们希望它实现的明显事实,如果你愿意的话,它必须遵循的法律。

所以假设我们已经为我们定义了这个代码,它必须遵循什么法律?显然,将某个列表的尾部附加到另一个列表会给我们一个将完整列表附加到第二个列表的结果的尾部。

这定义了我们如何“滑动”第一个列表。但是,如果没有更多的地方可以滑动怎么办?如果我们已经到达该列表的末尾怎么办?然后我们到达了空列表,将一个空列表附加到另一个列表中,我们得到了该列表作为结果。明显地。这就是您的代码中的第二行告诉我们的内容,它说, “将一个空列表与另一个列表附加会产生该列表作为结果”

令人惊讶的是,写下这两个append/3必须遵循的定律,就与写下定义本身是一样的。

补充:这从声明的角度解释它;请查看m09 的答案,该答案从操作的角度来看更多。

于 2012-07-18T21:59:07.420 回答
11

但是如何将两个列表附加在一起?

您回答了自己的问题:您使用append/3.

如果你想追加XY存储结果Z,你做

append(X, Y, Z)

例如X = [1, 2],如果Y = [3, 4, 5]然后Z将绑定到[1, 2, 3, 4, 5]

| ?- append([1,2],[3,4,5], X).

X = [1,2,3,4,5]

yes
| ?- 
于 2012-07-18T10:24:47.690 回答