Reputation: 93
I want to write a rule in Prolog that returns the even elements in a given list. For example: even_elements([1,2,3,4], Result) would return Result: [2,4]
Here is what I have so far:
% This is my base case.
even_elements([H|T], Result) :- (0 is mod(H,2) -> Result = [H|T] ; Result = T).
% This is my recursion.
even_elements([H|T], [H|NT]) :- even_elements(T, NT).
The base case works properly and eliminates the first element if it is odd; but the recursion doesn't change anything. Any tips on how to complete the recursion is appreciated.
Upvotes: 1
Views: 739
Reputation: 93
I also found this solution from this post although Willem's answer is way more readable:
even_elements(L1,L2):-findall(X,(member(X,L1), X mod 2=:=0),L2).
Upvotes: 1
Reputation: 476557
Often the base case in list processing deals with the empty list. Indeed, we can just write:
even_elements([], []).
For the recursive case, we can use quite a lot from your base case, the only thin that we still need to do is recurse on the tail of the list, so:
even_elements([H|T], Result) :-
( 0 is mod(H,2)
-> Result = [H|T2]
; Result = T2
),
even_elements(T, T2).
That being said, there is no need to implement the logic to filter a list. You can make use of the include/3
predicate [swi-doc], and thus define an even
predicate:
even(N) :-
0 is N mod 2.
Then we can filter with:
even_elements(L, R) :-
include(even, L, R).
This then gives us:
?- even_elements([1,4,2,5], R).
R = [4, 2].
Upvotes: 2