Reputation: 53
I want to construct a list of list to interleave each other to a single list like: coon([[1,4],[2,5],[3,6]], X) should return X=1,2,3,4,5,6. and there is a condition that each sublist should only have the same length, otherwise, it should fail such as [[q,r,y],[a,e],[c,g,t],X] shouid fail, and coon([A,B,C],[q,w,e,r,t,y]) should only return one solution, that is A=[q,r],B=[w,t],C=[e,y]. my recent approach is.
conns([],[]).
conns([[Head|Tail]|X],[Head|Y]):-
append(X,[Tail],X2),
conns(X2,Y).
conns([[]|T],A):-
conns(T,A).
It gives me multiple solutions when I try coon([A,B,C],[q,w,e,r,t,y]). I have been trying hours to figure it out but all failed. How should I return the single list to each sub-lists that contain the same length? Thank you so much!
Upvotes: 5
Views: 465
Reputation: 10102
:- use_module(library(clpfd),[transpose/2]).
connsx(Xss, Xs) :-
transpose(Xss, XssT),
append(XssT, Xs).
Upvotes: 5
Reputation: 58244
The problem you are having is with this predicate clause:
conns([[]|T],A):-
conns(T,A).
This allows solutions more general than you are wanting to define. Specifically, if I understand the problem correctly, the first argument to conns
should always be a list whose elements are lists all of equal length. That would mean that if [[]|T]
is the first argument and you expect conns([[]|T], A)
to succeed, then T
should also look like [[]|R]
or []
. That is, it should be a (possibly empty) list of empty lists.
If you revise the empty list case according to this constraint, your solution will work:
% The case where the first argument consists of non-empty lists
conns([[Head|Tail]|X], [Head|Y]):-
append(X, [Tail], X2),
conns(X2, Y).
% Base case in which first argument is a list of empty lists
conns([], []).
conns([[]|T], []) :-
conns(T, []).
Now when you run the query, you get this:
| ?- conns([[1,4],[2,5],[3,6]], R).
R = [1,2,3,4,5,6] ? ;
no
| ?-
As well as:
| ?- conns([A,B,C], [q,w,e,r,t,y]).
A = [q,r]
B = [w,t]
C = [e,y] ? a
no
| ?-
This solution does leave a choice point, which I'll leave as an exercise to eliminate if you wish.
Upvotes: 4