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

Iterate only few elements inside a jstl foreeach

jsp foreach jstl

I have a requirement where I have to itearate over a map element kept in PageContext, inside jstl fore each . And I am also using an iterator inside the option tag. So I need to make sure the fore ...

When do programmers use Empty Base Optimization (EBO)

c++ class optimization memory-management compiler-optimization

I was reading about Empty Base Optimization(EBO). While reading, the following questions popped up in my mind:

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.