Module nat2_Enumerable.
(* bijection from nat * nat to nat *)
Definition encode '(x, y) : nat :=
y + (nat_rec _ 0 (fun i m => (S i) + m) (y + x)).
(* bijection from nat to nat * nat *)
Definition decode (n : nat) : nat * nat :=
nat_rec _ (0, 0) (fun _ '(x, y) => if x is S x then (x, S y) else (S y, 0)) n.

Lemma decode_encode {xy: nat * nat} : decode (encode xy) = xy.