1

我只是在学习 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

4

1 回答 1

4

虽然这种编程技术是 Prolog 的关键,但这append_dl/3 是一个高度人为的例子,没有人以这种精确的方式使用。有一本 Prolog 教科书 (Art of Prolog) 将其用作第一个“激励”示例,并且某些课程仍然严格遵循此类教科书......

(让我们保持通常定义的通用定义append/3

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

所以取[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 的符号。

于 2017-11-14T21:05:53.473 回答