谓词解压缩列表

时间:2016-04-29 07:15:21

标签: list prolog tuples

List1=[(x,1),(y,1),(z,1)]

我正在尝试拆分此列表:

分为两个列表:

List3=[x,y,z]
List4=[1,1,1]

所以我编写了这个谓词来尝试这样做:

splt([], [], []).
splt([X|Xs], [Y|Ys], [X,Y|Zs]) :-
    splt(Xs,Ys,Zs).

然而,谓词不是期望的结果,而是返回:

1 ?- splt([(x,1),(y,2),(z,3)],L3,L4).
L3 = [_G1760, _G1769, _G1778],
L4 = [ (z, 1), _G1760, (y, 2), _G1769, (z, 3), _G1778].

3 个答案:

答案 0 :(得分:7)

首先,您选择的术语。这个:(a, b)绝对不是你通常代表一个"元组"在Prolog。您几乎总是使用a-b作为"对",并且在整个标准库中使用对。

因此,您的初始列表如下所示:[x-1, y-1, z-1]

这也应该解释你遇到问题的原因。您编写了(a, b),但您的谓词显示为a, b,并且当您希望获得一个,(a,b)字词时,您会使用两个元素。所以,为了修复你当前的谓词,你会写:

split([], [], []).
split([X|Xs], [Y|Ys], [(X,Y)|XYs]) :-
    split(Xs, Ys, XYs).

?- split(Xs, Ys, [(x,1), (y,1), (z,1)]).
Xs = [x, y, z],
Ys = [1, 1, 1].

但是,使用更传统的名称,术语顺序和Prolog对:

zip([], [], []).
zip([X-Y|XYs], [X|Xs], [Y|Ys]) :-
    zip(XYs, Xs, Ys).

?- zip([x-1, y-1, z-1], Xs, Ys).
Xs = [x, y, z],
Ys = [1, 1, 1].

当然,SWI-Prolog至少有一个library(pairs),它附带一个pairs_keys_values/3

?- pairs_keys_values([x-1, y-1, z-1], Xs, Ys).
Xs = [x, y, z],
Ys = [1, 1, 1].

答案 1 :(得分:2)

您将元组整体匹配,而不是它的组成部分。

您应该在[(X1,Y1)|XS]上匹配,而不是[X|XS][Y|Ys]

splt([],[],[]).
splt([(X1,Y1)|Xs],[X1|T1],[Y1|T2]):-
  splt(Xs,T1,T2).

这里第一项用作输入,第二项用作输出。

Ideone示例,使用SWI-Prolog,here

答案 2 :(得分:2)

我觉得使用库(yall)很舒服:

?- maplist([(X,Y),X,Y]>>true, [(x,1),(y,2),(z,3)],L3,L4).
L3 = [x, y, z],
L4 = [1, 2, 3].

或者,可能更清楚

?- maplist([A,B,C]>>(A=(B,C)), [(x,1),(y,2),(z,3)],L3,L4).
L3 = [x, y, z],
L4 = [1, 2, 3].