2

I have a list and a list of lists:

A = [1,2,4,5]
L = [[1,2,5],[3,4,5]]

If A contains the same elements as one of the lists, I want it to return true. As A contains the same elements (1,2,5) as the first list in L ([1,2,5]), it should return true even though there's one element in A that isn't in the first list in L.

I've tried using a couple of predicates supplied in the answer of a similar question in order to solve this:

p(X):- findall( Y, (member(Y,X), \+ have_common_element(X,Y) ), [_]).
have_common_element(A,B):- member(X,A), memberchk(X,B).

However the following query will return false:

p([[[1,2,5],[3,4,5]],[1,2,4,5]]).

I understand that this is because there is an element in A (4) that isn't in the first list of L, although I'm having difficulty figuring out how to extend the predicates to have the query return true.

Would it be possible to extend these predicates so that true will be returned even with the additional (and non-mutual) element included?

Community
  • 1
  • 1
Alpine
  • 533
  • 1
  • 6
  • 18

1 Answers1

2

What you want to say seems to be:

p(A, Ess) :-
   member(Es, Ess), % there is a list Es in Ess
   maplist(A+\E^member(E,A), Es). % for all E in Es: member(E,A).

or without lambdas:

p(A, Ess) :-
   member(Es, Ess),
   maplist(list_member(A), Es).

list_member(L, E) :-
   member(E, L).
false
  • 10,264
  • 13
  • 101
  • 209
  • 1
    Sorry for the late response, but I tried using the non-lambda version p([8,9],[[1,2,3],[3,4,5]]) to see if it would return false, however for some strange reason it's returning true. Might you know why? – Alpine Oct 21 '14 at 09:46
  • 1
    @Alpine: you got a warning on that: there was a `.` in place of a `,` – false Oct 21 '14 at 10:47