Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intersection of two lists without duplicate elements in Prolog

I need to write a program that finds the intersection of two lists. I can't use cuts and there shouldn't be any duplicate elements in the result list.

This is my code:

intersection([],_,[]).
intersection([X|Xs],Y,[X|Zs]) :-
    member(X,Y),
    intersection(Xs,Y,Zs).
intersection([_|Xs],Y,Zs) :-
    intersection(Xs,Y,Zs).

When I run the following query, I get these answers:

?- intersection([a,b,c,a],[a,v,c],L).
L = [a, c, a] ;
L = [a, c] ;            % <---------- this is only answer I want to get
L = [a, a] ;
L = [a] ;
L = [c, a] ;
L = [c] ;
L = [a] ;
L = [].

What can I do? I want to get L = [a,c] and nothing else... Can you help?

like image 479
nofar mishraki Avatar asked Jul 26 '15 10:07

nofar mishraki


1 Answers

In my answer to the related question "Intersection and union of 2 lists" I presented the logically pure predicate list_list_intersectionSet/3. It should fit your requirements to a T!

Here's is a brushed-up version of list_list_intersectionSet/3, which is based on:

  • monotone conditional if_/3,
  • meta-predicate tfilter/3,
  • and the reified test predicates dif/3 and memberd_t/3.

Here we go:

list_list_intersectionSet([]     ,_ ,[]).
list_list_intersectionSet([A|As0],Bs,Cs0) :-
   if_(memberd_t(A,Bs), Cs0 = [A|Cs], Cs0 = Cs),
   tfilter(dif(A),As0,As), 
   list_list_intersectionSet(As,Bs,Cs).

Let's see it in action!

?- list_list_intersectionSet([a,b,c,a],[a,v,c],L).
L = [a,c].
like image 114
repeat Avatar answered Jan 11 '23 10:01

repeat