1

I have a problem, i have two lists, and i want to extract all of elements that are the same. For example :

> comparer([la_defense,etoile,chatelet,nation],[auber,chatelet,hotel_de_ville,nation],X).

comparer([],LSB,LI).
comparer([X|LS],LSB,LI):-member(X,LSB),!,comparer(LS,LSB,[LI|X]).
comparer([X|LS],LSB,LI):-comparer(LS,LSB,LI).

I want this result :

X = [chatelet,nation].

But this code i made doesn't works. i'm a newbie so... what is the problem ? :/

false
  • 10,264
  • 13
  • 101
  • 209
toshiro92
  • 1,287
  • 5
  • 28
  • 42

3 Answers3

2

You are using an accumlator, so the code should be

comparer(L1, L2, R) :-
    comparer(L1, L2, [], R).

comparer([], _, R, LR) :-
    reverse(R, LR).

comparer([X|LS],LSB,LI, R):-
    member(X,LSB),!,
    comparer(LS,LSB,[X | LI], R).
comparer([_X|LS],LSB,LI, R):-
    comparer(LS,LSB,LI, R).

You can try this

comparer([], _, []).

comparer([X|LS],LSB,LI):-
    comparer(LS, LSB, R),
    (   member(X, LSB) -> LI = [X | R]; LI = R).
joel76
  • 5,565
  • 1
  • 18
  • 22
  • Thanks, it works perfectly ^^ so if member is true, LI = [X | R ]... is executed ? i didn't know "->" :/ – toshiro92 Dec 30 '12 at 21:29
2

intersection/3 does exactly what you need.

?- intersection([la_defense,etoile,chatelet,nation],[auber,chatelet,hotel_de_ville,nation],X).
X = [chatelet, nation].
CapelliC
  • 59,646
  • 5
  • 47
  • 90
1

My answer to the similar question Intersection and union of 2 lists might be of interest to you.

Unlike other answers posted here and there, the implementation I suggest is logically pure and monotone, which makes it more versatile and robust with regard to generalization / specialization.

First, let's see if it works with the query you gave above:

?- As = [la_defense,etoile,chatelet,nation],
   Bs = [auber,chatelet,hotel_de_ville,nation],
   list_list_intersection(As,Bs,Xs).
As = [la_defense, etoile, chatelet, nation],
Bs = [auber, chatelet, hotel_de_ville, nation],
Xs = [chatelet, nation].

But what if we write the query in a different (but logically equivalent) way?

?- As = [_,_,_,_],
   Bs = [_,_,_,_],
   list_list_intersection(As,Bs,Xs),
   As = [la_defense,etoile,chatelet,nation],
   Bs = [auber,chatelet,hotel_de_ville,nation].
As = [la_defense, etoile, chatelet, nation],
Bs = [auber, chatelet, hotel_de_ville, nation],
Xs = [chatelet, nation].

With list_list_intersection/3 we get the same result.


Now, let us consider using the builtin intersection/3, which was proposed in another answer. Is intersection/3 robust regarding generalization, too?

?- As = [_,_,_,_],
   Bs = [_,_,_,_],
   intersection(As,Bs,Xs),
   As = [la_defense,etoile,chatelet,nation],
   Bs = [auber,chatelet,hotel_de_ville,nation].
false.

No! intersection/3 fails, even though it succeeded in a logically equivalent query, which shows that the implementation of intersection/3 is not monotone.

Bottom line: intersection/3 is harder to use right than list_list_intersection/3; it forces you to think about declarative and procedural aspects when using it.

Community
  • 1
  • 1
repeat
  • 18,496
  • 4
  • 54
  • 166