Predicate to unzip a list

痞子三分冷 提交于 2019-12-04 04:22:28

问题


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

I'm attempting to split this list:

into two lists:

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

So I have written this predicate to try to do it:

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

However instead of the desired result, the predicate returns:

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

回答1:


First, the term you have chosen. This: (a, b), is most definitely not how you would usually represent a "tuple" in Prolog. You almost always use a-b for a "pair", and pairs are used throughout the standard libraries.

So your initial list would look like this: [x-1, y-1, z-1].

This should also explain why you are having your problem. You write (a, b), but your predicate says a, b, and you consume two elements when you expect to get one ,(a,b) term. So, to fix your current predicate you would write:

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

But instead, using a more conventional name, term order, and Prolog pairs:

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

And of course, SWI-Prolog at least has a library(pairs), and it comes with a pairs_keys_values/3:

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



回答2:


I find comfortable using library(yall):

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

or, maybe clearer

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



回答3:


You're matching the tuple as a whole, rather than it's component parts.

You should match on [(X1,Y1)|XS], instead of [X|XS] and [Y|Ys].

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

Here the first term is used as input, the second and third as output.

Ideone example, using SWI-Prolog, here.



来源:https://stackoverflow.com/questions/36931919/predicate-to-unzip-a-list

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!