General
Material
Lecture 1
Lecture 2
Lecture 3
Lecture 4
Lecture 5

Solution

%% The 2-place wrapper predicate. It calls the 3-place predicate
%% max. The accumulator is instantiated to the head of the input list.
max([Head|Tail],Max) :- max(Tail,Head,Max).

%% The 3-place predicate max uses an accumulator to store the greatest
%% element that has been found so far. The first argument is the part
%% of the list that has not been processed so far, the second argument
%% is the accumulator, and the third argument is for the final result.

%% If the list is empty, the value that is in the accumulator (i.e.,
%% the current maximal element) is the maximum of the whole list.
max([],Max,Max).

%% If the head is greater than the value of the accumulator, then the
%% head is greatest element that we have found so far. It becomes our
%% new accumulator value.
max([Head|Tail],Acc,Max) :- Head > Acc,
                            max(Tail,Head,Max).                    

%% If the head is smaller or equal to the accumulator value, the
%% accumulator is still the greatest element that we have found so
%% far. So, the accumulator stays as it is.
max([Head|Tail],Acc,Max) :- Head =< Acc,
                            max(Tail,Acc,Max).                    
    

Back to the exercise.