prolog - How to get values existing in two lists -
prolog - How to get values existing in two lists -
i have 2 lists song names , singer - top 10 european union , top 10 us. result should list containing songs exists in both lists.
here predicates sets 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 2 attempts write predicate doing 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). // result 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 list returned, wrong elements.
i'm hanging head in wall hours , hours , can't solve issue. more prolog take look? believe not concrete, main question how values existing in 2 lists.
edit: 2nd seek happens working, calling bad parameter list. calling ?- top10eu(l1),top10us(l2),both(l2,l1,l2,result),write(result).
returns right list: result = [stay_with_me, all_about_that_bass]
anyway, there more elegant way of doing this?
a bring together between 2 unsorted lists obtained help of library predicates:
both(l1,l2,l) :- findall(e, (member(e, l1), memberchk(e, l2)), l).
to extract part of matched structures, or perform more elaborate matching, can refine goal:
bothsong(l1,l2,l) :- findall(song, (e = song(song, _), member(e, l1), memberchk(e, l2)), l).
note songs having same author retrieved. because variable e
bind song(title, author).
prolog
Comments
Post a Comment