Module NatNat.
(* 0 + 1 + ... + n *)
Definition big_sum (n : nat) : nat := nat_rec _ 0 (fun i m => m + (S i)) n.
(* bijection from nat * nat to nat *)
Definition nat2_to_nat '(x, y) : nat := (big_sum (x + y)) + y.
Definition next_nat2 '(x, y) : nat * nat := if x is S x then (x, S y) else (S y, 0).
(* bijection from nat to nat * nat *)
Definition nat_to_nat2 (n : nat) : nat * nat := Nat.iter n next_nat2 (0, 0).
(* bijection from nat to list nat *)
Definition nat_to_list := Fix lt_wf _ (fun (n: nat) =>
match n return ((forall y : nat, y < n -> list nat) -> list nat) with
| 0 => fun _ => []
| S n => fun f => (fst (nat_to_nat2 n)) :: (f (snd (nat_to_nat2 n)) nat_to_nat2_snd_non_increasing)
end).
(* bijection from list nat to nat *)
Fixpoint list_to_nat (A: list nat) : nat :=
if A is a :: A then S (nat2_to_nat (a, list_to_nat A)) else 0.

Lemma nat_list_cancel {A} : nat_to_list (list_to_nat A) = A.