(* -*- coding: utf-8 -*- *)
(************************************************************************)
(*         *      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)         *)
(************************************************************************)
(** Properties of the injection from binary positive numbers to Peano natural numbers *)
(** Original development by Pierre Crégut, CNET, Lannion, France *)
Local Open Scope positive_scope.
Local Open Scope nat_scope.
Module Pos2Nat.
(** [Pos.to_nat] is a morphism for successor, addition, multiplication *)

(* Specifications: *)
Lemma inj_succ p : to_nat (succ p) = S (to_nat p).
Theorem inj_add p q : to_nat (p + q) = to_nat p + to_nat q.
Theorem inj_mul p q : to_nat (p * q) = to_nat p * to_nat q.
(** Mapping of xH, xO and xI through [Pos.to_nat] *)
Lemma inj_1 : to_nat 1 = 1.
Lemma inj_xO p : to_nat (xO p) = 2 * to_nat p.
Lemma inj_xI p : to_nat (xI p) = S (2 * to_nat p).
(** [Pos.to_nat] maps to the strictly positive subset of [nat] *)
Lemma is_succ p : exists n, to_nat p = S n.
(** [Pos.to_nat] is strictly positive *)
Lemma is_pos p : 0 < to_nat p.
(** [Pos.to_nat] is a bijection between [positive] and non-zero [nat], with [Pos.of_nat] as reciprocal. See [Nat2Pos.id] below for the dual equation. *)
Theorem id p : of_nat (to_nat p) = p.
(** [Pos.to_nat] is hence injective *)
Lemma inj p q : to_nat p = to_nat q -> p = q.
Lemma inj_iff p q : to_nat p = to_nat q <-> p = q.
(** [Pos.to_nat] is a morphism for comparison *)
Lemma inj_compare p q : (p ?= q)%positive = (to_nat p ?= to_nat q).
(** [Pos.to_nat] is a morphism for [lt], [le], etc *)
Lemma inj_lt p q : (p < q)%positive <-> to_nat p < to_nat q.
Lemma inj_le p q : (p <= q)%positive <-> to_nat p <= to_nat q.
Lemma inj_gt p q : (p > q)%positive <-> to_nat p > to_nat q.
Lemma inj_ge p q : (p >= q)%positive <-> to_nat p >= to_nat q.
(** [Pos.to_nat] is a morphism for subtraction *)
Theorem inj_sub p q : (q < p)%positive ->
to_nat (p - q) = to_nat p - to_nat q.
Theorem inj_sub_max p q :
to_nat (p - q) = Nat.max 1 (to_nat p - to_nat q).
Theorem inj_pred p : (1 < p)%positive ->
to_nat (pred p) = Nat.pred (to_nat p).
Theorem inj_pred_max p :
to_nat (pred p) = Nat.max 1 (Peano.pred (to_nat p)).