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:positiveto_nat (succ p) = S (to_nat p)p:positiveto_nat (succ p) = S (to_nat p)p:positiveiter_op Init.Nat.add (succ p) 1 = S (iter_op Init.Nat.add p 1)p:positive1 + iter_op Init.Nat.add p 1 = S (iter_op Init.Nat.add p 1)p:positiveforall x y z : nat, x + (y + z) = x + y + zapply Nat.add_assoc. Qed.p:positiveforall x y z : nat, x + (y + z) = x + y + zp, q:positiveto_nat (p + q) = to_nat p + to_nat qp, q:positiveto_nat (p + q) = to_nat p + to_nat qp:positiveforall q : positive, to_nat (p + q) = to_nat p + to_nat qq:positiveto_nat (1 + q) = to_nat 1 + to_nat qp:positiveIHp:forall q0 : positive, to_nat (p + q0) = to_nat p + to_nat q0q:positiveto_nat (succ p + q) = to_nat (succ p) + to_nat qnow rewrite add_succ_l, !inj_succ, IHp. Qed.p:positiveIHp:forall q0 : positive, to_nat (p + q0) = to_nat p + to_nat q0q:positiveto_nat (succ p + q) = to_nat (succ p) + to_nat qp, q:positiveto_nat (p * q) = to_nat p * to_nat qp, q:positiveto_nat (p * q) = to_nat p * to_nat qp:positiveforall q : positive, to_nat (p * q) = to_nat p * to_nat qnow rewrite mul_succ_l, inj_add, IHp, inj_succ. Qed.p:positiveIHp:forall q0 : positive, to_nat (p * q0) = to_nat p * to_nat q0q:positiveto_nat (succ p * q) = to_nat (succ p) * to_nat q
Mapping of xH, xO and xI through Pos.to_nat
to_nat 1 = 1reflexivity. Qed.to_nat 1 = 1p:positiveto_nat p~0 = 2 * to_nat pexact (inj_mul 2 p). Qed.p:positiveto_nat p~0 = 2 * to_nat pp:positiveto_nat p~1 = S (2 * to_nat p)now rewrite xI_succ_xO, inj_succ, inj_xO. Qed.p:positiveto_nat p~1 = S (2 * to_nat p)
Pos.to_nat maps to the strictly positive subset of nat
forall p : positive, exists n : nat, to_nat p = S nforall p : positive, exists n : nat, to_nat p = S nexists n : nat, to_nat 1 = S np:positiveIHp:exists n : nat, to_nat p = S nexists n : nat, to_nat (succ p) = S np:positiveIHp:exists n : nat, to_nat p = S nexists n : nat, to_nat (succ p) = S np:positiven:natHn:to_nat p = S nexists n0 : nat, to_nat (succ p) = S n0now rewrite inj_succ, Hn. Qed.p:positiven:natHn:to_nat p = S nto_nat (succ p) = S (S n)
Pos.to_nat is strictly positive
p:positive0 < to_nat pp:positive0 < to_nat pauto with arith. Qed.p:positiven:nat0 < S n
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:positiveof_nat (to_nat p) = pp:positiveof_nat (to_nat p) = pof_nat (to_nat 1) = 1%positivep:positiveIHp:of_nat (to_nat p) = pof_nat (to_nat (succ p)) = succ pp:positiveIHp:of_nat (to_nat p) = pof_nat (to_nat (succ p)) = succ pp:positiveIHp:of_nat (to_nat p) = pof_nat (S (to_nat p)) = succ pnow destruct (is_succ p) as (n,->). Qed.p:positiveIHp:of_nat (to_nat p) = pof_nat (S (to_nat p)) = succ (of_nat (to_nat p))
Pos.to_nat is hence injective
p, q:positiveto_nat p = to_nat q -> p = qp, q:positiveto_nat p = to_nat q -> p = qnow rewrite <- (id p), <- (id q), H. Qed.p, q:positiveH:to_nat p = to_nat qp = qp, q:positiveto_nat p = to_nat q <-> p = qp, q:positiveto_nat p = to_nat q <-> p = qp, q:positiveto_nat p = to_nat q -> p = qp, q:positivep = q -> to_nat p = to_nat qintros; now subst. Qed.p, q:positivep = q -> to_nat p = to_nat q
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:positiveforall q : positive, (p ?= q)%positive = (to_nat p ?= to_nat q)q:positive(1 ?= q)%positive = (to_nat 1 ?= to_nat q)p:positiveIH: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:positiveHq:succ (pred q) = q(1 ?= q)%positive = (to_nat 1 ?= to_nat q)q:positiveHq:succ (pred q) = qLt = (0 ?= to_nat (pred q))apply Nat.compare_lt_iff, is_pos.q:positiveHq:succ (pred q) = q(0 ?= to_nat (pred q)) = Ltp:positiveIH: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:positiveIH:forall q : positive, (p ?= q)%positive = (to_nat p ?= to_nat q)(succ p ?= 1)%positive = (to_nat (succ p) ?= to_nat 1)p:positiveIH:forall q0 : positive, (p ?= q0)%positive = (to_nat p ?= to_nat q0)q:positiveHq:succ (pred q) = q(succ p ?= q)%positive = (to_nat (succ p) ?= to_nat q)p:positiveIH:forall q : positive, (p ?= q)%positive = (to_nat p ?= to_nat q)CompOpp Lt = (S (to_nat p) ?= to_nat 1)p:positiveIH:forall q0 : positive, (p ?= q0)%positive = (to_nat p ?= to_nat q0)q:positiveHq:succ (pred q) = q(succ p ?= q)%positive = (to_nat (succ p) ?= to_nat q)p:positiveIH:forall q : positive, (p ?= q)%positive = (to_nat p ?= to_nat q)Gt = (to_nat p ?= 0)p:positiveIH:forall q0 : positive, (p ?= q0)%positive = (to_nat p ?= to_nat q0)q:positiveHq:succ (pred q) = q(succ p ?= q)%positive = (to_nat (succ p) ?= to_nat q)p:positiveIH:forall q : positive, (p ?= q)%positive = (to_nat p ?= to_nat q)(to_nat p ?= 0) = Gtp:positiveIH:forall q0 : positive, (p ?= q0)%positive = (to_nat p ?= to_nat q0)q:positiveHq: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.p:positiveIH:forall q0 : positive, (p ?= q0)%positive = (to_nat p ?= to_nat q0)q:positiveHq:succ (pred q) = q(succ p ?= q)%positive = (to_nat (succ p) ?= to_nat q)
Pos.to_nat is a morphism for lt, le, etc
p, q:positive(p < q)%positive <-> to_nat p < to_nat qp, q:positive(p < q)%positive <-> to_nat p < to_nat qnow rewrite inj_compare, Nat.compare_lt_iff. Qed.p, q:positive(p ?= q)%positive = Lt <-> to_nat p < to_nat qp, q:positive(p <= q)%positive <-> to_nat p <= to_nat qp, q:positive(p <= q)%positive <-> to_nat p <= to_nat qnow rewrite inj_compare, Nat.compare_le_iff. Qed.p, q:positive(p ?= q)%positive <> Gt <-> to_nat p <= to_nat qp, q:positive(p > q)%positive <-> to_nat p > to_nat qp, q:positive(p > q)%positive <-> to_nat p > to_nat qnow rewrite inj_compare, Nat.compare_gt_iff. Qed.p, q:positive(p ?= q)%positive = Gt <-> to_nat p > to_nat qp, q:positive(p >= q)%positive <-> to_nat p >= to_nat qp, q:positive(p >= q)%positive <-> to_nat p >= to_nat qnow rewrite inj_compare, Nat.compare_ge_iff. Qed.p, q:positive(p ?= q)%positive <> Lt <-> to_nat p >= to_nat q
Pos.to_nat is a morphism for subtraction
p, q:positive(q < p)%positive -> to_nat (p - q) = to_nat p - to_nat qp, q:positive(q < p)%positive -> to_nat (p - q) = to_nat p - to_nat qp, q:positiveH:(q < p)%positiveto_nat (p - q) = to_nat p - to_nat qp, q:positiveH:(q < p)%positiveto_nat (p - q) + to_nat q = to_nat p - to_nat q + to_nat qp, q:positiveH:(q < p)%positiveto_nat (p - q) + to_nat q = to_nat pp, q:positiveH:(q < p)%positiveto_nat q <= to_nat pnow apply Nat.lt_le_incl, inj_lt. Qed.p, q:positiveH:(q < p)%positiveto_nat q <= to_nat pp, q:positiveto_nat (p - q) = Nat.max 1 (to_nat p - to_nat q)p, q:positiveto_nat (p - q) = Nat.max 1 (to_nat p - to_nat q)p, q:positiveH:(q < p)%positiveto_nat (p - q) = Nat.max 1 (to_nat p - to_nat q)p, q:positiveH:(p <= q)%positiveto_nat (p - q) = Nat.max 1 (to_nat p - to_nat q)p, q:positiveH:(q < p)%positiveto_nat (p - q) = Nat.max 1 (to_nat p - to_nat q)now destruct (is_succ (p - q)) as (m,->).p, q:positiveH:(q < p)%positiveto_nat (p - q) = Nat.max 1 (to_nat (p - q))p, q:positiveH:(p <= q)%positiveto_nat (p - q) = Nat.max 1 (to_nat p - to_nat q)p, q:positiveH:(p <= q)%positiveto_nat 1 = Nat.max 1 (to_nat p - to_nat q)now rewrite H. Qed.p, q:positiveH:to_nat p - to_nat q = 0to_nat 1 = Nat.max 1 (to_nat p - to_nat q)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)now rewrite <- Pos.sub_1_r, inj_sub, Nat.sub_1_r. Qed.p:positiveH:(1 < p)%positiveto_nat (pred p) = Nat.pred (to_nat p)p:positiveto_nat (pred p) = Nat.max 1 (Init.Nat.pred (to_nat p))p:positiveto_nat (pred p) = Nat.max 1 (Init.Nat.pred (to_nat p))apply inj_sub_max. Qed.p:positiveto_nat (p - 1) = Nat.max 1 (to_nat p - 1)
Pos.to_nat and other operations
p, q:positiveto_nat (min p q) = Nat.min (to_nat p) (to_nat q)p, q:positiveto_nat (min p q) = Nat.min (to_nat p) (to_nat q)p, q:positiveto_nat match (p ?= q)%positive with | Gt => q | _ => p end = Nat.min (to_nat p) (to_nat q)p, q:positiveto_nat match to_nat p ?= to_nat q with | Gt => q | _ => p end = Nat.min (to_nat p) (to_nat q)p, q:positiveH:to_nat p = to_nat qNat.min (to_nat p) (to_nat q) = to_nat pp, q:positiveH:to_nat p < to_nat qNat.min (to_nat p) (to_nat q) = to_nat pp, q:positiveH:to_nat q < to_nat pNat.min (to_nat p) (to_nat q) = to_nat qp, q:positiveH:to_nat p = to_nat qNat.min (to_nat p) (to_nat q) = to_nat pnow rewrite H.p, q:positiveH:to_nat p = to_nat qto_nat p <= to_nat qnow apply Nat.min_l, Nat.lt_le_incl.p, q:positiveH:to_nat p < to_nat qNat.min (to_nat p) (to_nat q) = to_nat pnow apply Nat.min_r, Nat.lt_le_incl. Qed.p, q:positiveH:to_nat q < to_nat pNat.min (to_nat p) (to_nat q) = to_nat qp, q:positiveto_nat (max p q) = Nat.max (to_nat p) (to_nat q)p, q:positiveto_nat (max p q) = Nat.max (to_nat p) (to_nat q)p, q:positiveto_nat match (p ?= q)%positive with | Gt => p | _ => q end = Nat.max (to_nat p) (to_nat q)p, q:positiveto_nat match to_nat p ?= to_nat q with | Gt => p | _ => q end = Nat.max (to_nat p) (to_nat q)p, q:positiveH:to_nat p = to_nat qNat.max (to_nat p) (to_nat q) = to_nat qp, q:positiveH:to_nat p < to_nat qNat.max (to_nat p) (to_nat q) = to_nat qp, q:positiveH:to_nat q < to_nat pNat.max (to_nat p) (to_nat q) = to_nat pp, q:positiveH:to_nat p = to_nat qNat.max (to_nat p) (to_nat q) = to_nat qnow rewrite H.p, q:positiveH:to_nat p = to_nat qto_nat p <= to_nat qnow apply Nat.max_r, Nat.lt_le_incl.p, q:positiveH:to_nat p < to_nat qNat.max (to_nat p) (to_nat q) = to_nat qnow apply Nat.max_l, Nat.lt_le_incl. Qed.p, q:positiveH:to_nat q < to_nat pNat.max (to_nat p) (to_nat q) = to_nat pforall (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:positiveIHp: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))trivial.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:positiveIHp: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:positiveIHp: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:Typef:A -> Ax:Aiter f x (succ p) = nat_rect (fun _ : nat => A) x (fun _ : nat => f) (to_nat (succ p))p:positiveIHp: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:Typef:A -> Ax:Af (iter f x p) = nat_rect (fun _ : nat => A) x (fun _ : nat => f) (S (to_nat p))p:positiveIHp: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:Typef:A -> Ax:Af (iter f x p) = f (nat_rect (fun _ : nat => A) x (fun _ : nat => f) (to_nat p))apply IHp. Qed. End Pos2Nat. Module Nat2Pos.p:positiveIHp: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:Typef:A -> Ax:Aiter f x p = nat_rect (fun _ : nat => A) x (fun _ : nat => f) (to_nat p)
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:natn <> 0 -> Pos.to_nat (Pos.of_nat n) = nn:natn <> 0 -> Pos.to_nat (Pos.of_nat n) = n0 <> 0 -> Pos.to_nat (Pos.of_nat 0) = 0n:natH:n <> 0 -> Pos.to_nat (Pos.of_nat n) = nS n <> 0 -> Pos.to_nat (Pos.of_nat (S n)) = S nn:natH:n <> 0 -> Pos.to_nat (Pos.of_nat n) = nS n <> 0 -> Pos.to_nat (Pos.of_nat (S n)) = S nn:natH:n <> 0 -> Pos.to_nat (Pos.of_nat n) = nPos.to_nat (Pos.of_nat (S n)) = S nn:natH:n <> 0 -> Pos.to_nat (Pos.of_nat n) = nPos.to_nat match n with | 0%nat => 1 | S _ => Pos.succ (Pos.of_nat n) end = S nH:0 <> 0 -> Pos.to_nat (Pos.of_nat 0) = 0Pos.to_nat 1 = 1n:natH:S n <> 0 -> Pos.to_nat (Pos.of_nat (S n)) = S nPos.to_nat (Pos.succ (Pos.of_nat (S n))) = S (S n)n:natH:S n <> 0 -> Pos.to_nat (Pos.of_nat (S n)) = S nPos.to_nat (Pos.succ (Pos.of_nat (S n))) = S (S n)n:natH:S n <> 0 -> Pos.to_nat (Pos.of_nat (S n)) = S nS (Pos.to_nat (Pos.of_nat (S n))) = S (S n)now apply H. Qed.n:natH:S n <> 0 -> Pos.to_nat (Pos.of_nat (S n)) = S nPos.to_nat (Pos.of_nat (S n)) = S nn:natPos.to_nat (Pos.of_nat n) = Init.Nat.max 1 nn:natPos.to_nat (Pos.of_nat n) = Init.Nat.max 1 nPos.to_nat (Pos.of_nat 0) = Init.Nat.max 1 0n:natPos.to_nat (Pos.of_nat (S n)) = Init.Nat.max 1 (S n)now rewrite id. Qed.n:natPos.to_nat (Pos.of_nat (S n)) = Init.Nat.max 1 (S n)
Pos.of_nat is hence injective for non-zero numbers
n, m:natn <> 0 -> m <> 0 -> Pos.of_nat n = Pos.of_nat m -> n = mn, m:natn <> 0 -> m <> 0 -> Pos.of_nat n = Pos.of_nat m -> n = mnow rewrite <- (id n), <- (id m), H. Qed.n, m:natHn:n <> 0Hm:m <> 0H:Pos.of_nat n = Pos.of_nat mn = mn, m:natn <> 0 -> m <> 0 -> Pos.of_nat n = Pos.of_nat m <-> n = mn, m:natn <> 0 -> m <> 0 -> Pos.of_nat n = Pos.of_nat m <-> n = mn, m:natH:n <> 0H0:m <> 0Pos.of_nat n = Pos.of_nat m -> n = mn, m:natH:n <> 0H0:m <> 0n = m -> Pos.of_nat n = Pos.of_nat mintros; now subst. Qed.n, m:natH:n <> 0H0:m <> 0n = m -> Pos.of_nat n = Pos.of_nat m
Usual operations are morphisms with respect to Pos.of_nat
for non-zero numbers.
n:natn <> 0 -> Pos.of_nat (S n) = Pos.succ (Pos.of_nat n)n:natn <> 0 -> Pos.of_nat (S n) = Pos.succ (Pos.of_nat n)n:natH:n <> 0Pos.of_nat (S n) = Pos.succ (Pos.of_nat n)now rewrite Pos2Nat.inj_succ, !id. Qed.n:natH:n <> 0Pos.to_nat (Pos.of_nat (S n)) = Pos.to_nat (Pos.succ (Pos.of_nat n))n:natPos.of_nat (Init.Nat.pred n) = Pos.pred (Pos.of_nat n)n:natPos.of_nat (Init.Nat.pred n) = Pos.pred (Pos.of_nat n)n:natPos.of_nat (Init.Nat.pred (S (S n))) = Pos.pred (Pos.of_nat (S (S n)))now rewrite Pos.pred_succ. Qed.n:natmatch 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)n, m:natn <> 0 -> m <> 0 -> Pos.of_nat (n + m) = (Pos.of_nat n + Pos.of_nat m)%positiven, m:natn <> 0 -> m <> 0 -> Pos.of_nat (n + m) = (Pos.of_nat n + Pos.of_nat m)%positiven, m:natHn:n <> 0Hm:m <> 0Pos.of_nat (n + m) = (Pos.of_nat n + Pos.of_nat m)%positiven, m:natHn:n <> 0Hm:m <> 0Pos.to_nat (Pos.of_nat (n + m)) = Pos.to_nat (Pos.of_nat n + Pos.of_nat m)n, m:natHn:n <> 0Hm:m <> 0n + m <> 0n, m:natHn:n <> 0Hm:m <> 0H:n + m = 0Falsem:natHn:0 <> 0Hm:m <> 0H:0 + m = 0Falsen, m:natHn:S n <> 0Hm:m <> 0H:S n + m = 0Falsenow simpl in H. Qed.n, m:natHn:S n <> 0Hm:m <> 0H:S n + m = 0Falsen, m:natn <> 0 -> m <> 0 -> Pos.of_nat (n * m) = (Pos.of_nat n * Pos.of_nat m)%positiven, m:natn <> 0 -> m <> 0 -> Pos.of_nat (n * m) = (Pos.of_nat n * Pos.of_nat m)%positiven, m:natHn:n <> 0Hm:m <> 0Pos.of_nat (n * m) = (Pos.of_nat n * Pos.of_nat m)%positiven, m:natHn:n <> 0Hm:m <> 0Pos.to_nat (Pos.of_nat (n * m)) = Pos.to_nat (Pos.of_nat n * Pos.of_nat m)n, m:natHn:n <> 0Hm:m <> 0n * m <> 0n, m:natHn:n <> 0Hm:m <> 0H:n * m = 0Falsen, m:natHn:n <> 0Hm:m <> 0H:n = 0 \/ m = 0Falsen, m:natHn:n <> 0Hm:m <> 0H:n = 0Falsen, m:natHn:n <> 0Hm:m <> 0H:m = 0Falsenow elim Hm. Qed.n, m:natHn:n <> 0Hm:m <> 0H:m = 0Falsen, m:natn <> 0 -> m <> 0 -> (n ?= m) = (Pos.of_nat n ?= Pos.of_nat m)%positiven, m:natn <> 0 -> m <> 0 -> (n ?= m) = (Pos.of_nat n ?= Pos.of_nat m)%positiverewrite Pos2Nat.inj_compare, !id; trivial. Qed.n, m:natHn:n <> 0Hm:m <> 0(n ?= m) = (Pos.of_nat n ?= Pos.of_nat m)%positiven, m:natm <> 0 -> Pos.of_nat (n - m) = (Pos.of_nat n - Pos.of_nat m)%positiven, m:natm <> 0 -> Pos.of_nat (n - m) = (Pos.of_nat n - Pos.of_nat m)%positiven, m:natHm:m <> 0Pos.of_nat (n - m) = (Pos.of_nat n - Pos.of_nat m)%positiven, m:natHm:m <> 0Pos.to_nat (Pos.of_nat (n - m)) = Pos.to_nat (Pos.of_nat n - Pos.of_nat m)n, m:natHm:m <> 0Pos.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:natHm:m <> 0Pos.to_nat (Pos.of_nat (n - m)) = Nat.max 1 (Pos.to_nat (Pos.of_nat n) - m)destruct n, m; trivial. Qed.n, m:natHm:m <> 0Init.Nat.max 1 (n - m) = Nat.max 1 (Init.Nat.max 1 n - m)n, m:natPos.of_nat (Init.Nat.min n m) = Pos.min (Pos.of_nat n) (Pos.of_nat m)n, m:natPos.of_nat (Init.Nat.min n m) = Pos.min (Pos.of_nat n) (Pos.of_nat m)m:natPos.of_nat (Init.Nat.min 0 m) = Pos.min (Pos.of_nat 0) (Pos.of_nat m)n, m:natPos.of_nat (Init.Nat.min (S n) m) = Pos.min (Pos.of_nat (S n)) (Pos.of_nat m)m:nat1%positive = Pos.min 1 (Pos.of_nat m)n, m:natPos.of_nat (Init.Nat.min (S n) m) = Pos.min (Pos.of_nat (S n)) (Pos.of_nat m)m:natPos.min 1 (Pos.of_nat m) = 1%positiven, m:natPos.of_nat (Init.Nat.min (S n) m) = Pos.min (Pos.of_nat (S n)) (Pos.of_nat m)n, m:natPos.of_nat (Init.Nat.min (S n) m) = Pos.min (Pos.of_nat (S n)) (Pos.of_nat m)n:natPos.of_nat (Init.Nat.min (S n) 0) = Pos.min (Pos.of_nat (S n)) (Pos.of_nat 0)n, m:natPos.of_nat (Init.Nat.min (S n) (S m)) = Pos.min (Pos.of_nat (S n)) (Pos.of_nat (S m))n:nat1%positive = Pos.min match n with | 0%nat => 1 | S _ => Pos.succ (Pos.of_nat n) end 1n, m:natPos.of_nat (Init.Nat.min (S n) (S m)) = Pos.min (Pos.of_nat (S n)) (Pos.of_nat (S m))n:natPos.min match n with | 0%nat => 1 | S _ => Pos.succ (Pos.of_nat n) end 1 = 1%positiven, m:natPos.of_nat (Init.Nat.min (S n) (S m)) = Pos.min (Pos.of_nat (S n)) (Pos.of_nat (S m))n, m:natPos.of_nat (Init.Nat.min (S n) (S m)) = Pos.min (Pos.of_nat (S n)) (Pos.of_nat (S m))n, m:natPos.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) endn, m:natPos.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) endn, m:natH:S n = S mS n <= S mn, m:natH:S n < S mS n <= S mn, m:natH:S m < S nS m <= S nn, m:natH:S n < S mS n <= S mn, m:natH:S m < S nS m <= S nnow apply Nat.lt_le_incl. Qed.n, m:natH:S m < S nS m <= S nn, m:natPos.of_nat (Init.Nat.max n m) = Pos.max (Pos.of_nat n) (Pos.of_nat m)n, m:natPos.of_nat (Init.Nat.max n m) = Pos.max (Pos.of_nat n) (Pos.of_nat m)m:natPos.of_nat (Init.Nat.max 0 m) = Pos.max (Pos.of_nat 0) (Pos.of_nat m)n, m:natPos.of_nat (Init.Nat.max (S n) m) = Pos.max (Pos.of_nat (S n)) (Pos.of_nat m)m:natPos.of_nat m = Pos.max 1 (Pos.of_nat m)n, m:natPos.of_nat (Init.Nat.max (S n) m) = Pos.max (Pos.of_nat (S n)) (Pos.of_nat m)m:natPos.max 1 (Pos.of_nat m) = Pos.of_nat mn, m:natPos.of_nat (Init.Nat.max (S n) m) = Pos.max (Pos.of_nat (S n)) (Pos.of_nat m)n, m:natPos.of_nat (Init.Nat.max (S n) m) = Pos.max (Pos.of_nat (S n)) (Pos.of_nat m)n:natPos.of_nat (Init.Nat.max (S n) 0) = Pos.max (Pos.of_nat (S n)) (Pos.of_nat 0)n, m:natPos.of_nat (Init.Nat.max (S n) (S m)) = Pos.max (Pos.of_nat (S n)) (Pos.of_nat (S m))n:natmatch 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 1n, m:natPos.of_nat (Init.Nat.max (S n) (S m)) = Pos.max (Pos.of_nat (S n)) (Pos.of_nat (S m))n:natPos.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) endn, m:natPos.of_nat (Init.Nat.max (S n) (S m)) = Pos.max (Pos.of_nat (S n)) (Pos.of_nat (S m))n, m:natPos.of_nat (Init.Nat.max (S n) (S m)) = Pos.max (Pos.of_nat (S n)) (Pos.of_nat (S m))n, m:natPos.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) endn, m:natPos.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) endn, m:natH:S n = S mS n <= S mn, m:natH:S n < S mS n <= S mn, m:natH:S m < S nS m <= S nn, m:natH:S n < S mS n <= S mn, m:natH:S m < S nS m <= S nnow apply Nat.lt_le_incl. Qed. End Nat2Pos. (**********************************************************************)n, m:natH:S m < S nS m <= S n
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:positivePos.of_succ_nat (Pos.to_nat p) = Pos.succ pp:positivePos.of_succ_nat (Pos.to_nat p) = Pos.succ papply Pos2Nat.id. Qed.p:positivePos.of_nat (Pos.to_nat (Pos.succ p)) = Pos.succ p
Composition of Pos.to_nat, Pos.of_succ_nat and Pos.pred
is identity on positive
p:positivePos.pred (Pos.of_succ_nat (Pos.to_nat p)) = pnow rewrite id_succ, Pos.pred_succ. Qed. End Pos2SuccNat. Module SuccNat2Pos.p:positivePos.pred (Pos.of_succ_nat (Pos.to_nat p)) = p
Composition of Pos.of_succ_nat and Pos.to_nat is successor on nat
n:natPos.to_nat (Pos.of_succ_nat n) = S nn:natPos.to_nat (Pos.of_succ_nat n) = S nnow apply Nat2Pos.id. Qed.n:natPos.to_nat (Pos.of_nat (S n)) = S nn:natInit.Nat.pred (Pos.to_nat (Pos.of_succ_nat n)) = nnow rewrite id_succ. Qed.n:natInit.Nat.pred (Pos.to_nat (Pos.of_succ_nat n)) = n
Pos.of_succ_nat is hence injective
n, m:natPos.of_succ_nat n = Pos.of_succ_nat m -> n = mn, m:natPos.of_succ_nat n = Pos.of_succ_nat m -> n = mn, m:natH:Pos.of_succ_nat n = Pos.of_succ_nat mn = mn, m:natH:Pos.to_nat (Pos.of_succ_nat n) = Pos.to_nat (Pos.of_succ_nat m)n = mnow injection H. Qed.n, m:natH:S n = S mn = mn, m:natPos.of_succ_nat n = Pos.of_succ_nat m <-> n = mn, m:natPos.of_succ_nat n = Pos.of_succ_nat m <-> n = mn, m:natPos.of_succ_nat n = Pos.of_succ_nat m -> n = mn, m:natn = m -> Pos.of_succ_nat n = Pos.of_succ_nat mintros; now subst. Qed.n, m:natn = m -> Pos.of_succ_nat n = Pos.of_succ_nat m
Another formulation
n:natp:positivePos.to_nat p = S n -> Pos.of_succ_nat n = pn:natp:positivePos.to_nat p = S n -> Pos.of_succ_nat n = pn:natp:positiveH:Pos.to_nat p = S nPos.of_succ_nat n = pnow rewrite id_succ. Qed.n:natp:positiveH:Pos.to_nat p = S nPos.to_nat (Pos.of_succ_nat n) = Pos.to_nat p
Successor and comparison are morphisms with respect to
Pos.of_succ_nat
n:natPos.of_succ_nat (S n) = Pos.succ (Pos.of_succ_nat n)n:natPos.of_succ_nat (S n) = Pos.succ (Pos.of_succ_nat n)now rewrite Pos2Nat.inj_succ, !id_succ. Qed.n:natPos.to_nat (Pos.of_succ_nat (S n)) = Pos.to_nat (Pos.succ (Pos.of_succ_nat n))n, m:nat(n ?= m) = (Pos.of_succ_nat n ?= Pos.of_succ_nat m)%positiverewrite Pos2Nat.inj_compare, !id_succ; trivial. Qed.n, m:nat(n ?= m) = (Pos.of_succ_nat n ?= Pos.of_succ_nat m)%positive
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).Proof (fun H => Pos2Nat.inj_sub p q (Pos.gt_lt _ _ H)).p, q:positivePos.compare_cont Eq p q = Gt -> Pos.to_nat (p - q) = Pos.to_nat p - Pos.to_nat qProof (proj1 (Pos2Nat.inj_lt p q)).p, q:positivePos.compare_cont Eq p q = Lt -> Pos.to_nat p < Pos.to_nat qProof (proj1 (Pos2Nat.inj_gt p q)).p, q:positivePos.compare_cont Eq p q = Gt -> Pos.to_nat p > Pos.to_nat qProof (proj2 (Pos2Nat.inj_lt p q)).p, q:positivePos.to_nat p < Pos.to_nat q -> Pos.compare_cont Eq p q = LtProof (proj2 (Pos2Nat.inj_gt p q)).p, q:positivePos.to_nat p > Pos.to_nat q -> Pos.compare_cont Eq p q = Gt
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 * nforall (p : positive) (n : nat), Pos.iter_op Init.Nat.add p n = Pos.to_nat p * np:positiveIHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0n:natn + Pos.iter_op Init.Nat.add p (n + n) = n + Pos.iter_op Init.Nat.add p 2 * np:positiveIHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0n:natPos.iter_op Init.Nat.add p (n + n) = Pos.iter_op Init.Nat.add p 2 * nn:natn = n + 0p:positiveIHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0n:natPos.iter_op Init.Nat.add p (n + n) = Pos.iter_op Init.Nat.add p 2 * np:positiveIHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0n:natPos.iter_op Init.Nat.add p (n + n) = Pos.iter_op Init.Nat.add p 2 * nn:natn = n + 0p:positiveIHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0n:natPos.to_nat p * (n + n) = Pos.to_nat p * 2 * np:positiveIHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0n:natPos.iter_op Init.Nat.add p (n + n) = Pos.iter_op Init.Nat.add p 2 * nn:natn = n + 0p:positiveIHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0n:natPos.to_nat p * (n + n) = Pos.to_nat p * (2 * n)p:positiveIHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0n:natPos.iter_op Init.Nat.add p (n + n) = Pos.iter_op Init.Nat.add p 2 * nn:natn = n + 0p:positiveIHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0n:natn + n = 2 * np:positiveIHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0n:natPos.iter_op Init.Nat.add p (n + n) = Pos.iter_op Init.Nat.add p 2 * nn:natn = n + 0p:positiveIHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0n:natn + n = n + (n + 0)p:positiveIHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0n:natPos.iter_op Init.Nat.add p (n + n) = Pos.iter_op Init.Nat.add p 2 * nn:natn = n + 0p:positiveIHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0n:natPos.iter_op Init.Nat.add p (n + n) = Pos.iter_op Init.Nat.add p 2 * nn:natn = n + 0p:positiveIHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0n:natPos.to_nat p * (n + n) = Pos.to_nat p * 2 * nn:natn = n + 0p:positiveIHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0n:natPos.to_nat p * (n + n) = Pos.to_nat p * (2 * n)n:natn = n + 0p:positiveIHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0n:natn + n = 2 * nn:natn = n + 0p:positiveIHp:forall n0 : nat, Pos.iter_op Init.Nat.add p n0 = Pos.to_nat p * n0n:natn + n = n + (n + 0)n:natn = n + 0n:natn = n + 0now rewrite Nat.add_0_r. Qed.n:natn = n + 0forall (p : positive) (n : nat), Pos.iter_op Init.Nat.add (Pos.succ p) n = n + Pos.iter_op Init.Nat.add p nforall (p : positive) (n : nat), Pos.iter_op Init.Nat.add (Pos.succ p) n = n + Pos.iter_op Init.Nat.add p nnow rewrite !Pmult_nat_mult, Pos2Nat.inj_succ. Qed.p:positiven:natPos.iter_op Init.Nat.add (Pos.succ p) n = n + Pos.iter_op Init.Nat.add p nforall (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 nforall (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 np, q:positiven:natPos.iter_op Init.Nat.add (p + q) n = Pos.iter_op Init.Nat.add p n + Pos.iter_op Init.Nat.add q napply Nat.mul_add_distr_r. Qed.p, q:positiven:nat(Pos.to_nat p + Pos.to_nat q) * n = Pos.to_nat p * n + Pos.to_nat q * nforall (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) nforall (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) nnow rewrite Pos.add_carry_spec, Pmult_nat_succ_morphism. Qed.p, q:positiven:natPos.iter_op Init.Nat.add (Pos.add_carry p q) n = n + Pos.iter_op Init.Nat.add (p + q) nforall (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 nforall (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 np:positiven:natPos.iter_op Init.Nat.add p (n + n) = Pos.iter_op Init.Nat.add p n + Pos.iter_op Init.Nat.add p napply Nat.mul_add_distr_l. Qed.p:positiven:natPos.to_nat p * (n + n) = Pos.to_nat p * n + Pos.to_nat p * nforall p : positive, Pos.iter_op Init.Nat.add p 2 = Pos.to_nat p + Pos.to_nat pforall p : positive, Pos.iter_op Init.Nat.add p 2 = Pos.to_nat p + Pos.to_nat pp:positivePos.iter_op Init.Nat.add p 2 = Pos.to_nat p + Pos.to_nat pp:positive2 * Pos.to_nat p = Pos.to_nat p + Pos.to_nat pnow rewrite Nat.add_0_r. Qed.p:positivePos.to_nat p + (Pos.to_nat p + 0) = Pos.to_nat p + Pos.to_nat pforall (p : positive) (n : nat), n <= Pos.iter_op Init.Nat.add p nforall (p : positive) (n : nat), n <= Pos.iter_op Init.Nat.add p np:positiven:natn <= Pos.iter_op Init.Nat.add p np:positiven:natn <= Pos.to_nat p * np:positiven:natn <= 1 * np:positiven:nat1 * n <= Pos.to_nat p * np:positiven:nat1 * n <= Pos.to_nat p * napply Pos2Nat.is_pos. Qed. End ObsoletePmultNat.p:positiven:nat1 <= Pos.to_nat p