Yogesh kumar
Yogesh kumar

Reputation: 15

Removing all instances of an item in a list :Prolog

removeAll(X, [ X | T], [ H1 | T1 ] ):-
      ( member ( X , T )
        -> removeAll ( X , T , [ H1 | T1 ] )
        ;[ H1 | T1 ] is T
      ).
removeAll ( X , [ H | T ] , L ):-
removeAll ( X , T , L2 ), append ( [ H ] , L2 , L ).

If i pass "removeAll(2,[1,1,2],L).",
it gives the error "ERROR: is/2: Type error: 'evaluable' expected, found '[]' (an empty_list)".

If i pass "removeAll(1,[1,1,2],L)." , it returns false.

Really confused. Where am i going wrong ?

Upvotes: 3

Views: 10037

Answers (2)

repeat
repeat

Reputation: 18726

Stay safe, stay on the side of !

Based on tfilter/3 and dif/3 we can define removeAll/3 like so:

removeAll(X, Es, Xs) :-
   tfilter(dif(X), Es, Xs).

Some variations of the query given by the OP:

?-        removeAll(1, [1,1,2], Xs).
Xs = [2].

?- X = 1, removeAll(X, [1,1,2], Xs).
X = 1, Xs = [2].

?-        removeAll(X, [1,1,2], Xs), X = 1.
   X = 1, Xs = [2]
;  false.

?- X = 1, removeAll(X, [1,1,2], Xs), X = 1.
X = 1, Xs = [2].

Some more queries showing more specialized and more generalized uses:

?- removeAll(a, [a,b,c], [a,b,c]).
false.                               % as expected

?- removeAll(X, [a,b,c], Xs).
   Xs = [  b,c],     X=a
;  Xs = [a,  c],               X=b
;  Xs = [a,b  ],                         X=c
;  Xs = [a,b,c], dif(X,a), dif(X,b), dif(X,c).

Upvotes: 1

Yasel
Yasel

Reputation: 3120

First, you must consider the case that the source list is empty:

removeAll(_, [], []).

This is also the stop condition. Cause you are building a recursive predicate, deleting every element in the Head of the target list that match a specific element, until the list is empty

Second clause, if the element is the Head of the List, don't copy it to the Result list, and continue the recursive call with the Tail.

removeAll(X, [X|T], L):- removeAll(X, T, L), !.

Third clause, copy the element in the Head of the list to the Result list, and continue with the recursive call with the Tail.

removeAll(X, [H|T], [H|L]):- removeAll(X, T, L ).

Your predicate:

removeAll(_, [], []).
removeAll(X, [X|T], L):- removeAll(X, T, L), !.
removeAll(X, [H|T], [H|L]):- removeAll(X, T, L ).

Upvotes: 9

Related Questions