summaryrefslogtreecommitdiff
path: root/theories/NArith/BinPos.v
diff options
context:
space:
mode:
Diffstat (limited to 'theories/NArith/BinPos.v')
-rw-r--r--theories/NArith/BinPos.v1172
1 files changed, 0 insertions, 1172 deletions
diff --git a/theories/NArith/BinPos.v b/theories/NArith/BinPos.v
deleted file mode 100644
index 62bd57c0..00000000
--- a/theories/NArith/BinPos.v
+++ /dev/null
@@ -1,1172 +0,0 @@
-(* -*- coding: utf-8 -*- *)
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2011 *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(************************************************************************)
-
-(*i $Id: BinPos.v 14641 2011-11-06 11:59:10Z herbelin $ i*)
-
-Unset Boxed Definitions.
-
-Declare ML Module "z_syntax_plugin".
-
-(**********************************************************************)
-(** Binary positive numbers *)
-
-(** Original development by Pierre Crégut, CNET, Lannion, France *)
-
-Inductive positive : Set :=
-| xI : positive -> positive
-| xO : positive -> positive
-| xH : positive.
-
-(** Declare binding key for scope positive_scope *)
-
-Delimit Scope positive_scope with positive.
-
-(** Automatically open scope positive_scope for type positive, xO and xI *)
-
-Bind Scope positive_scope with positive.
-Arguments Scope xO [positive_scope].
-Arguments Scope xI [positive_scope].
-
-(** Postfix notation for positive numbers, allowing to mimic
- the position of bits in a big-endian representation.
- For instance, we can write 1~1~0 instead of (xO (xI xH))
- for the number 6 (which is 110 in binary notation).
-*)
-
-Notation "p ~ 1" := (xI p)
- (at level 7, left associativity, format "p '~' '1'") : positive_scope.
-Notation "p ~ 0" := (xO p)
- (at level 7, left associativity, format "p '~' '0'") : positive_scope.
-
-Open Local Scope positive_scope.
-
-(* In the current file, [xH] cannot yet be written as [1], since the
- interpretation of positive numerical constants is not available
- yet. We fix this here with an ad-hoc temporary notation. *)
-
-Notation Local "1" := xH (at level 7).
-
-(** Successor *)
-
-Fixpoint Psucc (x:positive) : positive :=
- match x with
- | p~1 => (Psucc p)~0
- | p~0 => p~1
- | 1 => 1~0
- end.
-
-(** Addition *)
-
-Set Boxed Definitions.
-
-Fixpoint Pplus (x y:positive) : positive :=
- match x, y with
- | p~1, q~1 => (Pplus_carry p q)~0
- | p~1, q~0 => (Pplus p q)~1
- | p~1, 1 => (Psucc p)~0
- | p~0, q~1 => (Pplus p q)~1
- | p~0, q~0 => (Pplus p q)~0
- | p~0, 1 => p~1
- | 1, q~1 => (Psucc q)~0
- | 1, q~0 => q~1
- | 1, 1 => 1~0
- end
-
-with Pplus_carry (x y:positive) : positive :=
- match x, y with
- | p~1, q~1 => (Pplus_carry p q)~1
- | p~1, q~0 => (Pplus_carry p q)~0
- | p~1, 1 => (Psucc p)~1
- | p~0, q~1 => (Pplus_carry p q)~0
- | p~0, q~0 => (Pplus p q)~1
- | p~0, 1 => (Psucc p)~0
- | 1, q~1 => (Psucc q)~1
- | 1, q~0 => (Psucc q)~0
- | 1, 1 => 1~1
- end.
-
-Unset Boxed Definitions.
-
-Infix "+" := Pplus : positive_scope.
-
-(** From binary positive numbers to Peano natural numbers *)
-
-Fixpoint Pmult_nat (x:positive) (pow2:nat) : nat :=
- match x with
- | p~1 => (pow2 + Pmult_nat p (pow2 + pow2))%nat
- | p~0 => Pmult_nat p (pow2 + pow2)%nat
- | 1 => pow2
- end.
-
-Definition nat_of_P (x:positive) := Pmult_nat x (S O).
-
-(** From Peano natural numbers to binary positive numbers *)
-
-Fixpoint P_of_succ_nat (n:nat) : positive :=
- match n with
- | O => 1
- | S x => Psucc (P_of_succ_nat x)
- end.
-
-(** Operation x -> 2*x-1 *)
-
-Fixpoint Pdouble_minus_one (x:positive) : positive :=
- match x with
- | p~1 => p~0~1
- | p~0 => (Pdouble_minus_one p)~1
- | 1 => 1
- end.
-
-(** Predecessor *)
-
-Definition Ppred (x:positive) :=
- match x with
- | p~1 => p~0
- | p~0 => Pdouble_minus_one p
- | 1 => 1
- end.
-
-(** An auxiliary type for subtraction *)
-
-Inductive positive_mask : Set :=
-| IsNul : positive_mask
-| IsPos : positive -> positive_mask
-| IsNeg : positive_mask.
-
-(** Operation x -> 2*x+1 *)
-
-Definition Pdouble_plus_one_mask (x:positive_mask) :=
- match x with
- | IsNul => IsPos 1
- | IsNeg => IsNeg
- | IsPos p => IsPos p~1
- end.
-
-(** Operation x -> 2*x *)
-
-Definition Pdouble_mask (x:positive_mask) :=
- match x with
- | IsNul => IsNul
- | IsNeg => IsNeg
- | IsPos p => IsPos p~0
- end.
-
-(** Operation x -> 2*x-2 *)
-
-Definition Pdouble_minus_two (x:positive) :=
- match x with
- | p~1 => IsPos p~0~0
- | p~0 => IsPos (Pdouble_minus_one p)~0
- | 1 => IsNul
- end.
-
-(** Subtraction of binary positive numbers into a positive numbers mask *)
-
-Fixpoint Pminus_mask (x y:positive) {struct y} : positive_mask :=
- match x, y with
- | p~1, q~1 => Pdouble_mask (Pminus_mask p q)
- | p~1, q~0 => Pdouble_plus_one_mask (Pminus_mask p q)
- | p~1, 1 => IsPos p~0
- | p~0, q~1 => Pdouble_plus_one_mask (Pminus_mask_carry p q)
- | p~0, q~0 => Pdouble_mask (Pminus_mask p q)
- | p~0, 1 => IsPos (Pdouble_minus_one p)
- | 1, 1 => IsNul
- | 1, _ => IsNeg
- end
-
-with Pminus_mask_carry (x y:positive) {struct y} : positive_mask :=
- match x, y with
- | p~1, q~1 => Pdouble_plus_one_mask (Pminus_mask_carry p q)
- | p~1, q~0 => Pdouble_mask (Pminus_mask p q)
- | p~1, 1 => IsPos (Pdouble_minus_one p)
- | p~0, q~1 => Pdouble_mask (Pminus_mask_carry p q)
- | p~0, q~0 => Pdouble_plus_one_mask (Pminus_mask_carry p q)
- | p~0, 1 => Pdouble_minus_two p
- | 1, _ => IsNeg
- end.
-
-(** Subtraction of binary positive numbers x and y, returns 1 if x<=y *)
-
-Definition Pminus (x y:positive) :=
- match Pminus_mask x y with
- | IsPos z => z
- | _ => 1
- end.
-
-Infix "-" := Pminus : positive_scope.
-
-(** Multiplication on binary positive numbers *)
-
-Fixpoint Pmult (x y:positive) : positive :=
- match x with
- | p~1 => y + (Pmult p y)~0
- | p~0 => (Pmult p y)~0
- | 1 => y
- end.
-
-Infix "*" := Pmult : positive_scope.
-
-(** Division by 2 rounded below but for 1 *)
-
-Definition Pdiv2 (z:positive) :=
- match z with
- | 1 => 1
- | p~0 => p
- | p~1 => p
- end.
-
-Infix "/" := Pdiv2 : positive_scope.
-
-(** Comparison on binary positive numbers *)
-
-Fixpoint Pcompare (x y:positive) (r:comparison) {struct y} : comparison :=
- match x, y with
- | p~1, q~1 => Pcompare p q r
- | p~1, q~0 => Pcompare p q Gt
- | p~1, 1 => Gt
- | p~0, q~1 => Pcompare p q Lt
- | p~0, q~0 => Pcompare p q r
- | p~0, 1 => Gt
- | 1, q~1 => Lt
- | 1, q~0 => Lt
- | 1, 1 => r
- end.
-
-Infix "?=" := Pcompare (at level 70, no associativity) : positive_scope.
-
-Definition Plt (x y:positive) := (Pcompare x y Eq) = Lt.
-Definition Pgt (x y:positive) := (Pcompare x y Eq) = Gt.
-Definition Ple (x y:positive) := (Pcompare x y Eq) <> Gt.
-Definition Pge (x y:positive) := (Pcompare x y Eq) <> Lt.
-
-Infix "<=" := Ple : positive_scope.
-Infix "<" := Plt : positive_scope.
-Infix ">=" := Pge : positive_scope.
-Infix ">" := Pgt : positive_scope.
-
-Notation "x <= y <= z" := (x <= y /\ y <= z) : positive_scope.
-Notation "x <= y < z" := (x <= y /\ y < z) : positive_scope.
-Notation "x < y < z" := (x < y /\ y < z) : positive_scope.
-Notation "x < y <= z" := (x < y /\ y <= z) : positive_scope.
-
-
-Definition Pmin (p p' : positive) := match Pcompare p p' Eq with
- | Lt | Eq => p
- | Gt => p'
- end.
-
-Definition Pmax (p p' : positive) := match Pcompare p p' Eq with
- | Lt | Eq => p'
- | Gt => p
- end.
-
-(********************************************************************)
-(** Boolean equality *)
-
-Fixpoint Peqb (x y : positive) {struct y} : bool :=
- match x, y with
- | 1, 1 => true
- | p~1, q~1 => Peqb p q
- | p~0, q~0 => Peqb p q
- | _, _ => false
- end.
-
-(**********************************************************************)
-(** Decidability of equality on binary positive numbers *)
-
-Lemma positive_eq_dec : forall x y: positive, {x = y} + {x <> y}.
-Proof.
- decide equality.
-Defined.
-
-(* begin hide *)
-Corollary ZL11 : forall p:positive, p = 1 \/ p <> 1.
-Proof.
- intro; edestruct positive_eq_dec; eauto.
-Qed.
-(* end hide *)
-
-(**********************************************************************)
-(** Properties of successor on binary positive numbers *)
-
-(** Specification of [xI] in term of [Psucc] and [xO] *)
-
-Lemma xI_succ_xO : forall p:positive, p~1 = Psucc p~0.
-Proof.
- reflexivity.
-Qed.
-
-Lemma Psucc_discr : forall p:positive, p <> Psucc p.
-Proof.
- destruct p; discriminate.
-Qed.
-
-(** Successor and double *)
-
-Lemma Psucc_o_double_minus_one_eq_xO :
- forall p:positive, Psucc (Pdouble_minus_one p) = p~0.
-Proof.
- induction p; simpl; f_equal; auto.
-Qed.
-
-Lemma Pdouble_minus_one_o_succ_eq_xI :
- forall p:positive, Pdouble_minus_one (Psucc p) = p~1.
-Proof.
- induction p; simpl; f_equal; auto.
-Qed.
-
-Lemma xO_succ_permute :
- forall p:positive, (Psucc p)~0 = Psucc (Psucc p~0).
-Proof.
- induction p; simpl; auto.
-Qed.
-
-Lemma double_moins_un_xO_discr :
- forall p:positive, Pdouble_minus_one p <> p~0.
-Proof.
- destruct p; discriminate.
-Qed.
-
-(** Successor and predecessor *)
-
-Lemma Psucc_not_one : forall p:positive, Psucc p <> 1.
-Proof.
- destruct p; discriminate.
-Qed.
-
-Lemma Ppred_succ : forall p:positive, Ppred (Psucc p) = p.
-Proof.
- intros [[p|p| ]|[p|p| ]| ]; simpl; auto.
- f_equal; apply Pdouble_minus_one_o_succ_eq_xI.
-Qed.
-
-Lemma Psucc_pred : forall p:positive, p = 1 \/ Psucc (Ppred p) = p.
-Proof.
- induction p; simpl; auto.
- right; apply Psucc_o_double_minus_one_eq_xO.
-Qed.
-
-Ltac destr_eq H := discriminate H || (try (injection H; clear H; intro H)).
-
-(** Injectivity of successor *)
-
-Lemma Psucc_inj : forall p q:positive, Psucc p = Psucc q -> p = q.
-Proof.
- induction p; intros [q|q| ] H; simpl in *; destr_eq H; f_equal; auto.
- elim (Psucc_not_one p); auto.
- elim (Psucc_not_one q); auto.
-Qed.
-
-(**********************************************************************)
-(** Properties of addition on binary positive numbers *)
-
-(** Specification of [Psucc] in term of [Pplus] *)
-
-Lemma Pplus_one_succ_r : forall p:positive, Psucc p = p + 1.
-Proof.
- destruct p; reflexivity.
-Qed.
-
-Lemma Pplus_one_succ_l : forall p:positive, Psucc p = 1 + p.
-Proof.
- destruct p; reflexivity.
-Qed.
-
-(** Specification of [Pplus_carry] *)
-
-Theorem Pplus_carry_spec :
- forall p q:positive, Pplus_carry p q = Psucc (p + q).
-Proof.
- induction p; destruct q; simpl; f_equal; auto.
-Qed.
-
-(** Commutativity *)
-
-Theorem Pplus_comm : forall p q:positive, p + q = q + p.
-Proof.
- induction p; destruct q; simpl; f_equal; auto.
- rewrite 2 Pplus_carry_spec; f_equal; auto.
-Qed.
-
-(** Permutation of [Pplus] and [Psucc] *)
-
-Theorem Pplus_succ_permute_r :
- forall p q:positive, p + Psucc q = Psucc (p + q).
-Proof.
- induction p; destruct q; simpl; f_equal;
- auto using Pplus_one_succ_r; rewrite Pplus_carry_spec; auto.
-Qed.
-
-Theorem Pplus_succ_permute_l :
- forall p q:positive, Psucc p + q = Psucc (p + q).
-Proof.
- intros p q; rewrite Pplus_comm, (Pplus_comm p);
- apply Pplus_succ_permute_r.
-Qed.
-
-Theorem Pplus_carry_pred_eq_plus :
- forall p q:positive, q <> 1 -> Pplus_carry p (Ppred q) = p + q.
-Proof.
- intros p q H; rewrite Pplus_carry_spec, <- Pplus_succ_permute_r; f_equal.
- destruct (Psucc_pred q); [ elim H; assumption | assumption ].
-Qed.
-
-(** No neutral for addition on strictly positive numbers *)
-
-Lemma Pplus_no_neutral : forall p q:positive, q + p <> p.
-Proof.
- induction p as [p IHp|p IHp| ]; intros [q|q| ] H;
- destr_eq H; apply (IHp q H).
-Qed.
-
-Lemma Pplus_carry_no_neutral :
- forall p q:positive, Pplus_carry q p <> Psucc p.
-Proof.
- intros p q H; elim (Pplus_no_neutral p q).
- apply Psucc_inj; rewrite <- Pplus_carry_spec; assumption.
-Qed.
-
-(** Simplification *)
-
-Lemma Pplus_carry_plus :
- forall p q r s:positive, Pplus_carry p r = Pplus_carry q s -> p + r = q + s.
-Proof.
- intros p q r s H; apply Psucc_inj; do 2 rewrite <- Pplus_carry_spec;
- assumption.
-Qed.
-
-Lemma Pplus_reg_r : forall p q r:positive, p + r = q + r -> p = q.
-Proof.
- intros p q r; revert p q; induction r.
- intros [p|p| ] [q|q| ] H; simpl; destr_eq H;
- f_equal; auto using Pplus_carry_plus;
- contradict H; auto using Pplus_carry_no_neutral.
- intros [p|p| ] [q|q| ] H; simpl; destr_eq H; f_equal; auto;
- contradict H; auto using Pplus_no_neutral.
- intros p q H; apply Psucc_inj; do 2 rewrite Pplus_one_succ_r; assumption.
-Qed.
-
-Lemma Pplus_reg_l : forall p q r:positive, p + q = p + r -> q = r.
-Proof.
- intros p q r H; apply Pplus_reg_r with (r:=p).
- rewrite (Pplus_comm r), (Pplus_comm q); assumption.
-Qed.
-
-Lemma Pplus_carry_reg_r :
- forall p q r:positive, Pplus_carry p r = Pplus_carry q r -> p = q.
-Proof.
- intros p q r H; apply Pplus_reg_r with (r:=r); apply Pplus_carry_plus;
- assumption.
-Qed.
-
-Lemma Pplus_carry_reg_l :
- forall p q r:positive, Pplus_carry p q = Pplus_carry p r -> q = r.
-Proof.
- intros p q r H; apply Pplus_reg_r with (r:=p);
- rewrite (Pplus_comm r), (Pplus_comm q); apply Pplus_carry_plus; assumption.
-Qed.
-
-(** Addition on positive is associative *)
-
-Theorem Pplus_assoc : forall p q r:positive, p + (q + r) = p + q + r.
-Proof.
- induction p.
- intros [q|q| ] [r|r| ]; simpl; f_equal; auto;
- rewrite ?Pplus_carry_spec, ?Pplus_succ_permute_r,
- ?Pplus_succ_permute_l, ?Pplus_one_succ_r; f_equal; auto.
- intros [q|q| ] [r|r| ]; simpl; f_equal; auto;
- rewrite ?Pplus_carry_spec, ?Pplus_succ_permute_r,
- ?Pplus_succ_permute_l, ?Pplus_one_succ_r; f_equal; auto.
- intros p r; rewrite <- 2 Pplus_one_succ_l, Pplus_succ_permute_l; auto.
-Qed.
-
-(** Commutation of addition with the double of a positive number *)
-
-Lemma Pplus_xO : forall m n : positive, (m + n)~0 = m~0 + n~0.
-Proof.
- destruct n; destruct m; simpl; auto.
-Qed.
-
-Lemma Pplus_xI_double_minus_one :
- forall p q:positive, (p + q)~0 = p~1 + Pdouble_minus_one q.
-Proof.
- intros; change (p~1) with (p~0 + 1).
- rewrite <- Pplus_assoc, <- Pplus_one_succ_l, Psucc_o_double_minus_one_eq_xO.
- reflexivity.
-Qed.
-
-Lemma Pplus_xO_double_minus_one :
- forall p q:positive, Pdouble_minus_one (p + q) = p~0 + Pdouble_minus_one q.
-Proof.
- induction p as [p IHp| p IHp| ]; destruct q; simpl;
- rewrite ?Pplus_carry_spec, ?Pdouble_minus_one_o_succ_eq_xI,
- ?Pplus_xI_double_minus_one; try reflexivity.
- rewrite IHp; auto.
- rewrite <- Psucc_o_double_minus_one_eq_xO, Pplus_one_succ_l; reflexivity.
-Qed.
-
-(** Misc *)
-
-Lemma Pplus_diag : forall p:positive, p + p = p~0.
-Proof.
- induction p as [p IHp| p IHp| ]; simpl;
- try rewrite ?Pplus_carry_spec, ?IHp; reflexivity.
-Qed.
-
-(**********************************************************************)
-(** Peano induction and recursion on binary positive positive numbers *)
-(** (a nice proof from Conor McBride, see "The view from the left") *)
-
-Inductive PeanoView : positive -> Type :=
-| PeanoOne : PeanoView 1
-| PeanoSucc : forall p, PeanoView p -> PeanoView (Psucc p).
-
-Fixpoint peanoView_xO p (q:PeanoView p) : PeanoView (p~0) :=
- match q in PeanoView x return PeanoView (x~0) with
- | PeanoOne => PeanoSucc _ PeanoOne
- | PeanoSucc _ q => PeanoSucc _ (PeanoSucc _ (peanoView_xO _ q))
- end.
-
-Fixpoint peanoView_xI p (q:PeanoView p) : PeanoView (p~1) :=
- match q in PeanoView x return PeanoView (x~1) with
- | PeanoOne => PeanoSucc _ (PeanoSucc _ PeanoOne)
- | PeanoSucc _ q => PeanoSucc _ (PeanoSucc _ (peanoView_xI _ q))
- end.
-
-Fixpoint peanoView p : PeanoView p :=
- match p return PeanoView p with
- | 1 => PeanoOne
- | p~0 => peanoView_xO p (peanoView p)
- | p~1 => peanoView_xI p (peanoView p)
- end.
-
-Definition PeanoView_iter (P:positive->Type)
- (a:P 1) (f:forall p, P p -> P (Psucc p)) :=
- (fix iter p (q:PeanoView p) : P p :=
- match q in PeanoView p return P p with
- | PeanoOne => a
- | PeanoSucc _ q => f _ (iter _ q)
- end).
-
-Require Import Eqdep_dec EqdepFacts.
-
-Theorem eq_dep_eq_positive :
- forall (P:positive->Type) (p:positive) (x y:P p),
- eq_dep positive P p x p y -> x = y.
-Proof.
- apply eq_dep_eq_dec.
- decide equality.
-Qed.
-
-Theorem PeanoViewUnique : forall p (q q':PeanoView p), q = q'.
-Proof.
- intros.
- induction q as [ | p q IHq ].
- apply eq_dep_eq_positive.
- cut (1=1). pattern 1 at 1 2 5, q'. destruct q'. trivial.
- destruct p0; intros; discriminate.
- trivial.
- apply eq_dep_eq_positive.
- cut (Psucc p=Psucc p). pattern (Psucc p) at 1 2 5, q'. destruct q'.
- intro. destruct p; discriminate.
- intro. unfold p0 in H. apply Psucc_inj in H.
- generalize q'. rewrite H. intro.
- rewrite (IHq q'0).
- trivial.
- trivial.
-Qed.
-
-Definition Prect (P:positive->Type) (a:P 1) (f:forall p, P p -> P (Psucc p))
- (p:positive) :=
- PeanoView_iter P a f p (peanoView p).
-
-Theorem Prect_succ : forall (P:positive->Type) (a:P 1)
- (f:forall p, P p -> P (Psucc p)) (p:positive),
- Prect P a f (Psucc p) = f _ (Prect P a f p).
-Proof.
- intros.
- unfold Prect.
- rewrite (PeanoViewUnique _ (peanoView (Psucc p)) (PeanoSucc _ (peanoView p))).
- trivial.
-Qed.
-
-Theorem Prect_base : forall (P:positive->Type) (a:P 1)
- (f:forall p, P p -> P (Psucc p)), Prect P a f 1 = a.
-Proof.
- trivial.
-Qed.
-
-Definition Prec (P:positive->Set) := Prect P.
-
-(** Peano induction *)
-
-Definition Pind (P:positive->Prop) := Prect P.
-
-(** Peano case analysis *)
-
-Theorem Pcase :
- forall P:positive -> Prop,
- P 1 -> (forall n:positive, P (Psucc n)) -> forall p:positive, P p.
-Proof.
- intros; apply Pind; auto.
-Qed.
-
-(**********************************************************************)
-(** Properties of multiplication on binary positive numbers *)
-
-(** One is right neutral for multiplication *)
-
-Lemma Pmult_1_r : forall p:positive, p * 1 = p.
-Proof.
- induction p; simpl; f_equal; auto.
-Qed.
-
-(** Successor and multiplication *)
-
-Lemma Pmult_Sn_m : forall n m : positive, (Psucc n) * m = m + n * m.
-Proof.
- induction n as [n IHn | n IHn | ]; simpl; intro m.
- rewrite IHn, Pplus_assoc, Pplus_diag, <-Pplus_xO; reflexivity.
- reflexivity.
- symmetry; apply Pplus_diag.
-Qed.
-
-(** Right reduction properties for multiplication *)
-
-Lemma Pmult_xO_permute_r : forall p q:positive, p * q~0 = (p * q)~0.
-Proof.
- intros p q; induction p; simpl; do 2 (f_equal; auto).
-Qed.
-
-Lemma Pmult_xI_permute_r : forall p q:positive, p * q~1 = p + (p * q)~0.
-Proof.
- intros p q; induction p as [p IHp|p IHp| ]; simpl; f_equal; auto.
- rewrite IHp, 2 Pplus_assoc, (Pplus_comm p); reflexivity.
-Qed.
-
-(** Commutativity of multiplication *)
-
-Theorem Pmult_comm : forall p q:positive, p * q = q * p.
-Proof.
- intros p q; induction q as [q IHq|q IHq| ]; simpl; try rewrite <- IHq;
- auto using Pmult_xI_permute_r, Pmult_xO_permute_r, Pmult_1_r.
-Qed.
-
-(** Distributivity of multiplication over addition *)
-
-Theorem Pmult_plus_distr_l :
- forall p q r:positive, p * (q + r) = p * q + p * r.
-Proof.
- intros p q r; induction p as [p IHp|p IHp| ]; simpl.
- rewrite IHp. set (m:=(p*q)~0). set (n:=(p*r)~0).
- change ((p*q+p*r)~0) with (m+n).
- rewrite 2 Pplus_assoc; f_equal.
- rewrite <- 2 Pplus_assoc; f_equal.
- apply Pplus_comm.
- f_equal; auto.
- reflexivity.
-Qed.
-
-Theorem Pmult_plus_distr_r :
- forall p q r:positive, (p + q) * r = p * r + q * r.
-Proof.
- intros p q r; do 3 rewrite Pmult_comm with (q:=r); apply Pmult_plus_distr_l.
-Qed.
-
-(** Associativity of multiplication *)
-
-Theorem Pmult_assoc : forall p q r:positive, p * (q * r) = p * q * r.
-Proof.
- induction p as [p IHp| p IHp | ]; simpl; intros q r.
- rewrite IHp; rewrite Pmult_plus_distr_r; reflexivity.
- rewrite IHp; reflexivity.
- reflexivity.
-Qed.
-
-(** Parity properties of multiplication *)
-
-Lemma Pmult_xI_mult_xO_discr : forall p q r:positive, p~1 * r <> q~0 * r.
-Proof.
- intros p q r; induction r; try discriminate.
- rewrite 2 Pmult_xO_permute_r; intro H; destr_eq H; auto.
-Qed.
-
-Lemma Pmult_xO_discr : forall p q:positive, p~0 * q <> q.
-Proof.
- intros p q; induction q; try discriminate.
- rewrite Pmult_xO_permute_r; injection; assumption.
-Qed.
-
-(** Simplification properties of multiplication *)
-
-Theorem Pmult_reg_r : forall p q r:positive, p * r = q * r -> p = q.
-Proof.
- induction p as [p IHp| p IHp| ]; intros [q|q| ] r H;
- reflexivity || apply (f_equal (A:=positive)) || apply False_ind.
- apply IHp with (r~0); simpl in *;
- rewrite 2 Pmult_xO_permute_r; apply Pplus_reg_l with (1:=H).
- apply Pmult_xI_mult_xO_discr with (1:=H).
- simpl in H; rewrite Pplus_comm in H; apply Pplus_no_neutral with (1:=H).
- symmetry in H; apply Pmult_xI_mult_xO_discr with (1:=H).
- apply IHp with (r~0); simpl; rewrite 2 Pmult_xO_permute_r; assumption.
- apply Pmult_xO_discr with (1:= H).
- simpl in H; symmetry in H; rewrite Pplus_comm in H;
- apply Pplus_no_neutral with (1:=H).
- symmetry in H; apply Pmult_xO_discr with (1:=H).
-Qed.
-
-Theorem Pmult_reg_l : forall p q r:positive, r * p = r * q -> p = q.
-Proof.
- intros p q r H; apply Pmult_reg_r with (r:=r).
- rewrite (Pmult_comm p), (Pmult_comm q); assumption.
-Qed.
-
-(** Inversion of multiplication *)
-
-Lemma Pmult_1_inversion_l : forall p q:positive, p * q = 1 -> p = 1.
-Proof.
- intros [p|p| ] [q|q| ] H; destr_eq H; auto.
-Qed.
-
-(*********************************************************************)
-(** Properties of boolean equality *)
-
-Theorem Peqb_refl : forall x:positive, Peqb x x = true.
-Proof.
- induction x; auto.
-Qed.
-
-Theorem Peqb_true_eq : forall x y:positive, Peqb x y = true -> x=y.
-Proof.
- induction x; destruct y; simpl; intros; try discriminate.
- f_equal; auto.
- f_equal; auto.
- reflexivity.
-Qed.
-
-Theorem Peqb_eq : forall x y : positive, Peqb x y = true <-> x=y.
-Proof.
- split. apply Peqb_true_eq.
- intros; subst; apply Peqb_refl.
-Qed.
-
-
-(**********************************************************************)
-(** Properties of comparison on binary positive numbers *)
-
-Theorem Pcompare_refl : forall p:positive, (p ?= p) Eq = Eq.
- induction p; auto.
-Qed.
-
-(* A generalization of Pcompare_refl *)
-
-Theorem Pcompare_refl_id : forall (p : positive) (r : comparison), (p ?= p) r = r.
- induction p; auto.
-Qed.
-
-Theorem Pcompare_not_Eq :
- forall p q:positive, (p ?= q) Gt <> Eq /\ (p ?= q) Lt <> Eq.
-Proof.
- induction p as [p IHp| p IHp| ]; intros [q| q| ]; split; simpl; auto;
- discriminate || (elim (IHp q); auto).
-Qed.
-
-Theorem Pcompare_Eq_eq : forall p q:positive, (p ?= q) Eq = Eq -> p = q.
-Proof.
- induction p; intros [q| q| ] H; simpl in *; auto;
- try discriminate H; try (f_equal; auto; fail).
- destruct (Pcompare_not_Eq p q) as (H',_); elim H'; auto.
- destruct (Pcompare_not_Eq p q) as (_,H'); elim H'; auto.
-Qed.
-
-Lemma Pcompare_eq_iff : forall p q:positive, (p ?= q) Eq = Eq <-> p = q.
-Proof.
- split.
- apply Pcompare_Eq_eq.
- intros; subst; apply Pcompare_refl.
-Qed.
-
-Lemma Pcompare_Gt_Lt :
- forall p q:positive, (p ?= q) Gt = Lt -> (p ?= q) Eq = Lt.
-Proof.
- induction p; intros [q|q| ] H; simpl; auto; discriminate.
-Qed.
-
-Lemma Pcompare_eq_Lt :
- forall p q : positive, (p ?= q) Eq = Lt <-> (p ?= q) Gt = Lt.
-Proof.
- intros p q; split; [| apply Pcompare_Gt_Lt].
- revert q; induction p; intros [q|q| ] H; simpl; auto; discriminate.
-Qed.
-
-Lemma Pcompare_Lt_Gt :
- forall p q:positive, (p ?= q) Lt = Gt -> (p ?= q) Eq = Gt.
-Proof.
- induction p; intros [q|q| ] H; simpl; auto; discriminate.
-Qed.
-
-Lemma Pcompare_eq_Gt :
- forall p q : positive, (p ?= q) Eq = Gt <-> (p ?= q) Lt = Gt.
-Proof.
- intros p q; split; [| apply Pcompare_Lt_Gt].
- revert q; induction p; intros [q|q| ] H; simpl; auto; discriminate.
-Qed.
-
-Lemma Pcompare_Lt_Lt :
- forall p q:positive, (p ?= q) Lt = Lt -> (p ?= q) Eq = Lt \/ p = q.
-Proof.
- induction p as [p IHp| p IHp| ]; intros [q|q| ] H; simpl in *; auto;
- destruct (IHp q H); subst; auto.
-Qed.
-
-Lemma Pcompare_Lt_eq_Lt :
- forall p q:positive, (p ?= q) Lt = Lt <-> (p ?= q) Eq = Lt \/ p = q.
-Proof.
- intros p q; split; [apply Pcompare_Lt_Lt |].
- intros [H|H]; [|subst; apply Pcompare_refl_id].
- revert q H; induction p; intros [q|q| ] H; simpl in *;
- auto; discriminate.
-Qed.
-
-Lemma Pcompare_Gt_Gt :
- forall p q:positive, (p ?= q) Gt = Gt -> (p ?= q) Eq = Gt \/ p = q.
-Proof.
- induction p as [p IHp|p IHp| ]; intros [q|q| ] H; simpl in *; auto;
- destruct (IHp q H); subst; auto.
-Qed.
-
-Lemma Pcompare_Gt_eq_Gt :
- forall p q:positive, (p ?= q) Gt = Gt <-> (p ?= q) Eq = Gt \/ p = q.
-Proof.
- intros p q; split; [apply Pcompare_Gt_Gt |].
- intros [H|H]; [|subst; apply Pcompare_refl_id].
- revert q H; induction p; intros [q|q| ] H; simpl in *;
- auto; discriminate.
-Qed.
-
-Lemma Dcompare : forall r:comparison, r = Eq \/ r = Lt \/ r = Gt.
-Proof.
- destruct r; auto.
-Qed.
-
-Ltac ElimPcompare c1 c2 :=
- elim (Dcompare ((c1 ?= c2) Eq));
- [ idtac | let x := fresh "H" in (intro x; case x; clear x) ].
-
-Lemma Pcompare_antisym :
- forall (p q:positive) (r:comparison),
- CompOpp ((p ?= q) r) = (q ?= p) (CompOpp r).
-Proof.
- induction p as [p IHp|p IHp| ]; intros [q|q| ] r; simpl; auto;
- rewrite IHp; auto.
-Qed.
-
-Lemma ZC1 : forall p q:positive, (p ?= q) Eq = Gt -> (q ?= p) Eq = Lt.
-Proof.
- intros p q H; change Eq with (CompOpp Eq).
- rewrite <- Pcompare_antisym, H; reflexivity.
-Qed.
-
-Lemma ZC2 : forall p q:positive, (p ?= q) Eq = Lt -> (q ?= p) Eq = Gt.
-Proof.
- intros p q H; change Eq with (CompOpp Eq).
- rewrite <- Pcompare_antisym, H; reflexivity.
-Qed.
-
-Lemma ZC3 : forall p q:positive, (p ?= q) Eq = Eq -> (q ?= p) Eq = Eq.
-Proof.
- intros p q H; change Eq with (CompOpp Eq).
- rewrite <- Pcompare_antisym, H; reflexivity.
-Qed.
-
-Lemma ZC4 : forall p q:positive, (p ?= q) Eq = CompOpp ((q ?= p) Eq).
-Proof.
- intros; change Eq at 1 with (CompOpp Eq).
- symmetry; apply Pcompare_antisym.
-Qed.
-
-Lemma Pcompare_spec : forall p q, CompSpec eq Plt p q ((p ?= q) Eq).
-Proof.
- intros. destruct ((p ?= q) Eq) as [ ]_eqn; constructor.
- apply Pcompare_Eq_eq; auto.
- auto.
- apply ZC1; auto.
-Qed.
-
-
-(** Comparison and the successor *)
-
-Lemma Pcompare_p_Sp : forall p : positive, (p ?= Psucc p) Eq = Lt.
-Proof.
- induction p; simpl in *;
- [ elim (Pcompare_eq_Lt p (Psucc p)); auto |
- apply Pcompare_refl_id | reflexivity].
-Qed.
-
-Theorem Pcompare_p_Sq : forall p q : positive,
- (p ?= Psucc q) Eq = Lt <-> (p ?= q) Eq = Lt \/ p = q.
-Proof.
- intros p q; split.
- (* -> *)
- revert p q; induction p as [p IHp|p IHp| ]; intros [q|q| ] H; simpl in *;
- try (left; reflexivity); try (right; reflexivity).
- destruct (IHp q (Pcompare_Gt_Lt _ _ H)); subst; auto.
- destruct (Pcompare_eq_Lt p q); auto.
- destruct p; discriminate.
- left; destruct (IHp q H);
- [ elim (Pcompare_Lt_eq_Lt p q); auto | subst; apply Pcompare_refl_id].
- destruct (Pcompare_Lt_Lt p q H); subst; auto.
- destruct p; discriminate.
- (* <- *)
- intros [H|H]; [|subst; apply Pcompare_p_Sp].
- revert q H; induction p; intros [q|q| ] H; simpl in *;
- auto; try discriminate.
- destruct (Pcompare_eq_Lt p (Psucc q)); auto.
- apply Pcompare_Gt_Lt; auto.
- destruct (Pcompare_Lt_Lt p q H); subst; auto using Pcompare_p_Sp.
- destruct (Pcompare_Lt_eq_Lt p q); auto.
-Qed.
-
-(** 1 is the least positive number *)
-
-Lemma Pcompare_1 : forall p, ~ (p ?= 1) Eq = Lt.
-Proof.
- destruct p; discriminate.
-Qed.
-
-(** Properties of the strict order on positive numbers *)
-
-Lemma Plt_1 : forall p, ~ p < 1.
-Proof.
- exact Pcompare_1.
-Qed.
-
-Lemma Plt_lt_succ : forall n m : positive, n < m -> n < Psucc m.
-Proof.
- unfold Plt; intros n m H; apply <- Pcompare_p_Sq; auto.
-Qed.
-
-Lemma Plt_irrefl : forall p : positive, ~ p < p.
-Proof.
- unfold Plt; intro p; rewrite Pcompare_refl; discriminate.
-Qed.
-
-Lemma Plt_trans : forall n m p : positive, n < m -> m < p -> n < p.
-Proof.
- intros n m p; induction p using Pind; intros H H0.
- elim (Plt_1 _ H0).
- apply Plt_lt_succ.
- destruct (Pcompare_p_Sq m p) as (H',_); destruct (H' H0); subst; auto.
-Qed.
-
-Theorem Plt_ind : forall (A : positive -> Prop) (n : positive),
- A (Psucc n) ->
- (forall m : positive, n < m -> A m -> A (Psucc m)) ->
- forall m : positive, n < m -> A m.
-Proof.
- intros A n AB AS m. induction m using Pind; intros H.
- elim (Plt_1 _ H).
- destruct (Pcompare_p_Sq n m) as (H',_); destruct (H' H); subst; auto.
-Qed.
-
-Lemma Ple_lteq : forall p q, p <= q <-> p < q \/ p = q.
-Proof.
- unfold Ple, Plt. intros.
- generalize (Pcompare_eq_iff p q).
- destruct ((p ?= q) Eq); intuition; discriminate.
-Qed.
-
-
-(**********************************************************************)
-(** Properties of subtraction on binary positive numbers *)
-
-Lemma Ppred_minus : forall p, Ppred p = Pminus p 1.
-Proof.
- destruct p; auto.
-Qed.
-
-Definition Ppred_mask (p : positive_mask) :=
-match p with
-| IsPos 1 => IsNul
-| IsPos q => IsPos (Ppred q)
-| IsNul => IsNeg
-| IsNeg => IsNeg
-end.
-
-Lemma Pminus_mask_succ_r :
- forall p q : positive, Pminus_mask p (Psucc q) = Pminus_mask_carry p q.
-Proof.
- induction p ; destruct q; simpl; f_equal; auto; destruct p; auto.
-Qed.
-
-Theorem Pminus_mask_carry_spec :
- forall p q : positive, Pminus_mask_carry p q = Ppred_mask (Pminus_mask p q).
-Proof.
- induction p as [p IHp|p IHp| ]; destruct q; simpl;
- try reflexivity; try rewrite IHp;
- destruct (Pminus_mask p q) as [|[r|r| ]|] || destruct p; auto.
-Qed.
-
-Theorem Pminus_succ_r : forall p q : positive, p - (Psucc q) = Ppred (p - q).
-Proof.
- intros p q; unfold Pminus;
- rewrite Pminus_mask_succ_r, Pminus_mask_carry_spec.
- destruct (Pminus_mask p q) as [|[r|r| ]|]; auto.
-Qed.
-
-Lemma double_eq_zero_inversion :
- forall p:positive_mask, Pdouble_mask p = IsNul -> p = IsNul.
-Proof.
- destruct p; simpl; intros; trivial; discriminate.
-Qed.
-
-Lemma double_plus_one_zero_discr :
- forall p:positive_mask, Pdouble_plus_one_mask p <> IsNul.
-Proof.
- destruct p; discriminate.
-Qed.
-
-Lemma double_plus_one_eq_one_inversion :
- forall p:positive_mask, Pdouble_plus_one_mask p = IsPos 1 -> p = IsNul.
-Proof.
- destruct p; simpl; intros; trivial; discriminate.
-Qed.
-
-Lemma double_eq_one_discr :
- forall p:positive_mask, Pdouble_mask p <> IsPos 1.
-Proof.
- destruct p; discriminate.
-Qed.
-
-Theorem Pminus_mask_diag : forall p:positive, Pminus_mask p p = IsNul.
-Proof.
- induction p as [p IHp| p IHp| ]; simpl; try rewrite IHp; auto.
-Qed.
-
-Lemma Pminus_mask_carry_diag : forall p, Pminus_mask_carry p p = IsNeg.
-Proof.
- induction p as [p IHp| p IHp| ]; simpl; try rewrite IHp; auto.
-Qed.
-
-Lemma Pminus_mask_IsNeg : forall p q:positive,
- Pminus_mask p q = IsNeg -> Pminus_mask_carry p q = IsNeg.
-Proof.
- induction p as [p IHp|p IHp| ]; intros [q|q| ] H; simpl in *; auto;
- try discriminate; unfold Pdouble_mask, Pdouble_plus_one_mask in H;
- specialize IHp with q.
- destruct (Pminus_mask p q); try discriminate; rewrite IHp; auto.
- destruct (Pminus_mask p q); simpl; auto; try discriminate.
- destruct (Pminus_mask_carry p q); simpl; auto; try discriminate.
- destruct (Pminus_mask p q); try discriminate; rewrite IHp; auto.
-Qed.
-
-Lemma ZL10 :
- forall p q:positive,
- Pminus_mask p q = IsPos 1 -> Pminus_mask_carry p q = IsNul.
-Proof.
- induction p; intros [q|q| ] H; simpl in *; try discriminate.
- elim (double_eq_one_discr _ H).
- rewrite (double_plus_one_eq_one_inversion _ H); auto.
- rewrite (double_plus_one_eq_one_inversion _ H); auto.
- elim (double_eq_one_discr _ H).
- destruct p; simpl; auto; discriminate.
-Qed.
-
-(** Properties of subtraction valid only for x>y *)
-
-Lemma Pminus_mask_Gt :
- forall p q:positive,
- (p ?= q) Eq = Gt ->
- exists h : positive,
- Pminus_mask p q = IsPos h /\
- q + h = p /\ (h = 1 \/ Pminus_mask_carry p q = IsPos (Ppred h)).
-Proof.
- induction p as [p IHp| p IHp| ]; intros [q| q| ] H; simpl in *;
- try discriminate H.
- (* p~1, q~1 *)
- destruct (IHp q H) as (r & U & V & W); exists (r~0); rewrite ?U, ?V; auto.
- repeat split; auto; right.
- destruct (ZL11 r) as [EQ|NE]; [|destruct W as [|W]; [elim NE; auto|]].
- rewrite ZL10; subst; auto.
- rewrite W; simpl; destruct r; auto; elim NE; auto.
- (* p~1, q~0 *)
- destruct (Pcompare_Gt_Gt _ _ H) as [H'|H']; clear H; rename H' into H.
- destruct (IHp q H) as (r & U & V & W); exists (r~1); rewrite ?U, ?V; auto.
- exists 1; subst; rewrite Pminus_mask_diag; auto.
- (* p~1, 1 *)
- exists (p~0); auto.
- (* p~0, q~1 *)
- destruct (IHp q (Pcompare_Lt_Gt _ _ H)) as (r & U & V & W).
- destruct (ZL11 r) as [EQ|NE]; [|destruct W as [|W]; [elim NE; auto|]].
- exists 1; subst; rewrite ZL10, Pplus_one_succ_r; auto.
- exists ((Ppred r)~1); rewrite W, Pplus_carry_pred_eq_plus, V; auto.
- (* p~0, q~0 *)
- destruct (IHp q H) as (r & U & V & W); exists (r~0); rewrite ?U, ?V; auto.
- repeat split; auto; right.
- destruct (ZL11 r) as [EQ|NE]; [|destruct W as [|W]; [elim NE; auto|]].
- rewrite ZL10; subst; auto.
- rewrite W; simpl; destruct r; auto; elim NE; auto.
- (* p~0, 1 *)
- exists (Pdouble_minus_one p); repeat split; destruct p; simpl; auto.
- rewrite Psucc_o_double_minus_one_eq_xO; auto.
-Qed.
-
-Theorem Pplus_minus :
- forall p q:positive, (p ?= q) Eq = Gt -> q + (p - q) = p.
-Proof.
- intros p q H; destruct (Pminus_mask_Gt p q H) as (r & U & V & _).
- unfold Pminus; rewrite U; simpl; auto.
-Qed.
-
-(** When x<y, the substraction of x by y returns 1 *)
-
-Lemma Pminus_mask_Lt : forall p q:positive, p<q -> Pminus_mask p q = IsNeg.
-Proof.
- unfold Plt; induction p as [p IHp|p IHp| ]; destruct q; simpl; intros;
- try discriminate; try rewrite IHp; auto.
- apply Pcompare_Gt_Lt; auto.
- destruct (Pcompare_Lt_Lt _ _ H).
- rewrite Pminus_mask_IsNeg; simpl; auto.
- subst; rewrite Pminus_mask_carry_diag; auto.
-Qed.
-
-Lemma Pminus_Lt : forall p q:positive, p<q -> p-q = 1.
-Proof.
- intros; unfold Plt, Pminus; rewrite Pminus_mask_Lt; auto.
-Qed.
-
-(** The substraction of x by x returns 1 *)
-
-Lemma Pminus_Eq : forall p:positive, p-p = 1.
-Proof.
- intros; unfold Pminus; rewrite Pminus_mask_diag; auto.
-Qed.
-
-(** Number of digits in a number *)
-
-Fixpoint Psize (p:positive) : nat :=
- match p with
- | 1 => S O
- | p~1 => S (Psize p)
- | p~0 => S (Psize p)
- end.
-
-Lemma Psize_monotone : forall p q, (p?=q) Eq = Lt -> (Psize p <= Psize q)%nat.
-Proof.
- assert (le0 : forall n, (0<=n)%nat) by (induction n; auto).
- assert (leS : forall n m, (n<=m -> S n <= S m)%nat) by (induction 1; auto).
- induction p; destruct q; simpl; auto; intros; try discriminate.
- intros; generalize (Pcompare_Gt_Lt _ _ H); auto.
- intros; destruct (Pcompare_Lt_Lt _ _ H); auto; subst; auto.
-Qed.
-
-
-
-
-