BigPapa
BigPapa

Reputation: 35

Nested list item deletion in prolog

I am working on this Prolog code to delete all occurrences of an element in a list, nested lists included. However instead of deleting the element it replaces it with an empty list.

Here is my code:

del(Item, [Head|Tail], [HeadResult|TailResult]) :-
   del(Item, Head, HeadResult),
   del(Item,Tail,TailResult), 
   !. 
del(Item,[], []). 
del(Item, Item, []). 
del(Item, Head, Head).

I believe the line del(Item,[], []). to be the culprit. However I am not sure how to change so that it doesn't appear in my new list.

Example of wanted output:

remberD(a, [a,b,c,[a,b]], New).

New = [b,c,[b]].

Upvotes: 1

Views: 694

Answers (1)

Will Ness
Will Ness

Reputation: 71065

You're attempting a structural recursion with

del(Item, [Head|Tail], [HeadResult|TailResult]) :-  % wrong
   del(Item, Head, HeadResult),
   del(Item, Tail, TailResult).

Seems good, except, what if Head = Item? The result should just be TailResult in such a case, there shouldn't be any HeadResult there at all:

del(Item, [Item|Tail], TailResult):-
   del(Item, Tail, TailResult).

Now, what if it's not an Item at the input list's head? Two cases - either it's a list and we need to go inside it, or it's not a list and we just keep it as it is:

del(Item, [Head|Tail], [HeadResult|TailResult]) :- 
   Head \= Item, Head = [_|_],
   del(Item, Head, HeadResult),
   del(Item, Tail, TailResult).

del(Item, [Head|Tail], [Head|TailResult]) :- 
   Head \= Item, Head \= [_|_],
   del(Item, Tail, TailResult).

The only other case is trying to delete something from an empty list:

del(_, [], []).

This assumes you'll always call this predicate with fully instantiated terms.

Upvotes: 1

Related Questions