1

I am new to prolog.I want to write compare_lists/2 which will compare 2 lists and return true if they have at least one common element. I know this can be done with something like that

common_list([H|_],T) :- member(H,T).
common_list([_|T],L) :- common_list(T,L).

common_list2(L1,L2) :- member(X,L1),member(X,L2).

but I want to do it without Prolog built-in predicates. I tried writing this

common_elements([H|_],[H|_]).
common_elements(L,[_|T]) :- common_elements(L,T).
common_elements([_|T],L):-common_elements(T,L).

but when I ask the online swish prolog tool common_elements([3,13,8,1],[5,3,7,3,1]). It answers true 37 times not 3 like the common_list/2 and common_list2/2 (I have to use cut to get only 1 instead of 3 but that's a different story).

Guy Coder
  • 24,501
  • 8
  • 71
  • 136

2 Answers2

1

You can write the member function very easily yourself

my_member(H, [H|_]).
my_member(X, [_|T]) :-
    my_member(X,T).

Ch3steR
  • 20,090
  • 4
  • 28
  • 58
man zet
  • 826
  • 9
  • 26
1

According to your condition when two Lists have at least one element in common return True and False if they no elements in common.

All you have to do is check if Head of your list exists in your second List. If Head is present in second List return True. Else repeat the process for rest of the process for the tail of the first list.

My approach is given below:-

is_member(X,[X|_]):- !.
is_member(X,[_|T]):- is_member(X,T).

compare1([],[]):- false.
compare1([H|_],List):- is_member(H,List) , !.
compare1([H|T],List):- \+is_member(H,List) , compare1(T,List).

OUTPUT

?- compare1([3,4],[1,2,2]).
   false
?- compare1([1,2,3,4],[5,6]).
   false
?- compare1([1,2,3],[4,5,6,3]).
   true
?- compare1([1,2,3],[]).
   false
?- compare1([],[]).
   false
?- compare1([],[1,2,3]).
   false

Hope this helped you.

Ch3steR
  • 20,090
  • 4
  • 28
  • 58