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.

Answers


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:

isRest(0,X,M,[List]):-..

[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).

Need Your Help

how to make a cell of table hyperlink

html hyperlink href

How can entire table cell be hyperlinked in html without javascript or jquery?

android tablet emulator not starting with 1024 ram size

android android-emulator ram

To increase performance, I want to allocate 1024 MB RAM to a tablet emulator. Problem is that it won't start, i.e. no windows/consoles show up when I click Start in the Virtual Device Manager. If I...