Section nat_Show.
Local Open Scope string.
Definition get_last_digit (n: nat): string :=
match n mod 10 with
| 0 => "0" | 1 => "1" | 2 => "2" | 3 => "3" | 4 => "4" | 5 => "5"
| 6 => "6" | 7 => "7" | 8 => "8" | _ => "9"
end.
Function string_of_nat_aux (acc: string) (n : nat) {measure id n}: string :=
let acc' := get_last_digit n ++ acc in
match n / 10 with
| 0 => acc'
| n' => string_of_nat_aux acc' n'
end.
intros _ n m ineq.
unfold id; simpl.
destruct n as [| n]; [simpl in *; easy |].
rewrite <- ineq; apply Nat.div_lt; lia.
Defined.
Definition string_of_nat := string_of_nat_aux "".
Ltac eq_fun H f :=
match type of H with
| ?x1 = ?x2 => assert (f x1 = f x2) by (rewrite H; reflexivity)
end.
Definition string_of_Z (n: Z) : string :=
match n with
| Z0 => "0"
| Zpos p => string_of_nat (Pos.to_nat p)
| Zneg p => "-" ++ string_of_nat (Pos.to_nat p)
end.
Fixpoint nat_to_string (n: nat): string :=
match n with
| O => ""
| S n => String (ascii_of_nat 49) (nat_to_string n)
end.

Lemma nat_to_string_inj:
forall (n m: nat), n <> m -> nat_to_string n <> nat_to_string m.