Define a predicate subsetsum(L, Sum, Subl) that takes a list L of numbers, a number Sum, and unifies SubL with a sub sequence of L such that the sum of the numbers in SubL is Sum.
For example
?- subsetsum([1,2,5,3,2], 5, SubSet);
SubSet = [1,2,2];
SubSet = [2,3];
SubSet = [5];
SubSet = [3,2];
No.
we have
sum([H1 | [H2 | Tail]], S):-
sum([[H1+H2]|Tail], S):-
sum([X], X).
and
subset([],[]).
subset([H1|T1], [H1|T2]) :- // heads are the same
subset(T1, T2).
subset([_|Rest], X):
subset(Rest, X).
If all numbers used are integers and your Prolog processor supports clpfd, proceed like this!
:- use_module(library(clpfd)).
z_z_product(A,B,AB) :-
AB #= A*B.
subsetsum_(Zs, Sum, Bs, [Sum|Vs]) :-
same_length(Zs, Bs),
append(Zs, Bs, Vs),
Bs ins 0..1,
maplist(z_z_product, Zs, Bs, Xs),
sum(Xs, #=, Sum).
Sample query:
?- subsetsum_([1,2,5,3,2], 5, Sel, Vs), labeling([], Vs).
Sel = [0,0,0,1,1], Vs = [5,1,2,5,3,2,0,0,0,1,1]
; Sel = [0,0,1,0,0], Vs = [5,1,2,5,3,2,0,0,1,0,0]
; Sel = [0,1,0,1,0], Vs = [5,1,2,5,3,2,0,1,0,1,0]
; Sel = [1,1,0,0,1], Vs = [5,1,2,5,3,2,1,1,0,0,1]
; false.
The following clauses should do what you need...
subsetsum(SET, SUM, ANSWER) :-
% Find a subset
subset(SET, ANSWER),
% Check elements of the subset add up to SUM
sum(ANSWER, SUM).
% sum(LIST, SUM) - sums all numbers in the list
sum([], 0).
sum([X | T], SUM) :-
sum(T, TAILSUM),
SUM is TAILSUM + X.
% subset - finds subsets
subset([], []).
subset([E|Tail], [E|NTail]) :-
subset(Tail, NTail).
subset([_|Tail], NTail) :-
subset(Tail, NTail).
With swi-prolog we can use the library predicate sum_list/2 together with that subset/2 you already got! Note that I gave subset/2 the better fitting name list_subsequence/2:
list_subsequence([], []).
list_subsequence([X|Xs], [X|Ys]) :-
list_subsequence(Xs, Ys).
list_subsequence([_|Xs], Ys) :-
list_subsequence(Xs, Ys).
subsetsum(List, Sum, Sub) :-
list_subsequence(List, Sub),
sum_list(Sub, Sum).
Here is the sample query that you gave:
?- subsetsum([1,2,5,3,2], 5, Xs).
Xs = [1,2,2]
; Xs = [2,3]
; Xs = [5]
; Xs = [3,2]
; false.
OK! Let's run another query with both integers and floats... does that work, too?
?- subsetsum([1,2.1,5,3,2], 5.1, Xs).
Xs = [1,2.1,2]
; Xs = [2.1,3]
; false.
Looks alright to me!
Related
Given two sorted lists Xs and Ys, how do I ensure the absolute difference between any X in Xs and any Y in Ys is at least two?
Sample queries with expected answers:
?- different([1,2,4],[5,6]). % 5-4 < 2
false
?- different([1,4],[2,6]). % 2-1 < 2
false
?- different([1,2,6],[4,8]). % 4-2 >= 2 and 6-4 >= 2 and 8-6 >= 2
true
?- different([],[4]).
true
How can I get to this result? Any ideas? Thank you!
Edit: Here is the code I have now:
difference([], []).
difference([_|_], []).
difference([], [_|_]).
difference(L1, L2) :-
L1 = [X1|X2],
L2 = [Y1|_],
Dif is X1-Y1,
(-1>Dif|Dif>1),
difference(X2, L2).
In this answer we use clpfd to attain both
versatility and optimum (linear) arithmetic complexity.
diff_to_mdist([], _, _).
diff_to_mdist([_|_], [], _).
diff_to_mdist([X|Xs], [Y|Ys], D) :-
( X #=< Y-D, diff_to_mdist(Xs, [Y|Ys], D)
; X #> Y-D, X #>= Y+D, diff_to_mdist([X|Xs], Ys, D)
).
diff_to_mdist([X0,X1|Xs], [Y0,Y1|Ys], D) :-
X0 #> Y0-D, X0 #< Y0+D,
( X0 #< Y0, X0 #=< Y0-D, X1 #>= Y0+D, diff_to_mdist([X0,X1|Xs], [Y1|Ys], D)
; X0 #> Y0, Y0 #=< X0-D, Y1 #>= X0+D, diff_to_mdist([X1|Xs], [Y0,Y1|Ys], D)
).
Let's use gnu-prolog version 1.4.4 and run queries like the ones suggested by the OP!
| ?- diff_to_mdist([1,2,4], [5,6], 2).
no
| ?- diff_to_mdist([1,4], [2,6], 2).
no
| ?- diff_to_mdist([1,2,6], [4,8], 2).
true ? ;
no
| ?- diff_to_mdist([], [4], 2).
yes
First, you can make your current code a lot neater and easier to read as follows:
different([], []).
different([_|_], []).
different([], [_|_]).
different([X|Xs], [Y|Ys]) :-
abs(X-Y) >= 2, % Prolog evaluates arithmetic expressions for compares
different(Xs, [Y|Ys]).
In this case, you've done one level of the recursion I mentioned in my comment, as it only checks each element of the first list against only the first element of the second. It ignores all the other elements of the second list. So you need to break it down further. You could make a helper predicate which compares each element of a list against a single value. Then have your main predicate call this helper predicate with each element of the other list. The main predicate would then look like:
different([], []).
different([], [_|_]).
different([X|Xs], L) :-
different_element(X, L),
different(Xs, L).
Then the helper predicate would be:
% This predicate succeeds if the first argument has the desired difference
% to each of the elements of the second argument (a list)
%
different_element(_, []).
different_element(X, [Y|Ys]) :-
abs(X-Y) >= 2,
different_element(X, Ys).
I've been searching through the many existing Prolog questions on SO relevant to splitting but couldn't find one as generic as the one that I want. I'd like to point out that I've been able to split lists into lists of 2/3/4 elements by using 2/3/4 variables piped before a list variable. This question is different from that only because of its genericness.
So, my list will always contain N*N items, N being unknown beforehand(usually will vary from 4 to 36, yes N is also a perfect square). I want to split it into a list of N lists containing N items each because that'll allow me to treat it as a matrix, hence allowing to transpose and certain operations of that sort. I haven't really been able to get too far with the logic because I'm relatively new to declarative programming; please see below my incomplete(faulty) attempt:
listmodel(1,L):- L = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16].
size(L,N) :- length(L,N1), N is round(sqrt(N1)).
% add_tail(+Liste, +Element, -ResultantList)
add_tail([],L,[L]).
add_tail([X|L1],L2,[X|LI]):-add_tail(L1,L2,LI).
% partition the list containing N*N items into a list of N lists containing N elements each.
% part(+Liste, +Size, -ResultantList)
part([],_,DL).
part(L,N,DL) :-
length(P,N), % P(refix) initialized
append(P,S,L), % S(uffix) contains rest of L, using append in (-,-,+) mode
add_tail(DL,P,DL1), %add P(first N elements) as first element of DL.
part(S,N,DL1).
Now running ?- listmodel(1,L),size(L,N),part(L,N,DL). will produce DL=[] because that is what it gets initialized to in the first add_tail call in the part predicate. I can't seem to figure out how to store all elements in a list that's preserved through the recursion.
Any help/direction of any kind will be appreciated. I'm stuck here since over 23 hours 10 minutes now.
Thanks.
This should do it:
part([], _, []).
part(L, N, [DL|DLTail]) :-
length(DL, N),
append(DL, LTail, L),
part(LTail, N, DLTail).
Base case is first/last arguments are empty lists.
Recursive step takes a fresh list of N elements, takes the first N elements from L (which will be one of the items of the third argument) and calls recursively.
Want to combine versatility and favorable termination properties?
Use clpfd!
:- use_module(library(clpfd)).
First, we define
list_prefix_n_suffix/4.
list_prefix_n_suffix(Zs,Xs,N,Ys) is logically equivalent to both append(Xs,Ys,Zs), length(Xs,N) and length(Xs,N), append(Xs,Ys,Zs), but has better universal termination behavior than either1 one!
list_prefix_n_suffix(Zs, Xs, N, Ys) :-
list_prefix_n0_n_suffix(Zs, Xs, 0,N, Ys).
list_prefix_n0_n_suffix(Zs, Xs, N0,N, Ys) :-
zcompare(Order, N0, N),
rel_list_prefix_n0_n_suffix(Order, Zs, Xs, N0,N, Ys).
rel_list_prefix_n0_n_suffix(=, Ys, [], _,_, Ys).
rel_list_prefix_n0_n_suffix(<, [Z|Zs], [Z|Xs], N0,N, Ys) :-
N1 #= N0 + 1,
list_prefix_n0_n_suffix(Zs, Xs, N1,N, Ys).
Some sample queries for list_prefix_n_suffix/4:
?- list_prefix_n_suffix([a,b,c], Xs,-1, Ys).
false. % OK: too small
?- list_prefix_n_suffix([a,b,c], Xs, 0, Ys).
Xs = [], Ys = [a,b,c]. % succeeds deterministically
?- list_prefix_n_suffix([a,b,c], Xs, 4, Ys).
false. % OK: too big
?- list_prefix_n_suffix([a,b,c], Xs, N, Ys).
Xs = [] , N = 0, Ys = [a,b,c]
; Xs = [a] , N = 1, Ys = [b,c]
; Xs = [a,b] , N = 2, Ys = [c]
; Xs = [a,b,c], N = 3, Ys = []
; false. % terminates universally
Based upon above list_prefix_n_suffix/4 we define list_rows_width/3:
list_rows_width([], [], _N).
list_rows_width([E|Es0], [[R|Rs]|Rss], N) :-
list_prefix_n_suffix([E|Es0], [R|Rs], N, Es),
list_rows_width(Es, Rss, N).
Sample queries using list_rows_width/3:
?- list_rows_width([a,b,c,d,e,f], Rows, 4).
false. % OK: 6 is not divisible by 4
?- list_rows_width([a,b,c,d,e,f], Rows, 3).
Rows = [[a,b,c],[d,e,f]]. % succeeds deterministically
?- list_rows_width([a,b,c,d,e,f,g,h,i,j,k,l], Rows, N).
N = 1, Rows = [[a],[b],[c],[d],[e],[f],[g],[h],[i],[j],[k],[l]]
; N = 2, Rows = [[a, b],[c, d],[e, f],[g, h],[i, j],[k, l]]
; N = 3, Rows = [[a, b, c],[d, e, f],[g, h, i],[j, k, l]]
; N = 4, Rows = [[a, b, c, d],[e, f, g, h],[i, j, k, l]]
; N = 6, Rows = [[a, b, c, d, e, f],[g, h, i, j, k, l]]
; N = 12, Rows = [[a, b, c, d, e, f, g, h, i, j, k, l]]
; false. % terminates universally
Works just like it should!
Footnote 1: Without resorting to using alternative control-flow mechanisms like prolog-coroutining.
I need to write a program that finds the intersection of two lists. I can't use cuts and there shouldn't be any duplicate elements in the result list.
This is my code:
intersection([],_,[]).
intersection([X|Xs],Y,[X|Zs]) :-
member(X,Y),
intersection(Xs,Y,Zs).
intersection([_|Xs],Y,Zs) :-
intersection(Xs,Y,Zs).
When I run the following query, I get these answers:
?- intersection([a,b,c,a],[a,v,c],L).
L = [a, c, a] ;
L = [a, c] ; % <---------- this is only answer I want to get
L = [a, a] ;
L = [a] ;
L = [c, a] ;
L = [c] ;
L = [a] ;
L = [].
What can I do? I want to get L = [a,c] and nothing else... Can you help?
In my answer to the related question "Intersection and union of 2 lists" I presented the logically pure predicate list_list_intersectionSet/3. It should fit your requirements to a T!
Here's is a brushed-up version of list_list_intersectionSet/3, which is based on:
monotone conditional if_/3,
meta-predicate tfilter/3,
and the reified test predicates dif/3 and memberd_t/3.
Here we go:
list_list_intersectionSet([] ,_ ,[]).
list_list_intersectionSet([A|As0],Bs,Cs0) :-
if_(memberd_t(A,Bs), Cs0 = [A|Cs], Cs0 = Cs),
tfilter(dif(A),As0,As),
list_list_intersectionSet(As,Bs,Cs).
Let's see it in action!
?- list_list_intersectionSet([a,b,c,a],[a,v,c],L).
L = [a,c].
If by "conjunction" you mean "intersection", you should take a look at the implementation in the SWI-Prolog library(lists) of the predicate intersection/3. It contains cuts, but you can leave them out if you don't mind all the choicepoints.
With it:
?- intersection([a,b,c,a],[a,v,c],I).
I = [a, c, a].
Of course, this doesn't work even in the library predicate, because you need sets with your current definition. (It is enough if only the first argument is a set.)
You can make sets with the sort/2 predicate: if the first argument is a list with repetitions, the second argument will be a sorted list without repetitions, for example:
?- sort([a,b,c,a], S1), intersection(S1, [a,v,c], I).
S1 = [a, b, c],
I = [a, c].
or maybe:
?- sort([a,b,c,a], S1), intersection(S1, [a,v,c,c,a,c], I).
S1 = [a, b, c],
I = [a, c].
?- sort([a,b,c,a,b,c,a,b,c], S1), intersection(S1, [a,v,c,c,a,c], I).
S1 = [a, b, c],
I = [a, c].
If you sort both arguments, you can use a ord_intersection/3 from library(ordsets), implemented in terms of oset_int/3.
?- sort([a,b,c,a], S1), sort([a,v,c,c,a,c], S2), ord_intersection(S1, S2, I).
S1 = [a, b, c],
S2 = [a, c, v],
I = [a, c].
Importantly, oset_int/3 does not use any cuts in its implementation. It however assumes that the first and second arguments are lists of elements sorted by the "standard order of terms" and without duplicates, as done by sort/2.
If for some reason you don't want to use sort/2, you could maybe use an accumulator and check against it before taking an element to the intersection:
my_intersection(Xs, Ys, Zs) :-
my_intersection_1(Xs, Ys, [], Zs).
my_intersection_1([], _, Zs, Zs).
my_intersection_1([X|Xs], Ys, Zs0, Zs) :-
member(X, Ys), \+ member(X, Zs0),
my_intersection_1(Xs, Ys, [X|Zs0], Zs).
my_intersection_1([_|Xs], Ys, Zs0, Zs) :-
my_intersection_1(Xs, Ys, Zs0, Zs).
Of course, the order of the elements in the result will be now reversed. If this is not what you mean by "conjunction", you could for example rewrite the first two clauses of my_intersection_1/4 as:
my_intersection_1([], _, _, []).
my_intersection_1([X|Xs], Ys, Zs0, [X|Zs]) :-
member(X, Ys), \+ member(X, Zs0),
my_intersection_1(Xs, Ys, [X|Zs0], Zs).
The previously shown list_list_intersectionSet/3 restricts the item order in the intersection:
?- list_list_intersectionSet([a,b],[a,b], [a,b]).
true.
?- list_list_intersectionSet([a,b],[a,b], [b,a]).
false.
In this answer we lift that restriction... preserving logical-purity and determinism (for ground cases)!
First, we define none_intersect/2 using Prolog lambdas and
meta-predicate maplist/2.
none_intersect(As,Bs) states that all members in As are different from all members in Bs.
:- use_module(library(lambda)).
none_intersect(As,Bs) :-
maplist(\A^maplist(dif(A),Bs),As).
Next, we define intersection_of_and/3---based on none_intersect/2 (defined above), meta-predicate tpartition/4 and reified term equality (=)/3:
intersection_of_and([],As,Bs) :-
none_intersect(As,Bs).
intersection_of_and([X|Xs],As0,Bs0) :-
tpartition(=(X),As0,[_|_],As), % [_|_] = [X|_]
tpartition(=(X),Bs0,[_|_],Bs), % [_|_] = [X|_]
intersection_of_and(Xs,As,Bs).
intersection_of_and(Xs,As,Bs) states that
all items which occur in both As and Bs also occur in Xs (first clause),
all items in Xs occur in both As and Bs at least once (second clause),
and the list Xs does not contain any duplicates.
intersection_of_and/3 uses a specific argument in order to enable first argument indexing.
Last, we define list_list_intersection/3 which has the argument order that the OP used:
list_list_intersection(As,Bs,Xs) :-
intersection_of_and(Xs,As,Bs).
Let's run some queries! First, the query that the bounty offerer suggested:
?- list_list_intersection([a,b],[a,b], [b,a]).
true.
Next, a similar query with 3 distinct items in 3 lists having 3 different orders:
?- list_list_intersection([a,b,c],[b,a,c], [c,a,b]).
true.
What if some x only occurs in the first/second list?
?- list_list_intersection([a,b,c,x],[b,a,c], [c,a,b]).
true.
?- list_list_intersection([a,b,c],[b,a,c,x], [c,a,b]).
true.
What if some item occurs twice in the first/second list?
?- list_list_intersection([a,b,c],[b,a,c,b], [c,a,b]).
true.
?- list_list_intersection([a,b,c,c],[b,a,c], [c,a,b]).
true.
Last, what if the intersection contains duplicates?
Intersections are not to contain duplicates...
?- list_list_intersection([a,b,c],[b,a,c], [c,c,a,b]).
false. % as expected
Seems like something like this would be the easy way:
intersection( Xs , Ys , Zs ) :-
sort(Xs,X1) , % order and de-dupe the 1st list so as to produce a set
sort(Ys,Y1) , % order and de-dupe the 2nd list so as to produce a set
merge(Xs,Ys,Zs) % merge the two [ordered] sets to produce the result
. % easy!
merge( [] , [] , [] ) .
merge( [] , [_|_] , [] ) .
merge( [_|_] , [] , [] ) .
merge( [X|Xs] , [Y|Ys] , [X|Zs] ) :- X = Y , merge( Xs , Ys , Zs ) .
merge( [X|Xs] , [Y|Ys] , Zs ) :- X < Y , merge( Xs , [Y|Ys] , Zs ) .
merge( [X|Xs] , [Y|Ys] , Zs ) :- X > Y , merge( [X|Xs] , Ys , Zs ) .
Or even just this [not-terribly-performant] one-liner:
intersection( Xs , Ys , Zs ) :- setof(Z,(member(Z,Xs),member(Z,Ys)),Zs).
This can be solved by simple set theory:
intersection(A,B,AnB):-
subtract(A,B,AminusB),
subtract(A,AminusB,K),
sort(K,AnB).
For the query:
?- intersection([a,b,c,a],[a,v,c],L).
output is
L = [a, c].
No more answers.
I need to write a Prolog predicate take(L, N, L1) which succeeds if list L1 contains the first N elements of list L, in the same order. For example:
?- take([5,1,2,7], 3, L1).
L1 = [5,1,2]
?- take([5,1,2,7], 10, L1).
L1 = [5,1,2,7]
Prolog thus far is making little sense to me, and I'm having a hard time breaking it down. Here is what I have so far:
take([H|T], 0, []).
take([H|T], N, L1) :-
take(T, X, L2),
X is N-1.
Can you please explain what I did wrong here?
Here is a definition that implements the relational counterpart to take in functional languages like Haskell1. First, the argument order should be different which facilitates partial application. There is a cut, but only after the error checking built-in (=<)/2 which produces an instantiation_error should the argument contain a variable.
take(N, _, Xs) :- N =< 0, !, N =:= 0, Xs = [].
take(_, [], []).
take(N, [X|Xs], [X|Ys]) :- M is N-1, take(M, Xs, Ys).
?- take(2, Xs, Ys).
Xs = [], Ys = []
; Xs = [_A], Ys = [_A]
; Xs = [_A,_B|_C], Ys = [_A,_B].
Note how above query reads:
How can one take 2 elements from Xs to get Ys?
And there are 3 different answers. If Xs is empty, then so is Ys. If Xs is a list with one element, then so is Ys. If Xs has at least 2 elements, then those two are Ys.
1) The only difference being that take(-1, Xs,Ys) fails (for all Xs, Ys). Probably the best would be to issue a domain_error similar to arg(-1,s(1),2)
findall/3 it's a bit the 'swiss knife' of Prolog. I would use this snippet:
take(Src,N,L) :- findall(E, (nth1(I,Src,E), I =< N), L).
The code by #CapelliC works if the instantiation is right; if not, it can show erratic behavior:
?- take(Es, 0, Xs).
**LOOPS** % trouble: goal does not terminate
?- take([A,_], 1, [x]).
true. % trouble: variable A remains unbound
To safeguard against this you can use
iwhen/2 like so:
take(Src, N, L) :-
iwhen(ground(N+Src), findall(E, (nth1(I,Src,E), I =< N), L)).
Sample queries run with SWI-Prolog 8.0.0:
?- take([a,b,c,d,e,f], 3, Ls).
Ls = [a,b,c].
?- take([a,b,c,d,e,f], N, Ls).
ERROR: Arguments are not sufficiently instantiated
?- take(Es, 0, Xs).
ERROR: Arguments are not sufficiently instantiated
?- take([A,_], 1, [x]).
ERROR: Arguments are not sufficiently instantiated
Safer now!
The obvious solution would be:
take(List, N, Prefix) :-
length(List, Len),
( Len =< N
-> Prefix = List
; length(Prefix, N),
append(Prefix, _, List)
).
Less thinking means less opportunity for mistakes. It also makes the predicate more general.
your base case is fine
take([H|T], 0, []).
And also you can say what if N is 1
take([H|T],1,[H]).
But you recursive case some variable is not defined like L2. So we can write this as
take([X|T1],N,[X|T2]):-
N>=0,
N1 is N-1,
take(T1,N1,T2).
which case all varibles are pattern-matched.
take(L, N, L1) :- length(L1, N), append(L1, _, L).
This is performant, general and deterministic:
first_elements_of_list(IntElems, LongLst, ShortLst) :-
LongLst = [H|T],
( nonvar(IntElems) -> Once = true
; is_list(ShortLst) -> Once = true
; Once = false
),
first_elements_of_list_(T, H, 1, IntElems, ShortLst),
(Once = true -> ! ; true).
first_elements_of_list_([], H, I, I, [H]).
first_elements_of_list_([_|_], H, I, I, [H]).
first_elements_of_list_([H|LongLst], PrevH, Upto, IntElems, [PrevH|ShortLst]) :-
Upto1 is Upto + 1,
first_elements_of_list_(LongLst, H, Upto1, IntElems, ShortLst).
Result in swi-prolog:
?- first_elements_of_list(N, [a, b, c], S).
N = 1,
S = [a] ;
N = 2,
S = [a,b] ;
N = 3,
S = [a,b,c].
?- first_elements_of_list(2, [a, b, c], S).
S = [a,b].
Below is a variant which also supports:
?- first_elements_of_list_more(10, [5, 1, 2, 7], L1).
L1 = [5,1,2,7].
first_elements_of_list_more(IntElems, [H|LongLst], [H|ShortLst]) :-
once_if_nonvar(IntElems, first_elements_of_list_more_(LongLst, 1, IntElems, ShortLst)).
first_elements_of_list_more_([], Inc, Elems, []) :-
(var(Elems) -> Inc = Elems
; Elems >= Inc).
first_elements_of_list_more_([_|_], E, E, []).
first_elements_of_list_more_([H|LongLst], Upto, IntElems, [H|ShortLst]) :-
succ(Upto, Upto1),
first_elements_of_list_more_(LongLst, Upto1, IntElems, ShortLst).
once_if_nonvar(Var, Expr) :-
nonvar(Var, Bool),
call(Expr),
(Bool == true -> ! ; true).
nonvar(Var, Bool) :-
(nonvar(Var) -> Bool = true ; Bool = false).
Please help me to solve this problem:
I have a list of lists
[[1,2],[3,4]]
How do I get:
[1,3]
[1,4]
[2,3]
[2,4]
Or if I have a list of lists
[[1,2],[3,4],[6,7]]
How do I get:
[1,3,6]
[1,3,7]
[1,4,6]
[1,4,7]
[2,3,6]
[2,3,7]
[2,4,6]
[2,4,7]
The predicate for accessing a single list element is the most basic Prolog building block: member/2.
And you want a list of all lists' elements: maplist/3 does such mapping. Thus we can write
combine(Ls, Rs) :-
maplist(get1, Ls, Rs).
get1(L, E) :-
member(E, L).
note that get1/2 is only required so that we swap the member/2 arguments. But because in (pure) Prolog we are describing relations between arguments, we can swap arguments' order and simplify it even more:
combine(Ls, Rs) :-
maplist(member, Rs, Ls).
Test output:
?- combine( [[1,2],[a,b]], Xs).
Xs = [1, a] ;
Xs = [1, b] ;
Xs = [2, a] ;
Xs = [2, b].
%% this is the same as:
%% maplist( member, Xs, [[1,2],[a,b]]) :-
%% member( X1, [1,2] ),
%% member( X2, [a,b]), Xs = [X1,X2].
edit
A joke: really, my first combine/2 should have been written like
combine(Ls, Rs) :-
maplist(rebmem, Ls, Rs).
rebmem(L, E) :-
member(E, L).
You can do something like this:
lists([], []).
lists([[Head|_]|Lists], [Head|L]):-
lists(Lists, L).
lists([[_,Head|Tail]|Lists], L):-
lists([[Head|Tail]|Lists], L).
That is, take the first element of the first list in your input list and continue recursively with the remaining lists. As a second chance, skip that element and redo with the remaining elements.