Built with Alectryon, running Coq+SerAPI v8.10.0+0.7.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
(* -*- coding: utf-8 -*- *)
(************************************************************************)
(*         *   The Coq Proof Assistant / The Coq Development Team       *)
(*  v      *   INRIA, CNRS and contributors - Copyright 1999-2018       *)
(* <O___,, *       (see CREDITS file for the list of authors)           *)
(*   \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)         *)
(************************************************************************)

Require Import BinPos PeanoNat.
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.
 Import Pos.
Pos.to_nat is a morphism for successor, addition, multiplication
p:positive

to_nat (succ p) = S (to_nat p)
p:positive

to_nat (succ p) = S (to_nat p)
p:positive

iter_op Init.Nat.add (succ p) 1 = S (iter_op Init.Nat.add p 1)
p:positive

1 + iter_op Init.Nat.add p 1 = S (iter_op Init.Nat.add p 1)
p:positive
forall x y z : nat, x + (y + z) = x + y + z
p:positive

forall x y z : nat, x + (y + z) = x + y + z
apply Nat.add_assoc. Qed.
p, q:positive

to_nat (p + q) = to_nat p + to_nat q
p, q:positive

to_nat (p + q) = to_nat p + to_nat q
p:positive

forall q : positive, to_nat (p + q) = to_nat p + to_nat q
q:positive

to_nat (1 + q) = to_nat 1 + to_nat q
p:positive
IHp:forall q0 : positive, to_nat (p + q0) = to_nat p + to_nat q0
q:positive
to_nat (succ p + q) = to_nat (succ p) + to_nat q
p:positive
IHp:forall q0 : positive, to_nat (p + q0) = to_nat p + to_nat q0
q:positive

to_nat (succ p + q) = to_nat (succ p) + to_nat q
now rewrite add_succ_l, !inj_succ, IHp. Qed.
p, q:positive

to_nat (p * q) = to_nat p * to_nat q
p, q:positive

to_nat (p * q) = to_nat p * to_nat q
p:positive

forall q : positive, to_nat (p * q) = to_nat p * to_nat q
p:positive
IHp:forall q0 : positive, to_nat (p * q0) = to_nat p * to_nat q0
q:positive

to_nat (succ p * q) = to_nat (succ p) * to_nat q
now rewrite mul_succ_l, inj_add, IHp, inj_succ. Qed.
Mapping of xH, xO and xI through Pos.to_nat

to_nat 1 = 1

to_nat 1 = 1
reflexivity. Qed.
p:positive

to_nat p~0 = 2 * to_nat p
p:positive

to_nat p~0 = 2 * to_nat p
exact (inj_mul 2 p). Qed.
p:positive

to_nat p~1 = S (2 * to_nat p)
p:positive

to_nat p~1 = S (2 * to_nat p)
now rewrite xI_succ_xO, inj_succ, inj_xO. Qed.
Pos.to_nat maps to the strictly positive subset of nat

forall p : positive, exists n : nat, to_nat p = S n

forall p : positive, exists n : nat, to_nat p = S n

exists n : nat, to_nat 1 = S n
p:positive
IHp:exists n : nat, to_nat p = S n
exists n : nat, to_nat (succ p) = S n
p:positive
IHp:exists n : nat, to_nat p = S n

exists n : nat, to_nat (succ p) = S n
p:positive
n:nat
Hn:to_nat p = S n

exists n0 : nat, to_nat (succ p) = S n0
p:positive
n:nat
Hn:to_nat p = S n

to_nat (succ p) = S (S n)
now rewrite inj_succ, Hn. Qed.
Pos.to_nat is strictly positive
p:positive

0 < to_nat p
p:positive

0 < to_nat p
p:positive
n:nat

0 < S n
auto with arith. Qed.
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.
p:positive

of_nat (to_nat p) = p
p:positive

of_nat (to_nat p) = p

of_nat (to_nat 1) = 1%positive
p:positive
IHp:of_nat (to_nat p) = p
of_nat (to_nat (succ p)) = succ p
p:positive
IHp:of_nat (to_nat p) = p

of_nat (to_nat (succ p)) = succ p
p:positive
IHp:of_nat (to_nat p) = p

of_nat (S (to_nat p)) = succ p
p:positive
IHp:of_nat (to_nat p) = p

of_nat (S (to_nat p)) = succ (of_nat (to_nat p))
now destruct (is_succ p) as (n,->). Qed.
Pos.to_nat is hence injective
p, q:positive

to_nat p = to_nat q -> p = q
p, q:positive

to_nat p = to_nat q -> p = q
p, q:positive
H:to_nat p = to_nat q

p = q
now rewrite <- (id p), <- (id q), H. Qed.
p, q:positive

to_nat p = to_nat q <-> p = q
p, q:positive

to_nat p = to_nat q <-> p = q
p, q:positive

to_nat p = to_nat q -> p = q
p, q:positive
p = q -> to_nat p = to_nat q
p, q:positive

p = q -> to_nat p = to_nat q
intros; now subst. Qed.
Pos.to_nat is a morphism for comparison
p, q:positive

(p ?= q)%positive = (to_nat p ?= to_nat q)
p, q:positive

(p ?= q)%positive = (to_nat p ?= to_nat q)
p:positive

forall q : positive, (p ?= q)%positive = (to_nat p ?= to_nat q)
q:positive

(1 ?= q)%positive = (to_nat 1 ?= to_nat q)
p:positive
IH:forall q0 : positive, (p ?= q0)%positive = (to_nat p ?= to_nat q0)
q:positive
(succ p ?= q)%positive = (to_nat (succ p) ?= to_nat q)
q:positive

(1 ?= q)%positive = (to_nat 1 ?= to_nat q)
q:positive
Hq:succ (pred q) = q

(1 ?= q)%positive = (to_nat 1 ?= to_nat q)
q:positive
Hq:succ (pred q) = q

Lt = (0 ?= to_nat (pred q))
q:positive
Hq:succ (pred q) = q

(0 ?= to_nat (pred q)) = Lt
apply Nat.compare_lt_iff, is_pos.
p:positive
IH:forall q0 : positive, (p ?= q0)%positive = (to_nat p ?= to_nat q0)
q:positive

(succ p ?= q)%positive = (to_nat (succ p) ?= to_nat q)
p:positive
IH:forall q : positive, (p ?= q)%positive = (to_nat p ?= to_nat q)

(succ p ?= 1)%positive = (to_nat (succ p) ?= to_nat 1)
p:positive
IH:forall q0 : positive, (p ?= q0)%positive = (to_nat p ?= to_nat q0)
q:positive
Hq:succ (pred q) = q
(succ p ?= q)%positive = (to_nat (succ p) ?= to_nat q)
p:positive
IH:forall q : positive, (p ?= q)%positive = (to_nat p ?= to_nat q)

CompOpp Lt = (S (to_nat p) ?= to_nat 1)
p:positive
IH:forall q0 : positive, (p ?= q0)%positive = (to_nat p ?= to_nat q0)
q:positive
Hq:succ (pred q) = q
(succ p ?= q)%positive = (to_nat (succ p) ?= to_nat q)
p:positive
IH:forall q : positive, (p ?= q)%positive = (to_nat p ?= to_nat q)

Gt = (to_nat p ?= 0)
p:positive
IH:forall q0 : positive, (p ?= q0)%positive = (to_nat p ?= to_nat q0)
q:positive
Hq:succ (pred q) = q
(succ p ?= q)%positive = (to_nat (succ p) ?= to_nat q)
p:positive
IH:forall q : positive, (p ?= q)%positive = (to_nat p ?= to_nat q)

(to_nat p ?= 0) = Gt
p:positive
IH:forall q0 : positive, (p ?= q0)%positive = (to_nat p ?= to_nat q0)
q:positive
Hq:succ (pred q) = q
(succ p ?= q)%positive = (to_nat (succ p) ?= to_nat q)
p:positive
IH:forall q0 : positive, (p ?= q0)%positive = (to_nat p ?= to_nat q0)
q:positive
Hq:succ (pred q) = q

(succ p ?= q)%positive = (to_nat (succ p) ?= to_nat q)
now rewrite <- Hq, 2 inj_succ, compare_succ_succ, IH. Qed.
Pos.to_nat is a morphism for lt, le, etc
p, q:positive

(p < q)%positive <-> to_nat p < to_nat q
p, q:positive

(p < q)%positive <-> to_nat p < to_nat q
p, q:positive

(p ?= q)%positive = Lt <-> to_nat p < to_nat q
now rewrite inj_compare, Nat.compare_lt_iff. Qed.
p, q:positive

(p <= q)%positive <-> to_nat p <= to_nat q
p, q:positive

(p <= q)%positive <-> to_nat p <= to_nat q
p, q:positive

(p ?= q)%positive <> Gt <-> to_nat p <= to_nat q
now rewrite inj_compare, Nat.compare_le_iff. Qed.
p, q:positive

(p > q)%positive <-> to_nat p > to_nat q
p, q:positive

(p > q)%positive <-> to_nat p > to_nat q
p, q:positive

(p ?= q)%positive = Gt <-> to_nat p > to_nat q
now rewrite inj_compare, Nat.compare_gt_iff. Qed.
p, q:positive

(p >= q)%positive <-> to_nat p >= to_nat q
p, q:positive

(p >= q)%positive <-> to_nat p >= to_nat q
p, q:positive

(p ?= q)%positive <> Lt <-> to_nat p >= to_nat q
now rewrite inj_compare, Nat.compare_ge_iff. Qed.
Pos.to_nat is a morphism for subtraction
p, q:positive

(q < p)%positive -> to_nat (p - q) = to_nat p - to_nat q
p, q:positive

(q < p)%positive -> to_nat (p - q) = to_nat p - to_nat q
p, q:positive
H:(q < p)%positive

to_nat (p - q) = to_nat p - to_nat q
p, q:positive
H:(q < p)%positive

to_nat (p - q) + to_nat q = to_nat p - to_nat q + to_nat q
p, q:positive
H:(q < p)%positive

to_nat (p - q) + to_nat q = to_nat p
p, q:positive
H:(q < p)%positive
to_nat q <= to_nat p
p, q:positive
H:(q < p)%positive

to_nat q <= to_nat p
now apply Nat.lt_le_incl, inj_lt. Qed.
p, q:positive

to_nat (p - q) = Nat.max 1 (to_nat p - to_nat q)
p, q:positive

to_nat (p - q) = Nat.max 1 (to_nat p - to_nat q)
p, q:positive
H:(q < p)%positive

to_nat (p - q) = Nat.max 1 (to_nat p - to_nat q)
p, q:positive
H:(p <= q)%positive
to_nat (p - q) = Nat.max 1 (to_nat p - to_nat q)
p, q:positive
H:(q < p)%positive

to_nat (p - q) = Nat.max 1 (to_nat p - to_nat q)
p, q:positive
H:(q < p)%positive

to_nat (p - q) = Nat.max 1 (to_nat (p - q))
now destruct (is_succ (p - q)) as (m,->).
p, q:positive
H:(p <= q)%positive

to_nat (p - q) = Nat.max 1 (to_nat p - to_nat q)
p, q:positive
H:(p <= q)%positive

to_nat 1 = Nat.max 1 (to_nat p - to_nat q)
p, q:positive
H:to_nat p - to_nat q = 0

to_nat 1 = Nat.max 1 (to_nat p - to_nat q)
now rewrite H. Qed.
p:positive

(1 < p)%positive -> to_nat (pred p) = Nat.pred (to_nat p)
p:positive

(1 < p)%positive -> to_nat (pred p) = Nat.pred (to_nat p)
p:positive
H:(1 < p)%positive

to_nat (pred p) = Nat.pred (to_nat p)
now rewrite <- Pos.sub_1_r, inj_sub, Nat.sub_1_r. Qed.
p:positive

to_nat (pred p) = Nat.max 1 (Init.Nat.pred (to_nat p))
p:positive

to_nat (pred p) = Nat.max 1 (Init.Nat.pred (to_nat p))
p:positive

to_nat (p - 1) = Nat.max 1 (to_nat p - 1)
apply inj_sub_max. Qed.
Pos.to_nat and other operations
p, q:positive

to_nat (min p q) = Nat.min (to_nat p) (to_nat q)
p, q:positive

to_nat (min p q) = Nat.min (to_nat p) (to_nat q)
p, q:positive

to_nat match (p ?= q)%positive with | Gt => q | _ => p end = Nat.min (to_nat p) (to_nat q)
p, q:positive

to_nat match to_nat p ?= to_nat q with | Gt => q | _ => p end = Nat.min (to_nat p) (to_nat q)
p, q:positive
H:to_nat p = to_nat q

Nat.min (to_nat p) (to_nat q) = to_nat p
p, q:positive
H:to_nat p < to_nat q
Nat.min (to_nat p) (to_nat q) = to_nat p
p, q:positive
H:to_nat q < to_nat p
Nat.min (to_nat p) (to_nat q) = to_nat q
p, q:positive
H:to_nat p = to_nat q

Nat.min (to_nat p) (to_nat q) = to_nat p
p, q:positive
H:to_nat p = to_nat q

to_nat p <= to_nat q
now rewrite H.
p, q:positive
H:to_nat p < to_nat q

Nat.min (to_nat p) (to_nat q) = to_nat p
now apply Nat.min_l, Nat.lt_le_incl.
p, q:positive
H:to_nat q < to_nat p

Nat.min (to_nat p) (to_nat q) = to_nat q
now apply Nat.min_r, Nat.lt_le_incl. Qed.
p, q:positive

to_nat (max p q) = Nat.max (to_nat p) (to_nat q)
p, q:positive

to_nat (max p q) = Nat.max (to_nat p) (to_nat q)
p, q:positive

to_nat match (p ?= q)%positive with | Gt => p | _ => q end = Nat.max (to_nat p) (to_nat q)
p, q:positive

to_nat match to_nat p ?= to_nat q with | Gt => p | _ => q end = Nat.max (to_nat p) (to_nat q)
p, q:positive
H:to_nat p = to_nat q

Nat.max (to_nat p) (to_nat q) = to_nat q
p, q:positive
H:to_nat p < to_nat q
Nat.max (to_nat p) (to_nat q) = to_nat q
p, q:positive
H:to_nat q < to_nat p
Nat.max (to_nat p) (to_nat q) = to_nat p
p, q:positive
H:to_nat p = to_nat q

Nat.max (to_nat p) (to_nat q) = to_nat q
p, q:positive
H:to_nat p = to_nat q

to_nat p <= to_nat q
now rewrite H.
p, q:positive
H:to_nat p < to_nat q

Nat.max (to_nat p) (to_nat q) = to_nat q
now apply Nat.max_r, Nat.lt_le_incl.
p, q:positive
H:to_nat q < to_nat p

Nat.max (to_nat p) (to_nat q) = to_nat p
now apply Nat.max_l, Nat.lt_le_incl. Qed.

forall (p : positive) (A : Type) (f : A -> A) (x : A), iter f x p = nat_rect (fun _ : nat => A) x (fun _ : nat => f) (to_nat p)

forall (p : positive) (A : Type) (f : A -> A) (x : A), iter f x p = nat_rect (fun _ : nat => A) x (fun _ : nat => f) (to_nat p)

forall (A : Type) (f : A -> A) (x : A), iter f x 1 = nat_rect (fun _ : nat => A) x (fun _ : nat => f) (to_nat 1)
p:positive
IHp:forall (A : Type) (f : A -> A) (x : A), iter f x p = nat_rect (fun _ : nat => A) x (fun _ : nat => f) (to_nat p)
forall (A : Type) (f : A -> A) (x : A), iter f x (succ p) = nat_rect (fun _ : nat => A) x (fun _ : nat => f) (to_nat (succ p))

forall (A : Type) (f : A -> A) (x : A), iter f x 1 = nat_rect (fun _ : nat => A) x (fun _ : nat => f) (to_nat 1)
trivial.
p:positive
IHp:forall (A : Type) (f : A -> A) (x : A), iter f x p = nat_rect (fun _ : nat => A) x (fun _ : nat => f) (to_nat p)

forall (A : Type) (f : A -> A) (x : A), iter f x (succ p) = nat_rect (fun _ : nat => A) x (fun _ : nat => f) (to_nat (succ p))
p:positive
IHp:forall (A0 : Type) (f0 : A0 -> A0) (x0 : A0), iter f0 x0 p = nat_rect (fun _ : nat => A0) x0 (fun _ : nat => f0) (to_nat p)
A:Type
f:A -> A
x:A

iter f x (succ p) = nat_rect (fun _ : nat => A) x (fun _ : nat => f) (to_nat (succ p))
p:positive
IHp:forall (A0 : Type) (f0 : A0 -> A0) (x0 : A0), iter f0 x0 p = nat_rect (fun _ : nat => A0) x0 (fun _ : nat => f0) (to_nat p)
A:Type
f:A -> A
x:A

f (iter f x p) = nat_rect (fun _ : nat => A) x (fun _ : nat => f) (S (to_nat p))
p:positive
IHp:forall (A0 : Type) (f0 : A0 -> A0) (x0 : A0), iter f0 x0 p = nat_rect (fun _ : nat => A0) x0 (fun _ : nat => f0) (to_nat p)
A:Type
f:A -> A
x:A

f (iter f x p) = f (nat_rect (fun _ : nat => A) x (fun _ : nat => f) (to_nat p))
p:positive
IHp:forall (A0 : Type) (f0 : A0 -> A0) (x0 : A0), iter f0 x0 p = nat_rect (fun _ : nat => A0) x0 (fun _ : nat => f0) (to_nat p)
A:Type
f:A -> A
x:A

iter f x p = nat_rect (fun _ : nat => A) x (fun _ : nat => f) (to_nat p)
apply IHp. Qed. End Pos2Nat. Module Nat2Pos.
Pos.of_nat is a bijection between non-zero nat and positive, with Pos.to_nat as reciprocal. See Pos2Nat.id above for the dual equation.
n:nat

n <> 0 -> Pos.to_nat (Pos.of_nat n) = n
n:nat

n <> 0 -> Pos.to_nat (Pos.of_nat n) = n

0 <> 0 -> Pos.to_nat (Pos.of_nat 0) = 0
n:nat
H:n <> 0 -> Pos.to_nat (Pos.of_nat n) = n
S n <> 0 -> Pos.to_nat (Pos.of_nat (S n)) = S n
n:nat
H:n <> 0 -> Pos.to_nat (Pos.of_nat n) = n

S n <> 0 -> Pos.to_nat (Pos.of_nat (S n)) = S n
n:nat
H:n <> 0 -> Pos.to_nat (Pos.of_nat n) = n

Pos.to_nat (Pos.of_nat (S n)) = S n
n:nat
H:n <> 0 -> Pos.to_nat (Pos.of_nat n) = n

Pos.to_nat match n with | 0%nat => 1 | S _ => Pos.succ (Pos.of_nat n) end = S n
H:0 <> 0 -> Pos.to_nat (Pos.of_nat 0) = 0

Pos.to_nat 1 = 1
n:nat
H:S n <> 0 -> Pos.to_nat (Pos.of_nat (S n)) = S n
Pos.to_nat (Pos.succ (Pos.of_nat (S n))) = S (S n)
n:nat
H:S n <> 0 -> Pos.to_nat (Pos.of_nat (S n)) = S n

Pos.to_nat (Pos.succ (Pos.of_nat (S n))) = S (S n)
n:nat
H:S n <> 0 -> Pos.to_nat (Pos.of_nat (S n)) = S n

S (Pos.to_nat (Pos.of_nat (S n))) = S (S n)
n:nat
H:S n <> 0 -> Pos.to_nat (Pos.of_nat (S n)) = S n

Pos.to_nat (Pos.of_nat (S n)) = S n
now apply H. Qed.
n:nat

Pos.to_nat (Pos.of_nat n) = Init.Nat.max 1 n
n:nat

Pos.to_nat (Pos.of_nat n) = Init.Nat.max 1 n

Pos.to_nat (Pos.of_nat 0) = Init.Nat.max 1 0
n:nat
Pos.to_nat (Pos.of_nat (S n)) = Init.Nat.max 1 (S n)
n:nat

Pos.to_nat (Pos.of_nat (S n)) = Init.Nat.max 1 (S n)
now rewrite id. Qed.
Pos.of_nat is hence injective for non-zero numbers
n, m:nat

n <> 0 -> m <> 0 -> Pos.of_nat n = Pos.of_nat m -> n = m
n, m:nat

n <> 0 -> m <> 0 -> Pos.of_nat n = Pos.of_nat m -> n = m
n, m:nat
Hn:n <> 0
Hm:m <> 0
H:Pos.of_nat n = Pos.of_nat m

n = m
now rewrite <- (id n), <- (id m), H. Qed.
n, m:nat

n <> 0 -> m <> 0 -> Pos.of_nat n = Pos.of_nat m <-> n = m
n, m:nat

n <> 0 -> m <> 0 -> Pos.of_nat n = Pos.of_nat m <-> n = m
n, m:nat
H:n <> 0
H0:m <> 0

Pos.of_nat n = Pos.of_nat m -> n = m
n, m:nat
H:n <> 0
H0:m <> 0
n = m -> Pos.of_nat n = Pos.of_nat m
n, m:nat
H:n <> 0
H0:m <> 0

n = m -> Pos.of_nat n = Pos.of_nat m
intros; now subst. Qed.
Usual operations are morphisms with respect to Pos.of_nat for non-zero numbers.
n:nat

n <> 0 -> Pos.of_nat (S n) = Pos.succ (Pos.of_nat n)
n:nat

n <> 0 -> Pos.of_nat (S n) = Pos.succ (Pos.of_nat n)
n:nat
H:n <> 0

Pos.of_nat (S n) = Pos.succ (Pos.of_nat n)
n:nat
H:n <> 0

Pos.to_nat (Pos.of_nat (S n)) = Pos.to_nat (Pos.succ (Pos.of_nat n))
now rewrite Pos2Nat.inj_succ, !id. Qed.
n:nat

Pos.of_nat (Init.Nat.pred n) = Pos.pred (Pos.of_nat n)
n:nat

Pos.of_nat (Init.Nat.pred n) = Pos.pred (Pos.of_nat n)
n:nat

Pos.of_nat (Init.Nat.pred (S (S n))) = Pos.pred (Pos.of_nat (S (S n)))
n:nat

match n with | 0 => 1%positive | S _ => Pos.succ (Pos.of_nat n) end = Pos.pred (Pos.succ match n with | 0%nat => 1 | S _ => Pos.succ (Pos.of_nat n) end)
now rewrite Pos.pred_succ. Qed.
n, m:nat

n <> 0 -> m <> 0 -> Pos.of_nat (n + m) = (Pos.of_nat n + Pos.of_nat m)%positive
n, m:nat

n <> 0 -> m <> 0 -> Pos.of_nat (n + m) = (Pos.of_nat n + Pos.of_nat m)%positive
n, m:nat
Hn:n <> 0
Hm:m <> 0

Pos.of_nat (n + m) = (Pos.of_nat n + Pos.of_nat m)%positive
n, m:nat
Hn:n <> 0
Hm:m <> 0

Pos.to_nat (Pos.of_nat (n + m)) = Pos.to_nat (Pos.of_nat n + Pos.of_nat m)
n, m:nat
Hn:n <> 0
Hm:m <> 0

n + m <> 0
n, m:nat
Hn:n <> 0
Hm:m <> 0
H:n + m = 0

False
m:nat
Hn:0 <> 0
Hm:m <> 0
H:0 + m = 0

False
n, m:nat
Hn:S n <> 0
Hm:m <> 0
H:S n + m = 0
False
n, m:nat
Hn:S n <> 0
Hm:m <> 0
H:S n + m = 0

False
now simpl in H. Qed.
n, m:nat

n <> 0 -> m <> 0 -> Pos.of_nat (n * m) = (Pos.of_nat n * Pos.of_nat m)%positive
n, m:nat

n <> 0 -> m <> 0 -> Pos.of_nat (n * m) = (Pos.of_nat n * Pos.of_nat m)%positive
n, m:nat
Hn:n <> 0
Hm:m <> 0

Pos.of_nat (n * m) = (Pos.of_nat n * Pos.of_nat m)%positive
n, m:nat
Hn:n <> 0
Hm:m <> 0

Pos.to_nat (Pos.of_nat (n * m)) = Pos.to_nat (Pos.of_nat n * Pos.of_nat m)
n, m:nat
Hn:n <> 0
Hm:m <> 0

n * m <> 0
n, m:nat
Hn:n <> 0
Hm:m <> 0
H:n * m = 0

False
n, m:nat
Hn:n <> 0
Hm:m <> 0
H:n = 0 \/ m = 0

False
n, m:nat
Hn:n <> 0
Hm:m <> 0
H:n = 0

False
n, m:nat
Hn:n <> 0
Hm:m <> 0
H:m = 0
False
n, m:nat
Hn:n <> 0
Hm:m <> 0
H:m = 0

False
now elim Hm. Qed.
n, m:nat

n <> 0 -> m <> 0 -> (n ?= m) = (Pos.of_nat n ?= Pos.of_nat m)%positive
n, m:nat

n <> 0 -> m <> 0 -> (n ?= m) = (Pos.of_nat n ?= Pos.of_nat m)%positive
n, m:nat
Hn:n <> 0
Hm:m <> 0

(n ?= m) = (Pos.of_nat n ?= Pos.of_nat m)%positive
rewrite Pos2Nat.inj_compare, !id; trivial. Qed.
n, m:nat

m <> 0 -> Pos.of_nat (n - m) = (Pos.of_nat n - Pos.of_nat m)%positive
n, m:nat

m <> 0 -> Pos.of_nat (n - m) = (Pos.of_nat n - Pos.of_nat m)%positive
n, m:nat
Hm:m <> 0

Pos.of_nat (n - m) = (Pos.of_nat n - Pos.of_nat m)%positive
n, m:nat
Hm:m <> 0

Pos.to_nat (Pos.of_nat (n - m)) = Pos.to_nat (Pos.of_nat n - Pos.of_nat m)
n, m:nat
Hm:m <> 0

Pos.to_nat (Pos.of_nat (n - m)) = Nat.max 1 (Pos.to_nat (Pos.of_nat n) - Pos.to_nat (Pos.of_nat m))
n, m:nat
Hm:m <> 0

Pos.to_nat (Pos.of_nat (n - m)) = Nat.max 1 (Pos.to_nat (Pos.of_nat n) - m)
n, m:nat
Hm:m <> 0

Init.Nat.max 1 (n - m) = Nat.max 1 (Init.Nat.max 1 n - m)
destruct n, m; trivial. Qed.
n, m:nat

Pos.of_nat (Init.Nat.min n m) = Pos.min (Pos.of_nat n) (Pos.of_nat m)
n, m:nat

Pos.of_nat (Init.Nat.min n m) = Pos.min (Pos.of_nat n) (Pos.of_nat m)
m:nat

Pos.of_nat (Init.Nat.min 0 m) = Pos.min (Pos.of_nat 0) (Pos.of_nat m)
n, m:nat
Pos.of_nat (Init.Nat.min (S n) m) = Pos.min (Pos.of_nat (S n)) (Pos.of_nat m)
m:nat

1%positive = Pos.min 1 (Pos.of_nat m)
n, m:nat
Pos.of_nat (Init.Nat.min (S n) m) = Pos.min (Pos.of_nat (S n)) (Pos.of_nat m)
m:nat

Pos.min 1 (Pos.of_nat m) = 1%positive
n, m:nat
Pos.of_nat (Init.Nat.min (S n) m) = Pos.min (Pos.of_nat (S n)) (Pos.of_nat m)
n, m:nat

Pos.of_nat (Init.Nat.min (S n) m) = Pos.min (Pos.of_nat (S n)) (Pos.of_nat m)
n:nat

Pos.of_nat (Init.Nat.min (S n) 0) = Pos.min (Pos.of_nat (S n)) (Pos.of_nat 0)
n, m:nat
Pos.of_nat (Init.Nat.min (S n) (S m)) = Pos.min (Pos.of_nat (S n)) (Pos.of_nat (S m))
n:nat

1%positive = Pos.min match n with | 0%nat => 1 | S _ => Pos.succ (Pos.of_nat n) end 1
n, m:nat
Pos.of_nat (Init.Nat.min (S n) (S m)) = Pos.min (Pos.of_nat (S n)) (Pos.of_nat (S m))
n:nat

Pos.min match n with | 0%nat => 1 | S _ => Pos.succ (Pos.of_nat n) end 1 = 1%positive
n, m:nat
Pos.of_nat (Init.Nat.min (S n) (S m)) = Pos.min (Pos.of_nat (S n)) (Pos.of_nat (S m))
n, m:nat

Pos.of_nat (Init.Nat.min (S n) (S m)) = Pos.min (Pos.of_nat (S n)) (Pos.of_nat (S m))
n, m:nat

Pos.of_nat (Init.Nat.min (S n) (S m)) = match (Pos.of_nat (S n) ?= Pos.of_nat (S m))%positive with | Gt => Pos.of_nat (S m) | _ => Pos.of_nat (S n) end
n, m:nat

Pos.of_nat (Init.Nat.min (S n) (S m)) = match S n ?= S m with | Gt => Pos.of_nat (S m) | _ => Pos.of_nat (S n) end
n, m:nat
H:S n = S m

S n <= S m
n, m:nat
H:S n < S m
S n <= S m
n, m:nat
H:S m < S n
S m <= S n
n, m:nat
H:S n < S m

S n <= S m
n, m:nat
H:S m < S n
S m <= S n
n, m:nat
H:S m < S n

S m <= S n
now apply Nat.lt_le_incl. Qed.
n, m:nat

Pos.of_nat (Init.Nat.max n m) = Pos.max (Pos.of_nat n) (Pos.of_nat m)
n, m:nat

Pos.of_nat (Init.Nat.max n m) = Pos.max (Pos.of_nat n) (Pos.of_nat m)
m:nat

Pos.of_nat (Init.Nat.max 0 m) = Pos.max (Pos.of_nat 0) (Pos.of_nat m)
n, m:nat
Pos.of_nat (Init.Nat.max (S n) m) = Pos.max (Pos.of_nat (S n)) (Pos.of_nat m)
m:nat

Pos.of_nat m = Pos.max 1 (Pos.of_nat m)
n, m:nat
Pos.of_nat (Init.Nat.max (S n) m) = Pos.max (Pos.of_nat (S n)) (Pos.of_nat m)
m:nat

Pos.max 1 (Pos.of_nat m) = Pos.of_nat m
n, m:nat
Pos.of_nat (Init.Nat.max (S n) m) = Pos.max (Pos.of_nat (S n)) (Pos.of_nat m)
n, m:nat

Pos.of_nat (Init.Nat.max (S n) m) = Pos.max (Pos.of_nat (S n)) (Pos.of_nat m)
n:nat

Pos.of_nat (Init.Nat.max (S n) 0) = Pos.max (Pos.of_nat (S n)) (Pos.of_nat 0)
n, m:nat
Pos.of_nat (Init.Nat.max (S n) (S m)) = Pos.max (Pos.of_nat (S n)) (Pos.of_nat (S m))
n:nat

match n with | 0 => 1%positive | S _ => Pos.succ (Pos.of_nat n) end = Pos.max match n with | 0%nat => 1 | S _ => Pos.succ (Pos.of_nat n) end 1
n, m:nat
Pos.of_nat (Init.Nat.max (S n) (S m)) = Pos.max (Pos.of_nat (S n)) (Pos.of_nat (S m))
n:nat

Pos.max match n with | 0%nat => 1 | S _ => Pos.succ (Pos.of_nat n) end 1 = match n with | 0 => 1%positive | S _ => Pos.succ (Pos.of_nat n) end
n, m:nat
Pos.of_nat (Init.Nat.max (S n) (S m)) = Pos.max (Pos.of_nat (S n)) (Pos.of_nat (S m))
n, m:nat

Pos.of_nat (Init.Nat.max (S n) (S m)) = Pos.max (Pos.of_nat (S n)) (Pos.of_nat (S m))
n, m:nat

Pos.of_nat (Init.Nat.max (S n) (S m)) = match (Pos.of_nat (S n) ?= Pos.of_nat (S m))%positive with | Gt => Pos.of_nat (S n) | _ => Pos.of_nat (S m) end
n, m:nat

Pos.of_nat (Init.Nat.max (S n) (S m)) = match S n ?= S m with | Gt => Pos.of_nat (S n) | _ => Pos.of_nat (S m) end
n, m:nat
H:S n = S m

S n <= S m
n, m:nat
H:S n < S m
S n <= S m
n, m:nat
H:S m < S n
S m <= S n
n, m:nat
H:S n < S m

S n <= S m
n, m:nat
H:S m < S n
S m <= S n
n, m:nat
H:S m < S n

S m <= S n
now apply Nat.lt_le_incl. Qed. End Nat2Pos. (**********************************************************************)
Properties of the shifted injection from Peano natural numbers to binary positive numbers
Module Pos2SuccNat.
Composition of Pos.to_nat and Pos.of_succ_nat is successor on positive
p:positive

Pos.of_succ_nat (Pos.to_nat p) = Pos.succ p
p:positive

Pos.of_succ_nat (Pos.to_nat p) = Pos.succ p
p:positive

Pos.of_nat (Pos.to_nat (Pos.succ p)) = Pos.succ p
apply Pos2Nat.id. Qed.
Composition of Pos.to_nat, Pos.of_succ_nat and Pos.pred is identity on positive
p:positive

Pos.pred (Pos.of_succ_nat (Pos.to_nat p)) = p
p:positive

Pos.pred (Pos.of_succ_nat (Pos.to_nat p)) = p
now rewrite id_succ, Pos.pred_succ. Qed. End Pos2SuccNat. Module SuccNat2Pos.
Composition of Pos.of_succ_nat and Pos.to_nat is successor on nat
n:nat

Pos.to_nat (Pos.of_succ_nat n) = S n
n:nat

Pos.to_nat (Pos.of_succ_nat n) = S n
n:nat

Pos.to_nat (Pos.of_nat (S n)) = S n
now apply Nat2Pos.id. Qed.
n:nat

Init.Nat.pred (Pos.to_nat (Pos.of_succ_nat n)) = n
n:nat

Init.Nat.pred (Pos.to_nat (Pos.of_succ_nat n)) = n
now rewrite id_succ. Qed.
Pos.of_succ_nat is hence injective
n, m:nat

Pos.of_succ_nat n = Pos.of_succ_nat m -> n = m
n, m:nat

Pos.of_succ_nat n = Pos.of_succ_nat m -> n = m
n, m:nat
H:Pos.of_succ_nat n = Pos.of_succ_nat m

n = m
n, m:nat
H:Pos.to_nat (Pos.of_succ_nat n) = Pos.to_nat (Pos.of_succ_nat m)

n = m
n, m:nat
H:S n = S m

n = m
now injection H. Qed.
n, m:nat

Pos.of_succ_nat n = Pos.of_succ_nat m <-> n = m
n, m:nat

Pos.of_succ_nat n = Pos.of_succ_nat m <-> n = m
n, m:nat

Pos.of_succ_nat n = Pos.of_succ_nat m -> n = m
n, m:nat
n = m -> Pos.of_succ_nat n = Pos.of_succ_nat m
n, m:nat

n = m -> Pos.of_succ_nat n = Pos.of_succ_nat m
intros; now subst. Qed.
Another formulation
n:nat
p:positive

Pos.to_nat p = S n -> Pos.of_succ_nat n = p
n:nat
p:positive

Pos.to_nat p = S n -> Pos.of_succ_nat n = p
n:nat
p:positive
H:Pos.to_nat p = S n

Pos.of_succ_nat n = p
n:nat
p:positive
H:Pos.to_nat p = S n

Pos.to_nat (Pos.of_succ_nat n) = Pos.to_nat p
now rewrite id_succ. Qed.
Successor and comparison are morphisms with respect to Pos.of_succ_nat
n:nat

Pos.of_succ_nat (S n) = Pos.succ (Pos.of_succ_nat n)
n:nat

Pos.of_succ_nat (S n) = Pos.succ (Pos.of_succ_nat n)
n:nat

Pos.to_nat (Pos.of_succ_nat (S n)) = Pos.to_nat (Pos.succ (Pos.of_succ_nat n))
now rewrite Pos2Nat.inj_succ, !id_succ. Qed.
n, m:nat

(n ?= m) = (Pos.of_succ_nat n ?= Pos.of_succ_nat m)%positive
n, m:nat

(n ?= m) = (Pos.of_succ_nat n ?= Pos.of_succ_nat m)%positive
rewrite Pos2Nat.inj_compare, !id_succ; trivial. Qed.
Other operations, for instance Pos.add and plus aren't directly related this way (we would need to compensate for the successor hidden in Pos.of_succ_nat
End SuccNat2Pos.
For compatibility, old names and old-style lemmas
Notation Psucc_S := Pos2Nat.inj_succ (only parsing).
Notation Pplus_plus := Pos2Nat.inj_add (only parsing).
Notation Pmult_mult := Pos2Nat.inj_mul (only parsing).
Notation Pcompare_nat_compare := Pos2Nat.inj_compare (only parsing).
Notation nat_of_P_xH := Pos2Nat.inj_1 (only parsing).
Notation nat_of_P_xO := Pos2Nat.inj_xO (only parsing).
Notation nat_of_P_xI := Pos2Nat.inj_xI (only parsing).
Notation nat_of_P_is_S := Pos2Nat.is_succ (only parsing).
Notation nat_of_P_pos := Pos2Nat.is_pos (only parsing).
Notation nat_of_P_inj_iff := Pos2Nat.inj_iff (only parsing).
Notation nat_of_P_inj := Pos2Nat.inj (only parsing).
Notation Plt_lt := Pos2Nat.inj_lt (only parsing).
Notation Pgt_gt := Pos2Nat.inj_gt (only parsing).
Notation Ple_le := Pos2Nat.inj_le (only parsing).
Notation Pge_ge := Pos2Nat.inj_ge (only parsing).
Notation Pminus_minus := Pos2Nat.inj_sub (only parsing).
Notation iter_nat_of_P := @Pos2Nat.inj_iter (only parsing).

Notation nat_of_P_of_succ_nat := SuccNat2Pos.id_succ (only parsing).
Notation P_of_succ_nat_of_P := Pos2SuccNat.id_succ (only parsing).

Notation nat_of_P_succ_morphism := Pos2Nat.inj_succ (only parsing).
Notation nat_of_P_plus_morphism := Pos2Nat.inj_add (only parsing).
Notation nat_of_P_mult_morphism := Pos2Nat.inj_mul (only parsing).
Notation nat_of_P_compare_morphism := Pos2Nat.inj_compare (only parsing).
Notation lt_O_nat_of_P := Pos2Nat.is_pos (only parsing).
Notation ZL4 := Pos2Nat.is_succ (only parsing).
Notation nat_of_P_o_P_of_succ_nat_eq_succ := SuccNat2Pos.id_succ (only parsing).
Notation P_of_succ_nat_o_nat_of_P_eq_succ := Pos2SuccNat.id_succ (only parsing).
Notation pred_o_P_of_succ_nat_o_nat_of_P_eq_id := Pos2SuccNat.pred_id (only parsing).

p, q:positive

Pos.compare_cont Eq p q = Gt -> Pos.to_nat (p - q) = Pos.to_nat p - Pos.to_nat q
Proof (fun H => Pos2Nat.inj_sub p q (Pos.gt_lt _ _ H)).
p, q:positive

Pos.compare_cont Eq p q = Lt -> Pos.to_nat p < Pos.to_nat q
Proof (proj1 (Pos2Nat.inj_lt p q)).
p, q:positive

Pos.compare_cont Eq p q = Gt -> Pos.to_nat p > Pos.to_nat q
Proof (proj1 (Pos2Nat.inj_gt p q)).
p, q:positive

Pos.to_nat p < Pos.to_nat q -> Pos.compare_cont Eq p q = Lt
Proof (proj2 (Pos2Nat.inj_lt p q)).
p, q:positive

Pos.to_nat p > Pos.to_nat q -> Pos.compare_cont Eq p q = Gt
Proof (proj2 (Pos2Nat.inj_gt p q)).
Old intermediate results about Pmult_nat
Section ObsoletePmultNat.


forall (p : positive) (n : nat), Pos.iter_op Init.Nat.add p n = Pos.to_nat p * n

forall (p : positive) (n : nat), Pos.iter_op Init.Nat.add p n = Pos.to_nat p * n
p:positive
IHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0
n:nat

n + Pos.iter_op Init.Nat.add p (n + n) = n + Pos.iter_op Init.Nat.add p 2 * n
p:positive
IHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0
n:nat
Pos.iter_op Init.Nat.add p (n + n) = Pos.iter_op Init.Nat.add p 2 * n
n:nat
n = n + 0
p:positive
IHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0
n:nat

Pos.iter_op Init.Nat.add p (n + n) = Pos.iter_op Init.Nat.add p 2 * n
p:positive
IHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0
n:nat
Pos.iter_op Init.Nat.add p (n + n) = Pos.iter_op Init.Nat.add p 2 * n
n:nat
n = n + 0
p:positive
IHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0
n:nat

Pos.to_nat p * (n + n) = Pos.to_nat p * 2 * n
p:positive
IHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0
n:nat
Pos.iter_op Init.Nat.add p (n + n) = Pos.iter_op Init.Nat.add p 2 * n
n:nat
n = n + 0
p:positive
IHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0
n:nat

Pos.to_nat p * (n + n) = Pos.to_nat p * (2 * n)
p:positive
IHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0
n:nat
Pos.iter_op Init.Nat.add p (n + n) = Pos.iter_op Init.Nat.add p 2 * n
n:nat
n = n + 0
p:positive
IHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0
n:nat

n + n = 2 * n
p:positive
IHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0
n:nat
Pos.iter_op Init.Nat.add p (n + n) = Pos.iter_op Init.Nat.add p 2 * n
n:nat
n = n + 0
p:positive
IHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0
n:nat

n + n = n + (n + 0)
p:positive
IHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0
n:nat
Pos.iter_op Init.Nat.add p (n + n) = Pos.iter_op Init.Nat.add p 2 * n
n:nat
n = n + 0
p:positive
IHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0
n:nat

Pos.iter_op Init.Nat.add p (n + n) = Pos.iter_op Init.Nat.add p 2 * n
n:nat
n = n + 0
p:positive
IHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0
n:nat

Pos.to_nat p * (n + n) = Pos.to_nat p * 2 * n
n:nat
n = n + 0
p:positive
IHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0
n:nat

Pos.to_nat p * (n + n) = Pos.to_nat p * (2 * n)
n:nat
n = n + 0
p:positive
IHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0
n:nat

n + n = 2 * n
n:nat
n = n + 0
p:positive
IHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0
n:nat

n + n = n + (n + 0)
n:nat
n = n + 0
n:nat

n = n + 0
n:nat

n = n + 0
now rewrite Nat.add_0_r. Qed.

forall (p : positive) (n : nat), Pos.iter_op Init.Nat.add (Pos.succ p) n = n + Pos.iter_op Init.Nat.add p n

forall (p : positive) (n : nat), Pos.iter_op Init.Nat.add (Pos.succ p) n = n + Pos.iter_op Init.Nat.add p n
p:positive
n:nat

Pos.iter_op Init.Nat.add (Pos.succ p) n = n + Pos.iter_op Init.Nat.add p n
now rewrite !Pmult_nat_mult, Pos2Nat.inj_succ. Qed.

forall (p q : positive) (n : nat), Pos.iter_op Init.Nat.add (p + q) n = Pos.iter_op Init.Nat.add p n + Pos.iter_op Init.Nat.add q n

forall (p q : positive) (n : nat), Pos.iter_op Init.Nat.add (p + q) n = Pos.iter_op Init.Nat.add p n + Pos.iter_op Init.Nat.add q n
p, q:positive
n:nat

Pos.iter_op Init.Nat.add (p + q) n = Pos.iter_op Init.Nat.add p n + Pos.iter_op Init.Nat.add q n
p, q:positive
n:nat

(Pos.to_nat p + Pos.to_nat q) * n = Pos.to_nat p * n + Pos.to_nat q * n
apply Nat.mul_add_distr_r. Qed.

forall (p q : positive) (n : nat), Pos.iter_op Init.Nat.add (Pos.add_carry p q) n = n + Pos.iter_op Init.Nat.add (p + q) n

forall (p q : positive) (n : nat), Pos.iter_op Init.Nat.add (Pos.add_carry p q) n = n + Pos.iter_op Init.Nat.add (p + q) n
p, q:positive
n:nat

Pos.iter_op Init.Nat.add (Pos.add_carry p q) n = n + Pos.iter_op Init.Nat.add (p + q) n
now rewrite Pos.add_carry_spec, Pmult_nat_succ_morphism. Qed.

forall (p : positive) (n : nat), Pos.iter_op Init.Nat.add p (n + n) = Pos.iter_op Init.Nat.add p n + Pos.iter_op Init.Nat.add p n

forall (p : positive) (n : nat), Pos.iter_op Init.Nat.add p (n + n) = Pos.iter_op Init.Nat.add p n + Pos.iter_op Init.Nat.add p n
p:positive
n:nat

Pos.iter_op Init.Nat.add p (n + n) = Pos.iter_op Init.Nat.add p n + Pos.iter_op Init.Nat.add p n
p:positive
n:nat

Pos.to_nat p * (n + n) = Pos.to_nat p * n + Pos.to_nat p * n
apply Nat.mul_add_distr_l. Qed.

forall p : positive, Pos.iter_op Init.Nat.add p 2 = Pos.to_nat p + Pos.to_nat p

forall p : positive, Pos.iter_op Init.Nat.add p 2 = Pos.to_nat p + Pos.to_nat p
p:positive

Pos.iter_op Init.Nat.add p 2 = Pos.to_nat p + Pos.to_nat p
p:positive

2 * Pos.to_nat p = Pos.to_nat p + Pos.to_nat p
p:positive

Pos.to_nat p + (Pos.to_nat p + 0) = Pos.to_nat p + Pos.to_nat p
now rewrite Nat.add_0_r. Qed.

forall (p : positive) (n : nat), n <= Pos.iter_op Init.Nat.add p n

forall (p : positive) (n : nat), n <= Pos.iter_op Init.Nat.add p n
p:positive
n:nat

n <= Pos.iter_op Init.Nat.add p n
p:positive
n:nat

n <= Pos.to_nat p * n
p:positive
n:nat

n <= 1 * n
p:positive
n:nat
1 * n <= Pos.to_nat p * n
p:positive
n:nat

1 * n <= Pos.to_nat p * n
p:positive
n:nat

1 <= Pos.to_nat p
apply Pos2Nat.is_pos. Qed. End ObsoletePmultNat.