Built with Alectryon, running Coq+SerAPI v8.19.0+0.19.3. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑Ctrl+↓ to navigate, Ctrl+🖱️ to focus. On Mac, use ⌘ instead of Ctrl.
[Loading ML file number_string_notation_plugin.cmxs (using legacy method) ... done]
Local Set Universe Minimization ToSet.(** * Binary Positive Integers *)(** Most of this file has been adapted from the Coq standard library for positive binary integers. *)(** Here we define the inductive type of positive binary numbers. *)InductivePos : Type0 :=
| xH : Pos
| x0 : Pos -> Pos
| x1 : Pos -> Pos.Declare Scope positive_scope.Delimit Scope positive_scope with pos.(** Here are some notations that let us write binary positive integers more easily. *)Notation"1" := xH : positive_scope.Notation"p ~ 1" := (x1 p) : positive_scope.Notation"p ~ 0" := (x0 p) : positive_scope.LocalOpen Scope positive_scope.(** ** Successor *)Fixpointpos_succx :=
match x with
| p~1 => (pos_succ p)~0
| p~0 => p~1
| 1 => 1~0end.(** Peano induction (due to Daniel Schepler) *)Fixpointpos_peano_ind (P : Pos -> Type) (a : P 1)
(f : forallp, P p -> P (pos_succ p)) (p : Pos) : P p
:= letf2 := pos_peano_ind (funp => P (p~0))
(f _ a) (funp (x : P p~0) => f _ (f _ x))
inmatch p with
| q~1 => f _ (f2 q)
| q~0 => f2 q
| 1 => a
end.(** Computation rules for Peano induction *)Definitionpos_peano_ind_beta_1 (P : Pos -> Type) (a : P 1)
(f : forallp, P p -> P (pos_succ p))
: pos_peano_ind P a f 1 = a := idpath.
P: Pos -> Type a: P 1 f: forallp : Pos, P p -> P (pos_succ p) p: Pos
pos_peano_ind P a f (pos_succ p) =
f p (pos_peano_ind P a f p)
P: Pos -> Type a: P 1 f: forallp : Pos, P p -> P (pos_succ p) p: Pos
pos_peano_ind P a f (pos_succ p) =
f p (pos_peano_ind P a f p)
p: Pos
forall (P : Pos -> Type) (a : P 1)
(f : forallp : Pos, P p -> P (pos_succ p)),
pos_peano_ind P a f (pos_succ p) =
f p (pos_peano_ind P a f p)
p: Pos IHp: forall (P : Pos -> Type) (a : P 1)
(f : forallp : Pos, P p -> P (pos_succ p)),
pos_peano_ind P a f (pos_succ p) = f p (pos_peano_ind P a f p)
forall (P : Pos -> Type) (a : P 1)
(f : forallp : Pos, P p -> P (pos_succ p)),
pos_peano_ind P a f (pos_succ p~1) =
f p~1 (pos_peano_ind P a f p~1)
p: Pos IHp: forall (P : Pos -> Type) (a : P 1)
(f : forallp : Pos, P p -> P (pos_succ p)),
pos_peano_ind P a f (pos_succ p) = f p (pos_peano_ind P a f p) P: Pos -> Type a: P 1 f: forallp : Pos, P p -> P (pos_succ p)
pos_peano_ind P a f (pos_succ p~1) =
f p~1 (pos_peano_ind P a f p~1)
srapply IHp.Qed.Definitionpos_peano_rec (P : Type)
: P -> (Pos -> P -> P) -> Pos -> P
:= pos_peano_ind (fun_ => P).Definitionpos_peano_rec_beta_pos_succ (P : Type)
(a : P) (f : Pos -> P -> P) (p : Pos)
: pos_peano_rec P a f (pos_succ p) = f p (pos_peano_rec P a f p)
:= pos_peano_ind_beta_pos_succ (fun_ => P) a f p.(** ** Properties of constructors *)Definitionx0_inj {zw : Pos} (p : x0 z = x0 w) : z = w
:= transport (funs => z = (
match s with xH => w | x0 a => a | x1 a => w end)) p idpath.Definitionx1_inj {zw : Pos} (p : x1 z = x1 w) : z = w
:= transport (funs => z = (
match s with xH => w | x0 a => w | x1 a => a end)) p idpath.Definitionx0_neq_xH {z : Pos} : x0 z <> xH
:= funp => transport (funs =>
match s with xH => Empty | x0 a => z = a | x1 a => Empty end) p idpath.Definitionx1_neq_xH {z : Pos} : x1 z <> xH
:= funp => transport (funs =>
match s with xH => Empty | x0 a => Empty | x1 a => z = a end) p idpath.Definitionx0_neq_x1 {zw : Pos} : x0 z <> x1 w
:= funp => transport (funs =>
match s with xH => Empty | x0 a => z = a | x1 _ => Empty end) p idpath.DefinitionxH_neq_x0 {z : Pos} : xH <> x0 z
:= x0_neq_xH o symmetry _ _.DefinitionxH_neq_x1 {z : Pos} : xH <> x1 z
:= x1_neq_xH o symmetry _ _.Definitionx1_neq_x0 {zw : Pos} : x1 z <> x0 w
:= x0_neq_x1 o symmetry _ _.(** * Positive binary integers have decidable paths *)
on: Pos IHon: forally : Pos, Decidable (on = y) zm: Pos IHzm: Decidable (on~1 = zm)
Decidable (on~1 = zm~0)
exact (inr x1_neq_x0).
on: Pos IHon: forally : Pos, Decidable (on = y) om: Pos IHom: Decidable (on~1 = om)
Decidable (on~1 = om~1)
on: Pos IHon: forally : Pos, Decidable (on = y) om: Pos IHom: Decidable (on~1 = om) p: on = om
Decidable (on~1 = om~1)
on: Pos IHon: forally : Pos, Decidable (on = y) om: Pos IHom: Decidable (on~1 = om) q: on <> om
Decidable (on~1 = om~1)
on: Pos IHon: forally : Pos, Decidable (on = y) om: Pos IHom: Decidable (on~1 = om) p: on = om
Decidable (on~1 = om~1)
apply inl, ap, p.
on: Pos IHon: forally : Pos, Decidable (on = y) om: Pos IHom: Decidable (on~1 = om) q: on <> om
Decidable (on~1 = om~1)
on: Pos IHon: forally : Pos, Decidable (on = y) om: Pos IHom: Decidable (on~1 = om) q: on <> om p: on~1 = om~1
Empty
byapply q, x1_inj.Defined.(** Decidable paths imply [Pos] is a hSet *)Instanceishset_pos : IsHSet Pos := _.(** * Operations over positive numbers *)(** ** Addition *)Fixpointpos_addxy :=
match x, y with
| p~1, q~1 => (pos_add_carry p q)~0
| p~1, q~0 => (pos_add p q)~1
| p~1, 1 => (pos_succ p)~0
| p~0, q~1 => (pos_add p q)~1
| p~0, q~0 => (pos_add p q)~0
| p~0, 1 => p~1
| 1, q~1 => (pos_succ q)~0
| 1, q~0 => q~1
| 1, 1 => 1~0endwith pos_add_carry x y :=
match x, y with
| p~1, q~1 => (pos_add_carry p q)~1
| p~1, q~0 => (pos_add_carry p q)~0
| p~1, 1 => (pos_succ p)~1
| p~0, q~1 => (pos_add_carry p q)~0
| p~0, q~0 => (pos_add p q)~1
| p~0, 1 => (pos_succ p)~0
| 1, q~1 => (pos_succ q)~1
| 1, q~0 => (pos_succ q)~0
| 1, 1 => 1~1end.Infix"+" := pos_add : positive_scope.(** ** Operation [x -> 2*x-1] *)Fixpointpos_pred_doublex :=
match x with
| p~1 => p~0~1
| p~0 => (pos_pred_double p)~1
| 1 => 1end.(** ** Predecessor *)Definitionpos_predx :=
match x with
| p~1 => p~0
| p~0 => pos_pred_double p
| 1 => 1end.(** ** An auxiliary type for subtraction *)InductivePos_mask : Set :=
| IsNul : Pos_mask
| IsPos : Pos -> Pos_mask
| IsNeg : Pos_mask.(** ** Operation [x -> 2*x+1] *)Definitionpos_mask_succ_double (x : Pos_mask) : Pos_mask :=
match x with
| IsNul => IsPos 1
| IsNeg => IsNeg
| IsPos p => IsPos p~1end.(** ** Operation [x -> 2*x] *)Definitionpos_mask_double (x : Pos_mask) : Pos_mask :=
match x with
| IsNul => IsNul
| IsNeg => IsNeg
| IsPos p => IsPos p~0end.(** ** Operation [x -> 2*x-2] *)Definitionpos_mask_double_predx : Pos_mask :=
match x with
| p~1 => IsPos p~0~0
| p~0 => IsPos (pos_pred_double p)~0
| 1 => IsNul
end.(** ** Predecessor with mask *)Definitionpos_mask_pred (p : Pos_mask) : Pos_mask :=
match p with
| IsPos 1 => IsNul
| IsPos q => IsPos (pos_pred q)
| IsNul => IsNeg
| IsNeg => IsNeg
end.(** ** Subtraction, result as a mask *)Fixpointpos_mask_sub (xy : Pos) {structy} : Pos_mask :=
match x, y with
| p~1, q~1 => pos_mask_double (pos_mask_sub p q)
| p~1, q~0 => pos_mask_succ_double (pos_mask_sub p q)
| p~1, 1 => IsPos p~0
| p~0, q~1 => pos_mask_succ_double (pos_mask_sub_carry p q)
| p~0, q~0 => pos_mask_double (pos_mask_sub p q)
| p~0, 1 => IsPos (pos_pred_double p)
| 1, 1 => IsNul
| 1, _ => IsNeg
endwith pos_mask_sub_carry (x y : Pos) {struct y} : Pos_mask :=
match x, y with
| p~1, q~1 => pos_mask_succ_double (pos_mask_sub_carry p q)
| p~1, q~0 => pos_mask_double (pos_mask_sub p q)
| p~1, 1 => IsPos (pos_pred_double p)
| p~0, q~1 => pos_mask_double (pos_mask_sub_carry p q)
| p~0, q~0 => pos_mask_succ_double (pos_mask_sub_carry p q)
| p~0, 1 => pos_mask_double_pred p
| 1, _ => IsNeg
end.(** ** Subtraction, result as a positive, returning 1 if [x<=y] *)Definitionpos_subxy :=
match pos_mask_sub x y with
| IsPos z => z
| _ => 1end.Infix"-" := pos_sub : positive_scope.(** ** Multiplication *)Fixpointpos_mulxy :=
match x with
| p~1 => y + (pos_mul p y)~0
| p~0 => (pos_mul p y)~0
| 1 => y
end.Infix"*" := pos_mul : positive_scope.(** ** Iteration over a positive number *)
A: Type f: A -> A
Pos -> A -> A
A: Type f: A -> A
Pos -> A -> A
A: Type f: A -> A
Pos -> (A -> A) -> A -> A
A: Type f: A -> A n: Pos g: A -> A
A -> A
exact (f o g).Defined.(** ** Iteration of a two-variable function, with nesting reflecting the bits *)Definitionpos_iter_op {A} (op : A -> A -> A)
:= fix p_iter (p : Pos) (a : A) : A
:= match p with
| 1 => a
| p~0 => p_iter p (op a a)
| p~1 => op a (p_iter p (op a a))
end.(** ** Power *)Definitionpos_pow (x : Pos) := pos_iter (pos_mul x) 1.(** ** Square *)Fixpointpos_squarep :=
match p with
| p~1 => (pos_square p + p)~0~1
| p~0 => (pos_square p)~0~0
| 1 => 1end.(** ** Division by 2 rounded below but for 1 *)Definitionpos_div2p :=
match p with
| 1 => 1
| p~0 => p
| p~1 => p
end.(** Division by 2 rounded up *)Definitionpos_div2_upp :=
match p with
| 1 => 1
| p~0 => p
| p~1 => pos_succ p
end.(** ** Number of digits in a positive number *)Fixpointnat_pos_sizep : nat :=
match p with
| 1 => S O
| p~1 => S (nat_pos_size p)
| p~0 => S (nat_pos_size p)
end.(** Same, with positive output *)Fixpointpos_sizep :=
match p with
| 1 => 1
| p~1 => pos_succ (pos_size p)
| p~0 => pos_succ (pos_size p)
end.(** ** From binary positive numbers to Peano natural numbers *)(** Sends [n] to [n], missing [0]. *)Definitionnat_of_pos (p : Pos) : nat
:= pos_iter S p 0%nat.(** ** From Peano natural numbers to binary positive numbers *)(** A version preserving positive numbers, and sending 0 to 1. *)Fixpointpos_of_nat (n : nat) : Pos :=
match n with
| O => 1
| S O => 1
| S x => pos_succ (pos_of_nat x)
end.(* Another version that converts [n] into [n+1] *)Fixpointpos_of_succ_nat (n : nat) : Pos :=
match n with
| O => 1
| S x => pos_succ (pos_of_succ_nat x)
end.(** ** Conversion with a decimal representation for printing/parsing *)Local Notationten := 1~0~1~0.Fixpointpos_of_uint_acc (d : Decimal.uint) (acc : Pos) :=
match d with
| Decimal.Nil => acc
| Decimal.D0 l => pos_of_uint_acc l (pos_mul ten acc)
| Decimal.D1 l => pos_of_uint_acc l (pos_add 1 (pos_mul ten acc))
| Decimal.D2 l => pos_of_uint_acc l (pos_add 1~0 (pos_mul ten acc))
| Decimal.D3 l => pos_of_uint_acc l (pos_add 1~1 (pos_mul ten acc))
| Decimal.D4 l => pos_of_uint_acc l (pos_add 1~0~0 (pos_mul ten acc))
| Decimal.D5 l => pos_of_uint_acc l (pos_add 1~0~1 (pos_mul ten acc))
| Decimal.D6 l => pos_of_uint_acc l (pos_add 1~1~0 (pos_mul ten acc))
| Decimal.D7 l => pos_of_uint_acc l (pos_add 1~1~1 (pos_mul ten acc))
| Decimal.D8 l => pos_of_uint_acc l (pos_add 1~0~0~0 (pos_mul ten acc))
| Decimal.D9 l => pos_of_uint_acc l (pos_add 1~0~0~1 (pos_mul ten acc))
end.Fixpointpos_of_uint (d : Decimal.uint) : option Pos :=
match d with
| Decimal.Nil => None
| Decimal.D0 l => pos_of_uint l
| Decimal.D1 l => Some (pos_of_uint_acc l 1)
| Decimal.D2 l => Some (pos_of_uint_acc l 1~0)
| Decimal.D3 l => Some (pos_of_uint_acc l 1~1)
| Decimal.D4 l => Some (pos_of_uint_acc l 1~0~0)
| Decimal.D5 l => Some (pos_of_uint_acc l 1~0~1)
| Decimal.D6 l => Some (pos_of_uint_acc l 1~1~0)
| Decimal.D7 l => Some (pos_of_uint_acc l 1~1~1)
| Decimal.D8 l => Some (pos_of_uint_acc l 1~0~0~0)
| Decimal.D9 l => Some (pos_of_uint_acc l 1~0~0~1)
end.Definitionpos_of_decimal_int (d:Decimal.int) : option Pos :=
match d with
| Decimal.Pos d => pos_of_uint d
| Decimal.Neg _ => None
end.Definitionpos_of_number_uint (d:Numeral.int) : option Pos :=
match d with
| Numeral.IntDec d => pos_of_decimal_int d
| Numeral.IntHex _ => None
end.Fixpointpos_to_little_uintp :=
match p with
| 1 => Decimal.D1 Decimal.Nil
| p~1 => Decimal.Little.succ_double (pos_to_little_uint p)
| p~0 => Decimal.Little.double (pos_to_little_uint p)
end.Definitionpos_to_uintp := Decimal.rev (pos_to_little_uint p).Definitionpos_to_decimal_intn := Decimal.Pos (pos_to_uint n).Definitionpos_to_number_uintp := Numeral.UIntDec (pos_to_uint p).
Pos -> nat
Pos -> nat
p: Pos
nat
nat
p: Pos IHp: nat
nat
p: Pos IHp: nat
nat
nat
exact (S O).
p: Pos IHp: nat
nat
exact (nat_add IHp IHp).
p: Pos IHp: nat
nat
exact (S (nat_add IHp IHp)).Defined.Number NotationPos pos_of_number_uint pos_to_number_uint : positive_scope.