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