Prolog find maximum even number in the list
I need to find max even number in the list. For example
goal: maxEVEN([4,10,-2,-1,23],M). M=10.
I have written this following code:
maxeven(,M). maxeven([X|R],M):- Rest is X mod 2, isRest(Rest, X, M, R). isRest(0,X,M,[List]):- X > M, maxeven(List,X). isRest(0,X,M,[List]):- X < M, maxeven(List,M). isRest(Rest,X,M,[List]):- maxeven(List,M).
It is going throw the every loop member and checking if it is even, if it is then checking if it is creater than already assigned value of M. the problem is, that for the first call isRest predicate the value of M is empty thats why it always returns false. I don't know what value i could assign to this variable for the first time that this algorithm would work with all numbers.
there are some simple ways: either first seek the first even, to initialize M, or start with M unbound and check the status using var/1.
But I think your code has other problems. This is unusual syntax:
[List] it's a list of one element, as such I can't see how it fits your algorithm. Maybe the problem arises from your code being more complex than needed. If we assume that maxeven/2 can fail when there are not even numbers, could be simple as
maxeven([X|Xs], M) :- 0 is X mod 2, % fail if not even ( maxeven(Xs, T), T > X, !, M = T ; M = X). maxeven([_|Xs], M) :- maxeven(Xs, M).
How this works: when X is even, try to see if some other even is in Xs, and compare, but if no other even exists (for instance, when X is the last), keep X. Otherwise, when X is not even, search the tail Xs...
See if can understand why the cut is required, and play moving it to some other place to get a better understanding of Prolog control flow... It's not very intuitive...
If you are interested in Prolog, don't forget to study its library: maxeven/2 could be as simple as
maxeven(Xs, M) :- setof(X, (member(X, Xs), 0 is X mod 2), Evens), last(Evens, M).
Here is a tail recursive version:
maxeven([X|T], MaxEven) :- 0 is X mod 2, !, maxeven(T, X, MaxEven). maxeven([_|T], MaxEven) :- maxeven(T, MaxEven). maxeven([X|T], LastMax, MaxEven) :- 0 is X mod 2, !, M is max(X, LastMax), maxeven(T, M, MaxEven). maxeven([_|T], LastMax, MaxEven) :- maxeven(T, LastMax, MaxEven). maxeven(, LastMax, LastMax).