Prolog: remove member of list with non-instantiated values

413 Views Asked by At

I want remove all appearences of an element on a list, similar to this, but in my case, the list may have non-instantiated variables. For example:

delMember(z, [A,B,A,z], L).
L = [A, B, A];
false.

and

delMember(A, [A, B, A, z], L).
L = [B,z];
false.

I tried defining delMember as the following:

delMember(_, [], []).
delMember(X, [X|Xs], Y) :- delMember(X, Xs, Y).
delMember(X, [T|Xs], [T|Y]) :- X \== T, delMember(X, Xs, Y).

With this definition, the last result I get is correct but it's still trying to instantiate the variables before that.

?- delMember(A, [A,B,A,z], R).
A = B, B = z,
R = [] ;
A = B,
R = [z] ;
A = z,
R = [B] ;
R = [B, z] ;

any ideas???

1

There are 1 best solutions below

0
On BEST ANSWER

If you look at your second predicate clause:

delMember(X, [X|Xs], Y) :- delMember(X, Xs, Y).

Unification is occurring with the X in the first and second arguments. This leads to the results you are observing when you do your query. You need to apply the same operator as you did in your third clause. So your complete predicate (with some slightly changed variable names to be more conventional) would look like:

delMember(_, [], []).
delMember(X, [X1|Xs], Ys) :- X == X1, delMember(X, Xs, Ys).
delMember(X, [X1|Xs], [X1|Ys]) :- X \== X1, delMember(X, Xs, Ys).