Rasalas
Rasalas

Reputation: 1562

How to check if all elements of one list are members of another list in Prolog

I'm learning Prolog right now and the recursive thinking is difficult to me.

I have two lists e.g. L1=[1,2,3] and L2=[3,1,2] and I should check if all elements of L1 are contained in L2

So allMembers(L1,L2). should return true and allMembers(L1,[2,3,4]). should return false, because there is no 4 in L1

I thought it would be possible to get the head of the one list and return true if it finds that element in the other list (by splitting it down until the list only contains one item), but I have no idea how to do that in Prolog.

It would be nice if you could help me getting faster on the uptake (?)

I found similar problems here, but couldn't find an answer to my specific problem :/

Edit:
I now have:

isMemberOf(X,[X|_]).
isMemberOf(X,[_|T]):- member(X,T).

which I need to use for any element in L1 to L2

Upvotes: 5

Views: 9658

Answers (5)

Rasalas
Rasalas

Reputation: 1562

This solves the question with only self defined predicates:

% allMembers(L1,L2) checks if all elements of L1 are available in L2
% solve the sub problem
isMemberOf(X,[X|_]).
isMemberOf(X,[_|T]):- isMemberOf(X,T).

% iterate through 'L1' and ask if the member exists in 'L2'
allMembers([],_).
allMembers([H|T],L):- allMembers(T,L), isMemberOf(H,L).

Upvotes: 1

Paulo Moura
Paulo Moura

Reputation: 18663

Quick solution using de facto standard predicates:

all_from_first_in_second(List1, List2) :-
    forall(member(Element,List1), member(Element,List2)).

Upvotes: 5

repeat
repeat

Reputation: 18726

Simply use list_permuted/2 like this:

?- list_permuted([1,2,3],[3,1,2]).
true.

Note that list_permuted/2 demands that both lists have the same items in the same quantity!

Upvotes: 1

lurker
lurker

Reputation: 58224

Probably the simplest way to define it may be:

% contained_in(L1, L2) succeeds if all elements of L1 are contained in L2
contained_in(L1, L2) :- maplist(contains(L2), L1).
contains(L, X) :- member(X, L).

maplist/2 will apply contains(L2) to each element of L1, and will succeed if every call succeeds. contains/2 is like member/2 but puts the arguments in the order that make it work with maplist.

Upvotes: 3

Scott Hunter
Scott Hunter

Reputation: 49803

To solve your sub-problem: member(A,B) is true if A is a member of the list B.

Upvotes: 2

Related Questions