Search code examples
prologprolog-dif

Implement a Prolog predicate that say if an element belong to a list. Problems with not numerical lists


I am studying Prolog for an university exam and I have problems with this exercise:

Implement the predicate not_member(X,L) that is TRUE if the element X does not belong to the list L.

If my reasoning is correct, I have found a solution:

% FACT (BASE CASE): It is TRUE that X is not in the list if the list is empty.
not_member(_,[]).

% RULE (GENERAL CASE): If the list is non-empty, I can divide it in its Head
%   element and the sublist Tail. X does not belong to the list if it is different 
%   from the current Head element and if it does not belong to the sublist Tail.
not_member(X,[Head|Tail]) :-
   X =\= Head,
   not_member(X,Tail).

This code works well with lists of numbers, as the following queries show:

2 ?- not_member(4, [1,2,3]).
true.

3 ?- not_member(1, [1,2,3]).
false.

With lists having some non-numerical elements, however, it does not work and reports an error:

4 ?- not_member(a, [a,b,c]).
ERROR: =\=/2: Arithmetic: `a/0' is not a function

Why?


Solution

  • Let's check the documentation!

    (=\=)/2 is an arithmetic operator.

    +Expr1 =\= +Expr2 True if expression Expr1 evaluates to a number non-equal to Expr2.

    You have to use (\=)/2 to compare two generic terms:

    not_member(_, []) :- !.
    
    not_member(X, [Head|Tail]) :-
         X \= Head,
        not_member(X, Tail).
    

    and:

    ?- not_member(d, [a,b,c]).
    true.