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].
答案 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].