Proof
let T cs := containers_ok cs -> num_things cs <= num_containers cs in
list_ind T
(* I. case where there are no containers. *)
(fun _ => le_0_n 0)
(* II. case where there is more than one container. *)
(list_ind
(fun xs => forall cs, T cs -> T (xs :: cs))
(* II.A. case where the first container is empty. *)
(fun cs
(H  : T cs)
(H0 : containers_ok (nil :: cs))
=> let H1
:  num_things cs <= num_containers cs
:= H (Forall_tail nil cs H0) in
(le_S
(0 + num_things cs)
(num_containers cs)
(H1 || a <= num_containers cs @a by plus_O_n (num_things cs))))
(* II.B. case where the first container has one or more things in it. *)
(fun x0
=> list_ind
(fun xs => _ -> forall cs, T cs -> T ((x0 :: xs) :: cs))
(* II.B.1. case where the first container has only one thing in it. *)
(fun _ cs
(H  : T cs)
(H0 : containers_ok ((x0 :: nil) :: cs))
=> let H1
:  num_things cs <= num_containers cs
:= H (Forall_tail (x0 :: nil) cs H0) in
le_n_S (num_things cs) (num_containers cs) H1
|| a <= S (num_containers cs) @a by Nat.add_1_l (num_things cs))
(* II.B.2. case where the first container has two or more things in it. *)
(fun x1 xs _ _ cs
(H  : T cs)
(H0 : containers_ok ((x0 :: x1 :: xs) :: cs))
=> False_ind
(num_things ((x0 :: x1 :: xs) :: cs) <= num_containers ((x0 :: x1 :: xs) :: cs))
((Nat.nle_succ_0 (length xs))
(le_S_n (S (length xs)) 0 ((Forall_inv H0) : S (S (length xs)) <= 1)))))).
(** * III. The Pigeonhole Principle *)

(* Specifications: *)
(** This lemma proves that if we have a collection of containers and the number of things in the containers is greater than the number of the containers then not all of the containers can be empty or have only one thing in it. *)
Lemma lemma_0
: forall cs : containers,
num_things cs > num_containers cs ->
~ containers_ok cs.