X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=blobdiff_plain;f=helm%2Fsoftware%2Fmatita%2Flibrary%2Fnat%2Fgcd.ma;h=dcdbc7b7ad302405a445bef9cc1bcf9bdb1f4235;hb=68dbcd02022874a025a9444aa1125b0458816fbb;hp=0568536dcb0f6d4cbaef1b94c3feb53d79b17824;hpb=06a19bec47845ecffe3bf9d9a95d3d4dadf76861;p=helm.git diff --git a/helm/software/matita/library/nat/gcd.ma b/helm/software/matita/library/nat/gcd.ma index 0568536dc..dcdbc7b7a 100644 --- a/helm/software/matita/library/nat/gcd.ma +++ b/helm/software/matita/library/nat/gcd.ma @@ -12,9 +12,8 @@ (* *) (**************************************************************************) -set "baseuri" "cic:/matita/nat/gcd". - include "nat/primes.ma". +include "nat/lt_arith.ma". let rec gcd_aux p m n: nat \def match divides_b n m with @@ -56,7 +55,7 @@ qed. theorem divides_mod_to_divides: \forall p,m,n:nat. O < n \to p \divides (m \mod n) \to p \divides n \to p \divides m. intros.elim H1.elim H2. -apply (witness p m ((n1*(m / n))+n2)). +apply (witness p m ((n2*(m / n))+n1)). rewrite > distr_times_plus. rewrite < H3. rewrite < assoc_times. @@ -100,7 +99,6 @@ qed. theorem divides_gcd_nm: \forall n,m. gcd n m \divides m \land gcd n m \divides n. intros. -(*CSC: simplify simplifies too much because of a redex in gcd *) change with (match leb n m with [ true \Rightarrow @@ -163,42 +161,109 @@ intros. exact (proj1 ? ? (divides_gcd_nm n m)). qed. + +theorem divides_times_gcd_aux: \forall p,m,n,d,c. +O \lt c \to O < n \to n \le m \to n \le p \to +d \divides (c*m) \to d \divides (c*n) \to d \divides c*gcd_aux p m n. +intro. +elim p +[ absurd (O < n) + [ assumption + | apply le_to_not_lt. + assumption + ] +| simplify. + cut (n1 \divides m \lor n1 \ndivides m) + [ elim Hcut + [ rewrite > divides_to_divides_b_true + [ simplify. + assumption + | assumption + | assumption + ] + | rewrite > not_divides_to_divides_b_false + [ simplify. + apply H + [ assumption + | cut (O \lt m \mod n1 \lor O = m \mod n1) + [ elim Hcut1 + [ assumption + | absurd (n1 \divides m) + [ apply mod_O_to_divides + [ assumption + | apply sym_eq. + assumption + ] + | assumption + ] + ] + | apply le_to_or_lt_eq. + apply le_O_n + ] + | apply lt_to_le. + apply lt_mod_m_m. + assumption + | apply le_S_S_to_le. + apply (trans_le ? n1) + [ change with (m \mod n1 < n1). + apply lt_mod_m_m. + assumption + | assumption + ] + | assumption + | rewrite < times_mod + [ rewrite < (sym_times c m). + rewrite < (sym_times c n1). + apply divides_mod + [ rewrite > (S_pred c) + [ rewrite > (S_pred n1) + [ apply (lt_O_times_S_S) + | assumption + ] + | assumption + ] + | assumption + | assumption + ] + | assumption + | assumption + ] + ] + | assumption + | assumption + ] + ] + | apply (decidable_divides n1 m). + assumption + ] +] +qed. + +(*a particular case of the previous theorem (setting c=1)*) theorem divides_gcd_aux: \forall p,m,n,d. O < n \to n \le m \to n \le p \to d \divides m \to d \divides n \to d \divides gcd_aux p m n. -intro.elim p. -absurd (O < n).assumption.apply le_to_not_lt.assumption. -simplify. -cut (n1 \divides m \lor n1 \ndivides m). -elim Hcut. -rewrite > divides_to_divides_b_true. -simplify.assumption. -assumption.assumption. -rewrite > not_divides_to_divides_b_false. -simplify. -apply H. -cut (O \lt m \mod n1 \lor O = m \mod n1). -elim Hcut1.assumption. -absurd (n1 \divides m).apply mod_O_to_divides. -assumption.apply sym_eq.assumption.assumption. -apply le_to_or_lt_eq.apply le_O_n. -apply lt_to_le. -apply lt_mod_m_m.assumption. -apply le_S_S_to_le. -apply (trans_le ? n1). -change with (m \mod n1 < n1). -apply lt_mod_m_m.assumption.assumption. -assumption. -apply divides_mod.assumption.assumption.assumption. -assumption.assumption. -apply (decidable_divides n1 m).assumption. +intros. +rewrite > (times_n_SO (gcd_aux p m n)). +rewrite < (sym_times (S O)). +apply (divides_times_gcd_aux) +[ apply (lt_O_S O) +| assumption +| assumption +| assumption +| rewrite > (sym_times (S O)). + rewrite < (times_n_SO m). + assumption +| rewrite > (sym_times (S O)). + rewrite < (times_n_SO n). + assumption +] qed. -theorem divides_d_gcd: \forall m,n,d. -d \divides m \to d \divides n \to d \divides gcd n m. +theorem divides_d_times_gcd: \forall m,n,d,c. +O \lt c \to d \divides (c*m) \to d \divides (c*n) \to d \divides c*gcd n m. intros. -(*CSC: here simplify simplifies too much because of a redex in gcd *) change with -(d \divides +(d \divides c * match leb n m with [ true \Rightarrow match n with @@ -208,20 +273,63 @@ match leb n m with match m with [ O \Rightarrow n | (S p) \Rightarrow gcd_aux (S p) n (S p) ]]). -apply (leb_elim n m). -apply (nat_case1 n).simplify.intros.assumption. -intros. -change with (d \divides gcd_aux (S m1) m (S m1)). -apply divides_gcd_aux. -unfold lt.apply le_S_S.apply le_O_n.assumption.apply le_n.assumption. -rewrite < H2.assumption. -apply (nat_case1 m).simplify.intros.assumption. +apply (leb_elim n m) +[ apply (nat_case1 n) + [ simplify. + intros. + assumption + | intros. + change with (d \divides c*gcd_aux (S m1) m (S m1)). + apply divides_times_gcd_aux + [ assumption + | unfold lt. + apply le_S_S. + apply le_O_n + | assumption + | apply (le_n (S m1)) + | assumption + | rewrite < H3. + assumption + ] + ] +| apply (nat_case1 m) + [ simplify. + intros. + assumption + | intros. + change with (d \divides c * gcd_aux (S m1) n (S m1)). + apply divides_times_gcd_aux + [ unfold lt. + change with (O \lt c). + assumption + | apply lt_O_S + | apply lt_to_le. + apply not_le_to_lt. + assumption + | apply (le_n (S m1)). + | assumption + | rewrite < H3. + assumption + ] + ] +] +qed. + +(*a particular case of the previous theorem (setting c=1)*) +theorem divides_d_gcd: \forall m,n,d. +d \divides m \to d \divides n \to d \divides gcd n m. intros. -change with (d \divides gcd_aux (S m1) n (S m1)). -apply divides_gcd_aux. -unfold lt.apply le_S_S.apply le_O_n. -apply lt_to_le.apply not_le_to_lt.assumption.apply le_n.assumption. -rewrite < H2.assumption. +rewrite > (times_n_SO (gcd n m)). +rewrite < (sym_times (S O)). +apply (divides_d_times_gcd) +[ apply (lt_O_S O) +| rewrite > (sym_times (S O)). + rewrite < (times_n_SO m). + assumption +| rewrite > (sym_times (S O)). + rewrite < (times_n_SO n). + assumption +] qed. theorem eq_minus_gcd_aux: \forall p,m,n.O < n \to n \le m \to n \le p \to @@ -483,7 +591,6 @@ intro.apply (nat_case n) qed. theorem symmetric_gcd: symmetric nat gcd. -(*CSC: bug here: unfold symmetric does not work *) change with (\forall n,m:nat. gcd n m = gcd m n). intros. @@ -545,9 +652,9 @@ elim H2. generalize in match H1. rewrite > H3. intro. -cut (O < n2) - [elim (gcd_times_SO_to_gcd_SO n n n2 ? ? H4) - [cut (gcd n (n*n2) = n) +cut (O < n1) + [elim (gcd_times_SO_to_gcd_SO n n n1 ? ? H4) + [cut (gcd n (n*n1) = n) [apply (lt_to_not_eq (S O) n) [assumption|rewrite < H4.assumption] |apply gcd_n_times_nm.assumption @@ -555,7 +662,7 @@ cut (O < n2) |apply (trans_lt ? (S O))[apply le_n|assumption] |assumption ] - |elim (le_to_or_lt_eq O n2 (le_O_n n2)); + |elim (le_to_or_lt_eq O n1 (le_O_n n1)); [assumption |apply False_ind. apply (le_to_not_lt n (S O)) @@ -563,7 +670,7 @@ cut (O < n2) apply divides_to_le [rewrite > H4.apply lt_O_S |apply divides_d_gcd - [apply (witness ? ? n2).reflexivity + [apply (witness ? ? n1).reflexivity |apply divides_n_n ] ] @@ -638,6 +745,7 @@ apply gcd_O_to_eq_O.apply sym_eq.assumption. apply le_to_or_lt_eq.apply le_O_n. qed. +(* primes and divides *) theorem divides_times_to_divides: \forall n,p,q:nat.prime n \to n \divides p*q \to n \divides p \lor n \divides q. intros. @@ -647,18 +755,14 @@ cut (n \divides p \lor n \ndivides p) |right. cut (\exists a,b. a*n - b*p = (S O) \lor b*p - a*n = (S O)) [elim Hcut1.elim H3.elim H4 - [(* first case *) - rewrite > (times_n_SO q).rewrite < H5. + [rewrite > (times_n_SO q).rewrite < H5. rewrite > distr_times_minus. + elim H1. + autobatch by witness; + (* rewrite > (sym_times q (a1*p)). rewrite > (assoc_times a1). - elim H1. - (* - rewrite > H6. - applyS (witness n (n*(q*a-a1*n2)) (q*a-a1*n2)) - reflexivity. *); - applyS (witness n ? ? (refl_eq ? ?)) (* timeout=50 *). - (* + applyS (witness n ? ? (refl_eq ? ?)). rewrite < (sym_times n).rewrite < assoc_times. rewrite > (sym_times q).rewrite > assoc_times. rewrite < (assoc_times a1).rewrite < (sym_times n). @@ -669,14 +773,18 @@ cut (n \divides p \lor n \ndivides p) |(* second case *) rewrite > (times_n_SO q).rewrite < H5. rewrite > distr_times_minus. + elim H1. autobatch by witness; + (* rewrite > (sym_times q (a1*p)). rewrite > (assoc_times a1). - elim H1.rewrite > H6. + rewrite > H6. + applyS (witness n ? ? (refl_eq ? ?)). rewrite < sym_times.rewrite > assoc_times. rewrite < (assoc_times q). rewrite < (sym_times n). rewrite < distr_times_minus. - apply (witness ? ? (n2*a1-q*a)).reflexivity + apply (witness ? ? (n1*a1-q*a)).reflexivity + *) ](* end second case *) |rewrite < (prime_to_gcd_SO n p) [apply eq_minus_gcd|assumption|assumption @@ -691,6 +799,30 @@ cut (n \divides p \lor n \ndivides p) ] qed. +theorem divides_exp_to_divides: +\forall p,n,m:nat. prime p \to +p \divides n \sup m \to p \divides n. +intros 3.elim m.simplify in H1. +apply (transitive_divides p (S O)).assumption. +apply divides_SO_n. +cut (p \divides n \lor p \divides n \sup n1). +elim Hcut.assumption. +apply H.assumption.assumption. +apply divides_times_to_divides.assumption. +exact H2. +qed. + +theorem divides_exp_to_eq: +\forall p,q,m:nat. prime p \to prime q \to +p \divides q \sup m \to p = q. +intros. +unfold prime in H1. +elim H1.apply H4. +apply (divides_exp_to_divides p q m). +assumption.assumption. +unfold prime in H.elim H.assumption. +qed. + theorem eq_gcd_times_SO: \forall m,n,p:nat. O < n \to O < p \to gcd m n = (S O) \to gcd m p = (S O) \to gcd m (n*p) = (S O). intros. @@ -746,19 +878,15 @@ cut (n \divides p \lor n \ndivides p) |cut (\exists a,b. a*n - b*m = (S O) \lor b*m - a*n = (S O)) [elim Hcut1.elim H4.elim H5 [(* first case *) + elim H2. rewrite > (times_n_SO p).rewrite < H6. rewrite > distr_times_minus. - rewrite > (sym_times p (a1*m)). - rewrite > (assoc_times a1). + autobatch by witness, divides_minus. + |(* second case *) elim H2. - applyS (witness n ? ? (refl_eq ? ?)) (* timeout=50 *). - |(* second case *) rewrite > (times_n_SO p).rewrite < H6. rewrite > distr_times_minus. - rewrite > (sym_times p (a1*m)). - rewrite > (assoc_times a1). - elim H2. - applyS (witness n ? ? (refl_eq ? ?)). + autobatch by witness, divides_minus. ](* end second case *) |rewrite < H1.apply eq_minus_gcd. ] @@ -766,4 +894,41 @@ cut (n \divides p \lor n \ndivides p) |apply (decidable_divides n p). assumption. ] +qed. + +(* +theorem divides_to_divides_times1: \forall p,q,n. prime p \to prime q \to p \neq q \to +divides p n \to divides q n \to divides (p*q) n. +intros.elim H3. +rewrite > H5 in H4. +elim (divides_times_to_divides ? ? ? H1 H4) + [elim H.apply False_ind. + apply H2.apply sym_eq.apply H8 + [assumption + |apply prime_to_lt_SO.assumption + ] + |elim H6. + apply (witness ? ? n1). + rewrite > assoc_times. + rewrite < H7.assumption + ] +qed. +*) + +theorem divides_to_divides_times: \forall p,q,n. prime p \to p \ndivides q \to +divides p n \to divides q n \to divides (p*q) n. +intros.elim H3. +rewrite > H4 in H2. +elim (divides_times_to_divides ? ? ? H H2) + [apply False_ind.apply H1.assumption + |elim H5. + autobatch by transitive_divides, H5, reflexive_divides,divides_times. + (* + apply (witness ? ? n2). + rewrite > sym_times in ⊢ (? ? ? (? % ?)). + rewrite > assoc_times. + autobatch. + (*rewrite < H6.assumption*) + *) + ] qed. \ No newline at end of file