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.
Inductive tree : Set :=
| leaf : tree
| node : nat -> tree -> tree -> tree.
Fixpoint tree_to_nat (t: tree) : nat :=
match t with
| leaf => 0
| node n t u => S (nat2_to_nat (n, nat2_to_nat ((tree_to_nat t), (tree_to_nat u))))
end.
Definition nat_to_tree : nat -> tree.

Lemma nat_tree_cancel {t} : nat_to_tree (tree_to_nat t) = t.