(************************************************************************)
(*         *      The Rocq Prover / The Rocq Development Team           *)
(*  v      *         Copyright INRIA, CNRS and contributors             *)
(* <O___,, * (see version control and CREDITS file for authors & dates) *)
(*   \VV/  **************************************************************)
(*    //   *    This file is distributed under the terms of the         *)
(*         *     GNU Lesser General Public License Version 2.1          *)
(*         *     (see LICENSE file for the text of the license)         *)
(************************************************************************)
(** * HexadecimalNat  Proofs that conversions between hexadecimal numbers and [nat] are bijections. *)
Module Unsigned.
(** A few helper functions used during proofs *)
Definition hd d :=
match d with
| Nil => 0x0
| D0 _ => 0x0
| D1 _ => 0x1
| D2 _ => 0x2
| D3 _ => 0x3
| D4 _ => 0x4
| D5 _ => 0x5
| D6 _ => 0x6
| D7 _ => 0x7
| D8 _ => 0x8
| D9 _ => 0x9
| Da _ => 0xa
| Db _ => 0xb
| Dc _ => 0xc
| Dd _ => 0xd
| De _ => 0xe
| Df _ => 0xf
end.
Definition tl d :=
match d with
| Nil => d
| D0 d | D1 d | D2 d | D3 d | D4 d | D5 d | D6 d | D7 d | D8 d | D9 d
| Da d | Db d | Dc d | Dd d | De d | Df d => d
end.
Fixpoint usize (d:uint) : nat :=
match d with
| Nil => 0
| D0 d => S (usize d)
| D1 d => S (usize d)
| D2 d => S (usize d)
| D3 d => S (usize d)
| D4 d => S (usize d)
| D5 d => S (usize d)
| D6 d => S (usize d)
| D7 d => S (usize d)
| D8 d => S (usize d)
| D9 d => S (usize d)
| Da d => S (usize d)
| Db d => S (usize d)
| Dc d => S (usize d)
| Dd d => S (usize d)
| De d => S (usize d)
| Df d => S (usize d)
end.
(** A direct version of [to_little_uint], not tail-recursive *)
Fixpoint to_lu n :=
match n with
| 0 => Hexadecimal.zero
| S n => Little.succ (to_lu n)
end.
(** A direct version of [of_little_uint] *)
Fixpoint of_lu (d:uint) : nat :=
match d with
| Nil => 0x0
| D0 d => 0x10 * of_lu d
| D1 d => 0x1 + 0x10 * of_lu d
| D2 d => 0x2 + 0x10 * of_lu d
| D3 d => 0x3 + 0x10 * of_lu d
| D4 d => 0x4 + 0x10 * of_lu d
| D5 d => 0x5 + 0x10 * of_lu d
| D6 d => 0x6 + 0x10 * of_lu d
| D7 d => 0x7 + 0x10 * of_lu d
| D8 d => 0x8 + 0x10 * of_lu d
| D9 d => 0x9 + 0x10 * of_lu d
| Da d => 0xa + 0x10 * of_lu d
| Db d => 0xb + 0x10 * of_lu d
| Dc d => 0xc + 0x10 * of_lu d
| Dd d => 0xd + 0x10 * of_lu d
| De d => 0xe + 0x10 * of_lu d
| Df d => 0xf + 0x10 * of_lu d
end.
(** Properties of [to_lu] *)

(* Specifications: *)
Lemma to_lu_succ n : to_lu (S n) = Little.succ (to_lu n).
Lemma to_little_uint_succ n d :
Nat.to_little_hex_uint n (Little.succ d) =
Little.succ (Nat.to_little_hex_uint n d).
Lemma to_lu_equiv n :
to_lu n = Nat.to_little_hex_uint n zero.
Lemma to_uint_alt n :
Nat.to_hex_uint n = rev (to_lu n).