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 的 dcg 表示法。
我刚刚学习 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 的 dcg 表示法。