Search code examples
listprolog

Prolog Predicate Help: Delete Number N times from List


Question: deleteNum(+Element, +List, -NewList, +NumToDelete) takes a list, an element, and the number of elements to delete from the List. The NewList should be the original List minus NumToDelete Elements. It does not matter which instances of the element get deleted, and no alternate answers should be given. For example,

Example:

?- deleteNum(3, [2,3,5,4,3,3], NewList, 2).
NewList = [2,5,4,3]

This is the code I tried, but it kept returning false when I attempted the example above. I'm not sure why.

deleteNum(_, [],[], 0).
deleteNum(X, [X|T], T, 0).
deleteNum(X, [H|T], [H|T1], Num):- 
     Num1 is Num - 1, 
     deleteNum(X, T, T1, Num1).

Thank you very much in advance.


Solution

  • You seem to be mixing up two cases with this predicate:

    deleteNum(X, [H|T], [H|T1], Num):- 
         Num1 is Num - 1, 
         deleteNum(X, T, T1, Num1).
    

    It's not removing X yet it's still reducing Num.

    Here's a couple of ways to do what you want:

    deleteNum(_, L, L, 0).
    deleteNum(X, [H|T], [H|T1], Num) :-
        X \= H,
        deleteNum(X, T, T1, Num).
        deleteNum(X, [X|T], T1, Num):- 
    Num1 is Num - 1, 
        deleteNum(X, T, T1, Num1).
    

    Or:

    deleteNum(_, L, L, 0).
    deleteNum(X, [X|T], T1, Num):- 
        !,
        Num1 is Num - 1, 
        deleteNum(X, T, T1, Num1).
    deleteNum(X, [H|T], [H|T1], Num) :-
        deleteNum(X, T, T1, Num).
    

    It depends if you like ! or not.

    Both succeed on ?- deleteNum(3, [2,3,5,4,3,3], NewList, 2), write(NewList), nl. and unify NewList to [2, 5, 4, 3].

    Please keep in mind that Prolog doesn't return anything. It just succeeds or fails. Along the way it just tries to unify variables in order to succeed.