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].
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 usea-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 saysa, b
, and you consume two elements when you expect to get one,(a,b)
term. So, to fix your current predicate you would write:But instead, using a more conventional name, term order, and Prolog pairs:
And of course, SWI-Prolog at least has a library(pairs), and it comes with a
pairs_keys_values/3
:I find comfortable using library(yall):
or, maybe clearer
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]
.Here the first term is used as input, the second and third as output.
Ideone example, using SWI-Prolog, here.