Prolog "append_dl/3" 包装器

Prolog "append_dl/3" wrapper

我刚刚学习 Prolog 和 Prolog 中差异列表的概念,所以请多多包涵。

我有以下代码:

:- op(400, xfx, \).

append(Xs, Ys, Zs) :-
  append_dl( [Xs|T1]\T1, [Ys|T2]\T2, Zs\[]).

append_dl( Xs\Ys, Ys\Zs, Xs\Zs).

现在,如果我在 SWI 解释器中附加列表 [1,2,3] 和 [a,b,c],它会生成列表列表

?- append([1,2,3],[a,b,c],Zs).
Zs = [[1, 2, 3], [a, b, c]].

而如果我像这样直接调用 append_dl:

?- append_dl([1,2,3|T1]\T1,[a,b,c|T2]\T2,Zs\[]).
T1 = [a, b, c],
T2 = [],
Zs = [1, 2, 3, a, b, c].

有效...

我哪里做错了,应该如何使用差异列表正确包装这些函数?

谢谢大家的帮助:D

虽然这种编程技术是 Prolog 的关键,但这个 append_dl/3 是一个高度人为的例子,没有人以这种精确的方式使用。有一本 Prolog 教科书 (Art of Prolog) 将其用作第一个 "motivating" 示例,一些课程仍然按照字面意思使用此类教科书...

(让我们保留 append/3 的通用定义,因为它通常是这样定义的)

差异列表不是列表。相反,它们是列表之间的差异。所以 list difference 对他们来说是一个更合适的名字。在大多数情况下,您没有准备好这样的差异,相反,您必须将实际列表转换为这样的差异,或者(更常见的是)在进行时构建差异。

所以取列表[1,2,3],可以用差值[1,2,3|Xs]\Xs表示。另一种表示方式是 [1,2,3]\[]。但是,只有当差异以您没有的最一般形式表示时,您才可以使用 append_dl/3 。因此,您首先需要将常规列表转换为该表示形式。

mappend(XsL, YsL, ZsL) :-
   append(XsL, Xs,Xs0),       % convert XsL to a difference Xs0\Xs
   append(YsL, Ys,Ys0),       % convert YsL to a difference Ys0\Ys
   append_dl( Xs0\Xs, Ys0\Ys, ZsL\[]).

在这个具体示例中,转换只是开销。您需要两次内置 append/3。此外,mappend(XsL, YsL, [1,2]) 不会终止,而 append(XsL, YsL, [1,2]) 会终止。对于那种情况,您将更改目标的顺序。

完成该作业后,我建议您学习 Prolog 的 表示法。