Fixpoint maxl (l : list nat) : nat :=
match l with
| nil => 0
| n :: l' => max n (maxl l')
end.

(* Specifications: *)
Lemma maxl_is_max :
forall l n, In n l -> n <= maxl l.
Lemma all_max_le l y :
(forall x, In x l -> x <= y) -> maxl l <= y.
Lemma maxl_app : forall (l1 l2 : list nat), maxl (l1 ++ l2) = max (maxl l1) (maxl l2).
Lemma in_maxl (l : list nat) : l<>nil -> In (maxl l) l.
Lemma all_maxl P xs: xs <> [] -> (forall x, In x xs -> P x) -> P (maxl xs).
Lemma maxl_le_maxl A f g (l : list A) :
(forall x, In x l -> f x <= g x) -> maxl (map f l) <= maxl (map g l).
Lemma maxl_map_const {A:Type} l (f: A → nat) n:
(∀ x, x ∈ l → (f x) = n) →
l ≠ [] → maxl (map f l) = n.
Lemma maxl_map_0 A l (f : A -> nat) : (* if n=0, we don't need l ≠ [] *)
(forall x, In x l -> (f x) = 0) ->
maxl (map f l) = 0.
Lemma maxl_map_plus_le A f g (l : list A) :
maxl (map (fun x => f x + g x) l) <= maxl (map f l) + maxl (map g l).
Lemma maxl_concat: forall l,
maxl (concat l) = maxl (map maxl l).
Lemma maxl_map_lt_iff (A:Type): forall (l:list A) f n,
0<n -> maxl (map f l) < n <-> (forall m, In m l -> (f m) < n).
Lemma maxl_map_le_iff (A:Type): forall (l:list A) f n,
maxl (map f l) <= n <-> (forall m, In m l -> (f m) <= n).
Lemma maxl_map_is_max_map (A:Type): forall (l:list A) f a,
In a l -> (f a) <= maxl (map f l).
Lemma maxl_eq_maxl {A:Type} f g (l:list A):
(∀ x : A, x ∈ l → f x = g x) →
maxl (map f l) = maxl (map g l).
Lemma incl_le_maxl :
forall (l1 l2 : list nat), incl l1 l2 -> maxl l1 <= maxl l2.
Lemma maxl_cons : forall n l, maxl (n::l) = max n (maxl l).
Lemma forall2_le_maxl :
forall (l1 l2 : list nat), Forall2 le l1 l2 -> maxl l1 <= maxl l2.
Lemma incl_flat_map (A B : Type) (f g : A -> list B) l :
(forall a, In a l -> incl (f a) (g a)) ->
incl (flat_map f l) (flat_map g l).