I have two lists with song names and the singer - top 10 for EU and top 10 for US. The result should be a list containing the songs which exists in both lists.
Here are the predicates which sets the lists:
top10us([
song(all_About_That_Bass, "Meghan Trainor"),
song(shake_It_Off, "Taylor Swift"),
song(black_Widow, "Iggy Azalea Featuring Rita Ora"),
song(bang_Bang, "Jessie J, Ariana Grande & Nicki Minaj"),
song(anaconda, "Nicki Minaj"),
song(habits, "Tove Lo"),
song(dont_Tell_Em, "Jeremih Featuring YG"),
song(animals, "Maroon 5"),
song(stay_With_Me, "Sam Smith"),
song(break_Free, "Ariana Grande Featuring Zedd")
]).
top10eu([
song(prayer_In_C, "Lilly Wood & Prick"),
song(lovers_On_The_Sun, "David Guetta & Sam Martin"),
song(chandelier, "Sia"),
song(rude, "Magic!"),
song(stay_With_Me, "Sam Smith"),
song(maps, "Maroon 5"),
song(all_Of_Me, "John Legend"),
song(all_About_That_Bass, "Meghan Trainor"),
song(a_Sky_Full_Of_Stars, "Coldplay"),
song(bailando, "Enrique Iglesias")
]).
Here are my two attempts to write a predicate doing the job.
Attempt 1:
member(ITEM,[song(ITEM,_)|_],1).
member(_,[],0).
member(ITEM,[_|T],R):-
member(ITEM,T,R).
both([],[],[]).
both([song(NAME,_)|T1], L2,[NAME|T3]):-
member(NAME,L2,R),R=1,both(T1, L2, T3).
both([_|T], L2, T3):-
both(T, L2, T3).
?- top10eu(L1),top10us(L2),both(L1,L2,RESULT),write(RESULT). // the result is false here
Attempt 2:
both(_,[],[],[]).
both(ORIGINAL,[_|T],[],OUTPUT):-
both(ORIGINAL,T,ORIGINAL,OUTPUT).
both(ORIGINAL, [song(NAME,SINGER)|T1], [song(NAME,_)|T2],[NAME|T3]):-
both(ORIGINAL, [song(NAME,SINGER)|T1], T2, T3).
both(ORIGINAL, L1, [_|T2], T3):-
both(ORIGINAL, L1, T2, T3).
?- top10eu(L1),top10us(L2),both(L1,L1,L2,RESULT),write(RESULT). // here a list is returned, but with wrong elements.
I'm hanging my head in wall for hours and hours and can't solve this issue. Could someone more into prolog take a look? I believe this is not too concrete, as the main question is how to get values existing in two lists.
EDIT: My 2nd try happens to be working, but I was calling it with bad parameter list. Calling it with ?- top10eu(L1),top10us(L2),both(L2,L1,L2,RESULT),write(RESULT).
returns the correct list: RESULT = [stay_With_Me, all_About_That_Bass]
Anyway, is there more elegant way of doing this?