(* Search in the list for the max with respect to a valuation function f *)
Fixpoint find_max (l : list A) : option (nat * A) :=
  match l with
  | nil => None
  | a :: l1 =>
      match find_max l1 with
      | None => Some (f a, a)
      | Some (n1, b) =>
          let n2 := f a in
          match le_lt_dec n1 n2 with
          | right _ => Some (n1, b)
          | left _ => Some (n2, a)
          end
      end
  end.

Theorem find_max_correct : forall l : list A, match find_max l with | None => l = nil | Some (a, b) => (In b l /\ a = f b) /\ (forall c : A, In c l -> f c <= f b) end.