diff options
Diffstat (limited to 'contrib/omega/Zcomplements.v')
-rw-r--r-- | contrib/omega/Zcomplements.v | 313 |
1 files changed, 313 insertions, 0 deletions
diff --git a/contrib/omega/Zcomplements.v b/contrib/omega/Zcomplements.v new file mode 100644 index 000000000..6bf081781 --- /dev/null +++ b/contrib/omega/Zcomplements.v @@ -0,0 +1,313 @@ +(****************************************************************************) +(* The Calculus of Inductive Constructions *) +(* *) +(* Projet Coq *) +(* *) +(* INRIA LRI-CNRS ENS-CNRS *) +(* Rocquencourt Orsay Lyon *) +(* *) +(* Coq V6.3 *) +(* July 1st 1999 *) +(* *) +(****************************************************************************) +(* Zcomplements.v *) +(****************************************************************************) + +Require Omega. +Require Wf_nat. + +(* Multiplication by a number >0 preserves Zcompare. It also perserves + Zle, Zlt, Zge, Zgt *) + +Implicit Arguments On. + +Lemma Zmult_zero : (x,y:Z)`x*y=0` -> `x=0` \/ `y=0`. +Destruct x; Destruct y; Auto. +Simpl; Intros; Discriminate H. +Simpl; Intros; Discriminate H. +Simpl; Intros; Discriminate H. +Simpl; Intros; Discriminate H. +Save. + +Lemma Zeq_Zminus : (x,y:Z)x=y -> `x-y = 0`. +Intros; Omega. +Save. + +Lemma Zminus_Zeq : (x,y:Z)`x-y=0` -> x=y. +Intros; Omega. +Save. + +Lemma Zmult_Zminus_distr_l : (x,y,z:Z)`(x-y)*z = x*z - y*z`. +Intros; Unfold Zminus. +Rewrite <- Zopp_Zmult. +Apply Zmult_plus_distr_l. +Save. + +Lemma Zmult_Zminus_distr_r : (x,y,z:Z)`z*(x-y) = z*x - z*y`. +Intros; Rewrite (Zmult_sym z `x-y`). +Rewrite (Zmult_sym z x). +Rewrite (Zmult_sym z y). +Apply Zmult_Zminus_distr_l. +Save. + +Lemma Zmult_reg_left : (x,y,z:Z)`z>0` -> `z*x=z*y` -> x=y. +Intros. +Generalize (Zeq_Zminus H0). +Intro. +Apply Zminus_Zeq. +Rewrite <- (Zmult_Zminus_distr_r x y z) in H1. +Elim (Zmult_zero H1). +Omega. +Trivial. +Save. + +Lemma Zmult_reg_right : (x,y,z:Z)`z>0` -> `x*z=y*z` -> x=y. +Intros x y z Hz. +Rewrite (Zmult_sym x z). +Rewrite (Zmult_sym y z). +Intro; Apply Zmult_reg_left with z; Assumption. +Save. + +Lemma Zgt0_le_pred : (y:Z) `y > 0` -> `0 <= (Zpred y)`. +Intro; Unfold Zpred; Omega. +Save. + +Lemma Zlt_Zplus : + (x1,x2,y1,y2:Z)`x1 < x2` -> `y1 < y2` -> `x1 + y1 < x2 + y2`. +Intros; Omega. +Save. + +Lemma Zlt_Zmult_right : (x,y,z:Z)`z>0` -> `x < y` -> `x*z < y*z`. + +Intros; Rewrite (Zs_pred z); Generalize (Zgt0_le_pred H); Intro; +Apply natlike_ind with P:=[z:Z]`x*(Zs z) < y*(Zs z)`; +[ Simpl; Do 2 (Rewrite Zmult_n_1); Assumption +| Unfold Zs; Intros x0 Hx0; Do 6 (Rewrite Zmult_plus_distr_r); + Repeat (Rewrite Zmult_n_1); + Intro; Apply Zlt_Zplus; Assumption +| Assumption ]. +Save. + +Lemma Zlt_Zmult_right2 : (x,y,z:Z)`z>0` -> `x*z < y*z` -> `x < y`. +Intros x y z H; Rewrite (Zs_pred z). +Apply natlike_ind with P:=[z:Z]`x*(Zs z) < y*(Zs z)`->`x < y`. +Simpl; Do 2 Rewrite Zmult_n_1; Auto 1. +Unfold Zs. +Intros x0 Hx0; Repeat (Rewrite Zmult_plus_distr_r). +Repeat Rewrite Zmult_n_1. +Auto with zarith. +Unfold Zpred; Omega. +Save. + +Lemma Zle_Zmult_right : (x,y,z:Z)`z>0` -> `x <= y` -> `x*z <= y*z`. +Intros x y z Hz Hxy. +Elim (Zle_lt_or_eq x y Hxy). +Intros; Apply Zlt_le_weak. +Apply Zlt_Zmult_right; Trivial. +Intros; Apply Zle_refl. +Rewrite H; Trivial. +Save. + +Lemma Zle_Zmult_right2 : (x,y,z:Z)`z>0` -> `x*z <= y*z` -> `x <= y`. +Intros x y z Hz Hxy. +Elim (Zle_lt_or_eq `x*z` `y*z` Hxy). +Intros; Apply Zlt_le_weak. +Apply Zlt_Zmult_right2 with z; Trivial. +Intros; Apply Zle_refl. +Apply Zmult_reg_right with z; Trivial. +Save. + +Lemma Zgt_Zmult_right : (x,y,z:Z)`z>0` -> `x > y` -> `x*z > y*z`. + +Intros; Apply Zlt_gt; Apply Zlt_Zmult_right; +[ Assumption | Apply Zgt_lt ; Assumption ]. +Save. + +Lemma Zlt_Zmult_left : (x,y,z:Z)`z>0` -> `x < y` -> `z*x < z*y`. + +Intros; +Rewrite (Zmult_sym z x); Rewrite (Zmult_sym z y); +Apply Zlt_Zmult_right; Assumption. +Save. + +Lemma Zgt_Zmult_left : (x,y,z:Z)`z>0` -> `x > y` -> `z*x > z*y`. +Intros; +Rewrite (Zmult_sym z x); Rewrite (Zmult_sym z y); +Apply Zgt_Zmult_right; Assumption. +Save. + +Theorem Zcompare_Zmult_right : (x,y,z:Z)` z>0` -> `x ?= y`=`x*z ?= y*z`. + +Intros; Apply Zcompare_egal_dec; +[ Intros; Apply Zlt_Zmult_right; Trivial +| Intro Hxy; Apply [a,b:Z](let (t1,t2)=(Zcompare_EGAL a b) in t2); + Rewrite ((let (t1,t2)=(Zcompare_EGAL x y) in t1) Hxy); Trivial +| Intros; Apply Zgt_Zmult_right; Trivial +]. +Save. + +Theorem Zcompare_Zmult_left : (x,y,z:Z)`z>0` -> `x ?= y`=`z*x ?= z*y`. +Intros; +Rewrite (Zmult_sym z x); +Rewrite (Zmult_sym z y); +Apply Zcompare_Zmult_right; Assumption. +Save. + + +Section diveucl. + +Lemma two_or_two_plus_one : (x:Z) { y:Z | `x = 2*y`}+{ y:Z | `x = 2*y+1`}. +Destruct x. +Left ; Split with ZERO; Reflexivity. + +Destruct p. +Right ; Split with (POS p0); Reflexivity. + +Left ; Split with (POS p0); Reflexivity. + +Right ; Split with ZERO; Reflexivity. + +Destruct p. +Right ; Split with (NEG (add xH p0)). +Rewrite NEG_xI. +Rewrite NEG_add. +Omega. + +Left ; Split with (NEG p0); Reflexivity. + +Right ; Split with `-1`; Reflexivity. +Save. + +(* The biggest power of 2 that is stricly less than a *) +(* Easy to compute : replace all "1" of the binary representation by + "0", except the first "1" (or the first one :-) *) +Fixpoint floor_pos [a : positive] : positive := + Cases a of + | xH => xH + | (xO a') => (xO (floor_pos a')) + | (xI b') => (xO (floor_pos b')) + end. + +Definition floor := [a:positive](POS (floor_pos a)). + +Lemma floor_gt0 : (x:positive) `(floor x) > 0`. +Intro. +Compute. +Trivial. +Save. + +Lemma floor_ok : (a:positive) + `(floor a) <= (POS a) < 2*(floor a)`. +Unfold floor. +Induction a. + +Intro p; Simpl. +Repeat Rewrite POS_xI. +Rewrite (POS_xO (xO (floor_pos p))). +Rewrite (POS_xO (floor_pos p)). +Omega. + +Intro p; Simpl. +Repeat Rewrite POS_xI. +Rewrite (POS_xO (xO (floor_pos p))). +Rewrite (POS_xO (floor_pos p)). +Rewrite (POS_xO p). +Omega. + +Simpl; Omega. +Save. + +Lemma Zdiv_eucl_POS : (b:Z)`b > 0` -> (p:positive) + { qr:Z*Z | let (q,r)=qr in `(POS p)=b*q+r` /\ `0 <= r < b` }. + +Induction p. + +(* p => (xI p) *) +(* Notez l'utilisation des nouveaux patterns Intro *) +Intros p' ((q,r), (Hrec1, Hrec2)). +Elim (Z_lt_ge_dec `2*r+1` b); +[ Exists `(2*q, 2*r+1)`; + Rewrite POS_xI; + Rewrite Hrec1; + Split; + [ Rewrite Zmult_Zplus_distr; + Rewrite Zplus_assoc_l; + Rewrite (Zmult_permute b `2`); + Reflexivity + | Omega ] +| Exists `(2*q+1, 2*r+1-b)`; + Rewrite POS_xI; + Rewrite Hrec1; + Split; + [ Do 2 Rewrite Zmult_Zplus_distr; + Unfold Zminus; + Do 2 Rewrite Zplus_assoc_l; + Rewrite <- (Zmult_permute `2` b); + Generalize `b*q`; Intros; Omega + | Omega ] +]. + +(* p => (xO p) *) +Intros p' ((q,r), (Hrec1, Hrec2)). +Elim (Z_lt_ge_dec `2*r` b); +[ Exists `(2*q,2*r)`; + Rewrite POS_xO; + Rewrite Hrec1; + Split; + [ Rewrite Zmult_Zplus_distr; + Rewrite (Zmult_permute b `2`); + Reflexivity + | Omega ] +| Exists `(2*q+1, 2*r-b)`; + Rewrite POS_xO; + Rewrite Hrec1; + Split; + [ Do 2 Rewrite Zmult_Zplus_distr; + Unfold Zminus; + Rewrite <- (Zmult_permute `2` b); + Generalize `b*q`; Intros; Omega + | Omega ] +]. +(* xH *) +Elim (Z_le_gt_dec `2` b); +[ Exists `(0,1)`; Omega +| Exists `(1,0)`; Omega +]. +Save. + +Theorem Zdiv_eucl : (b:Z)`b > 0` -> (a:Z) + { qr:Z*Z | let (q,r)=qr in `a=b*q+r` /\ `0 <= r < b` }. +Destruct a; + +[ (* a=0 *) Exists `(0,0)`; Omega +| (* a = (POS p) *) Intros; Apply Zdiv_eucl_POS; Auto +| (* a = (NEG p) *) Intros; Elim (Zdiv_eucl_POS H p); + Intros (q,r) (Hp1, Hp2); + Elim (Z_le_gt_dec r `0`); + [ Exists `(-q,0)`; Split; + [ Apply Zopp_intro; Simpl; Rewrite Hp1; + Rewrite Zero_right; + Rewrite <- Zopp_Zmult; + Rewrite Zmult_Zopp_Zopp; + Generalize `b*q`; Intro; Omega + | Omega + ] + | Exists `(-(q+1),b-r)`; Split; + [ Apply Zopp_intro; + Unfold Zminus; Simpl; Rewrite Hp1; + Repeat Rewrite Zopp_Zplus; + Repeat Rewrite <- Zopp_Zmult; + Rewrite Zmult_Zplus_distr; + Rewrite Zmult_Zopp_Zopp; + Rewrite Zplus_assoc_r; + Apply f_equal with f:=[c:Z]`b*q+c`; + Omega + | Omega ] + ] +]. +Save. + +End diveucl. + +(* $Id$ *) + |