如何在 Prolog 中附加列表?

Posted

技术标签:

【中文标题】如何在 Prolog 中附加列表?【英文标题】:How do I append lists in Prolog? 【发布时间】:2012-07-17 08:39:03 【问题描述】:

我在网上搜索了一下,找到了这个(来自http://www.csupomona.edu/~jrfisher/www/prolog_tutorial/2_7.html

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

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

例子,

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

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

我也不知道递归中发生了什么。 (我追了但是没看懂)

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

【问题讨论】:

【参考方案1】:

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

您回答了自己的问题:您使用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
| ?- 

【讨论】:

哦,我的意思是,我如何编写代码,使其功能类似于 prolog 的 append() 您的编码方式与append 的编码方式相同!?您已经发现了实现(这是您问题中的前两行代码)。【参考方案2】:

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

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

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

你的第一行说," C 是附加 AB 的结果,如果 AC 是非空列表,它们都有相同的 head (即第一个元素),Ctail 是在 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 必须遵循的这两条定律,就等于写下定义本身。

补充: 这从声明的角度来解释它;请查看an answer by m09,它从操作的角度更能说明问题。

【讨论】:

以上是关于如何在 Prolog 中附加列表?的主要内容,如果未能解决你的问题,请参考以下文章

Prolog附加到列表中

Prolog:如何调整跟踪中显示的列表的最大长度?

如何通过Prolog将字符串连接到列表中的多个元素?

如何在 Prolog 回溯期间获取值列表?

Prolog 如何通过交错将列表列表构造成单个列表?

这个Prolog代码如何真正起作用 - 随机播放两个列表