Search code examples
listprologset-theory

Prolog list difference routine


I am trying to implement a list difference routine in prolog. For some reason the following fails:

difference(Xs,Ys,D) :- difference(Xs,Ys,[],D).
difference([],_,A,D) :- D is A, !.
difference([X|Xs],Ys,A,D) :-
  not(member(X,Ys)),
  A1 is [X|A],
  difference(Xs,Ys,A1,D).

When trying:

?- difference([1,2],[],D).

I get this error:

ERROR: '.'/2: Type error: `[]' expected, found `1' ("x" must hold one character)
^  Exception: (10) _L161 is [2|1] ? 

Solution

  • Your usage A1 is [X|A] is incorrect. Predicate is is used only for arithmetics. Btw, SWI-Prolog has built-in subtract predicate:

    1 ?- subtract([1,2,3,a,b],[2,a],R).
    R = [1, 3, b].
    
    2 ?- listing(subtract).
    subtract([], _, []) :- !.
    subtract([A|C], B, D) :-
            memberchk(A, B), !,
            subtract(C, B, D).
    subtract([A|B], C, [A|D]) :-
            subtract(B, C, D).
    
    true.
    

    Is this what you need?