Reputation: 35
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
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