0
votes

How do I write a procedure in Prolog that clears a list of integers of its negative elements and returns the result in a new list? Without using cuts but can use negation.

For example:

?- filter([1,0,-6,7,-1],L).
L = [1,0,7];
no
3
filter([],[]). filter([H|T],S) :- H<0, filter(T,S). filter([H|T],S) :- H>=0, filter(T,[H|S]).General_9

3 Answers

2
votes

You have it almost right. Your solution was:

filter([],[]).
filter([H|T],S) :-
  H<0,
  filter(T,S).
filter([H|T],S) :-
  H>=0,
  filter(T,[H|S]).

The base case and the case where the item is negative are right. The problem is with the last case. Once you checked that the item is nonnegative you know that the item will be on the resulting list. Therefore you should do the recursion and return a list that contains the element you have checked (H) and the list returned by recursion. Thus, the last clause should be

filter([H|T],[H|S]) :-
  H>=0,
  filter(T,S).
1
votes

In SWI-Prolog you can use exclude/3

?- exclude(negative, [-1, -0.5, 0, 0.5, 1], L).
L = [0, 0.5, 1].

provided that you have a definition for negative/1:

negative(Number) :-
    Number < 0.
0
votes

Using recursion for the last case,

I'd write :

filter([],[]).

filter([H|T],S) :-
  H<0,
  filter(T,S).

filter([H|T], L) :- 
 H>=0, 
 filter(T, S),
 append([H],S,L).