Search code examples
listprologmember

Does an element exists in a list of lists?


I want to find if a given element exists in a list of lists. I am only getting true if the element exists somewhere is the first list of lists.

Any advice?

memberlist(X,[[X|T1]|T2]).
memberlist(X,[[H|T1]|T2]) :-
  memberlist(X,[T1|T2]).

Solution

  • The problem is that [[H|T1]|T2] only matches given the first list has at least one element. Indeed: [[],[1,4],[2,5]] for instance does not unify with [[H|T1]|T2].

    So you can solve the problem by adding a clause:

    memberlist(X,[[]|T2]) :-
        memberlist(X,T2).
    

    thus we obtain:

    memberlist(X,[[X|_]|_]).
    memberlist(X,[[H|T1]|T2]) :-
        memberlist(X,[T1|T2]).
    memberlist(X,[[]|T2]) :-
        memberlist(X,T2).
    

    the first clause also uses the underscores to specify that we are "not interested" in these variables. This is common for Prolog programs (probably the interpreter warned that T1 and T2 were mentioned only once).

    So in case the first list is exhausted, we simply move to the next list.

    Your predicate does a lot of "packing" and "unpacking". Furthermore we can make use of the member/2 builtin. So we can rewrite it:

    memberlist(X,[H|_]) :-
        member(X,H).
    memberlist(X,[_|T2]) :-
      memberlist(X,T2).