src/HOL/Old_Number_Theory/Primes.thy
changeset 57512 cc97b347b301
parent 53077 a1b3784f8129
child 57514 bdc2c6b40bf2
equal deleted inserted replaced
57511:de51a86fc903 57512:cc97b347b301
   106   thus ?thesis unfolding dvd_def by blast
   106   thus ?thesis unfolding dvd_def by blast
   107 qed
   107 qed
   108 
   108 
   109 declare nat_mult_dvd_cancel_disj[presburger]
   109 declare nat_mult_dvd_cancel_disj[presburger]
   110 lemma nat_mult_dvd_cancel_disj'[presburger]: 
   110 lemma nat_mult_dvd_cancel_disj'[presburger]: 
   111   "(m\<Colon>nat)*k dvd n*k \<longleftrightarrow> k = 0 \<or> m dvd n" unfolding mult_commute[of m k] mult_commute[of n k] by presburger 
   111   "(m\<Colon>nat)*k dvd n*k \<longleftrightarrow> k = 0 \<or> m dvd n" unfolding mult.commute[of m k] mult.commute[of n k] by presburger 
   112 
   112 
   113 lemma divides_mul_l: "(a::nat) dvd b ==> (c * a) dvd (c * b)"
   113 lemma divides_mul_l: "(a::nat) dvd b ==> (c * a) dvd (c * b)"
   114   by presburger
   114   by presburger
   115 
   115 
   116 lemma divides_mul_r: "(a::nat) dvd b ==> (a * c) dvd (b * c)" by presburger
   116 lemma divides_mul_r: "(a::nat) dvd b ==> (a * c) dvd (b * c)" by presburger
   118   by (auto simp add: dvd_def)
   118   by (auto simp add: dvd_def)
   119 
   119 
   120 lemma divides_div_not: "(x::nat) = (q * n) + r \<Longrightarrow> 0 < r \<Longrightarrow> r < n ==> ~(n dvd x)"
   120 lemma divides_div_not: "(x::nat) = (q * n) + r \<Longrightarrow> 0 < r \<Longrightarrow> r < n ==> ~(n dvd x)"
   121 proof(auto simp add: dvd_def)
   121 proof(auto simp add: dvd_def)
   122   fix k assume H: "0 < r" "r < n" "q * n + r = n * k"
   122   fix k assume H: "0 < r" "r < n" "q * n + r = n * k"
   123   from H(3) have r: "r = n* (k -q)" by(simp add: diff_mult_distrib2 mult_commute)
   123   from H(3) have r: "r = n* (k -q)" by(simp add: diff_mult_distrib2 mult.commute)
   124   {assume "k - q = 0" with r H(1) have False by simp}
   124   {assume "k - q = 0" with r H(1) have False by simp}
   125   moreover
   125   moreover
   126   {assume "k - q \<noteq> 0" with r have "r \<ge> n" by auto
   126   {assume "k - q \<noteq> 0" with r have "r \<ge> n" by auto
   127     with H(2) have False by simp}
   127     with H(2) have False by simp}
   128   ultimately show False by blast
   128   ultimately show False by blast
   184 
   184 
   185 lemma coprime_bezout: "coprime a b \<longleftrightarrow> (\<exists>x y. a * x - b * y = 1 \<or> b * x - a * y = 1)"
   185 lemma coprime_bezout: "coprime a b \<longleftrightarrow> (\<exists>x y. a * x - b * y = 1 \<or> b * x - a * y = 1)"
   186 using coprime_def gcd_bezout by auto
   186 using coprime_def gcd_bezout by auto
   187 
   187 
   188 lemma coprime_divprod: "d dvd a * b  \<Longrightarrow> coprime d a \<Longrightarrow> d dvd b"
   188 lemma coprime_divprod: "d dvd a * b  \<Longrightarrow> coprime d a \<Longrightarrow> d dvd b"
   189   using relprime_dvd_mult_iff[of d a b] by (auto simp add: coprime_def mult_commute)
   189   using relprime_dvd_mult_iff[of d a b] by (auto simp add: coprime_def mult.commute)
   190 
   190 
   191 lemma coprime_1[simp]: "coprime a 1" by (simp add: coprime_def)
   191 lemma coprime_1[simp]: "coprime a 1" by (simp add: coprime_def)
   192 lemma coprime_1'[simp]: "coprime 1 a" by (simp add: coprime_def)
   192 lemma coprime_1'[simp]: "coprime 1 a" by (simp add: coprime_def)
   193 lemma coprime_Suc0[simp]: "coprime a (Suc 0)" by (simp add: coprime_def)
   193 lemma coprime_Suc0[simp]: "coprime a (Suc 0)" by (simp add: coprime_def)
   194 lemma coprime_Suc0'[simp]: "coprime (Suc 0) a" by (simp add: coprime_def)
   194 lemma coprime_Suc0'[simp]: "coprime (Suc 0) a" by (simp add: coprime_def)
   203   {assume az: "a\<noteq> 0" 
   203   {assume az: "a\<noteq> 0" 
   204     from z have z': "?g > 0" by simp
   204     from z have z': "?g > 0" by simp
   205     from bezout_gcd_strong[OF az, of b] 
   205     from bezout_gcd_strong[OF az, of b] 
   206     obtain x y where xy: "a*x = b*y + ?g" by blast
   206     obtain x y where xy: "a*x = b*y + ?g" by blast
   207     from xy a b have "?g * a'*x = ?g * (b'*y + 1)" by (simp add: algebra_simps)
   207     from xy a b have "?g * a'*x = ?g * (b'*y + 1)" by (simp add: algebra_simps)
   208     hence "?g * (a'*x) = ?g * (b'*y + 1)" by (simp add: mult_assoc)
   208     hence "?g * (a'*x) = ?g * (b'*y + 1)" by (simp add: mult.assoc)
   209     hence "a'*x = (b'*y + 1)"
   209     hence "a'*x = (b'*y + 1)"
   210       by (simp only: nat_mult_eq_cancel1[OF z']) 
   210       by (simp only: nat_mult_eq_cancel1[OF z']) 
   211     hence "a'*x - b'*y = 1" by simp
   211     hence "a'*x - b'*y = 1" by simp
   212     with coprime_bezout[of a' b'] have ?thesis by auto}
   212     with coprime_bezout[of a' b'] have ?thesis by auto}
   213   ultimately show ?thesis by blast
   213   ultimately show ?thesis by blast
   294     obtain x y where "a'^n * x - b'^n * y = 1 \<or> b'^n * x - a'^n * y = 1"  by blast
   294     obtain x y where "a'^n * x - b'^n * y = 1 \<or> b'^n * x - a'^n * y = 1"  by blast
   295     hence "?g^n * (a'^n * x - b'^n * y) = ?g^n \<or> ?g^n*(b'^n * x - a'^n * y) = ?g^n"
   295     hence "?g^n * (a'^n * x - b'^n * y) = ?g^n \<or> ?g^n*(b'^n * x - a'^n * y) = ?g^n"
   296       using z by auto 
   296       using z by auto 
   297     then have "a^n * x - b^n * y = ?g^n \<or> b^n * x - a^n * y = ?g^n"
   297     then have "a^n * x - b^n * y = ?g^n \<or> b^n * x - a^n * y = ?g^n"
   298       using z ab'' by (simp only: power_mult_distrib[symmetric] 
   298       using z ab'' by (simp only: power_mult_distrib[symmetric] 
   299         diff_mult_distrib2 mult_assoc[symmetric])
   299         diff_mult_distrib2 mult.assoc[symmetric])
   300     hence  ?thesis by blast }
   300     hence  ?thesis by blast }
   301   ultimately show ?thesis by blast
   301   ultimately show ?thesis by blast
   302 qed
   302 qed
   303 
   303 
   304 lemma gcd_exp: "gcd (a^n) (b^n) = gcd a b^n"
   304 lemma gcd_exp: "gcd (a^n) (b^n) = gcd a b^n"
   332     obtain a' b' where ab': "a = a' * ?g" "b = b' * ?g" "coprime a' b'" by blast
   332     obtain a' b' where ab': "a = a' * ?g" "b = b' * ?g" "coprime a' b'" by blast
   333     from gcd_dvd2[of a b] have thb: "?g dvd b" .
   333     from gcd_dvd2[of a b] have thb: "?g dvd b" .
   334     from ab'(1) have "a' dvd a"  unfolding dvd_def by blast  
   334     from ab'(1) have "a' dvd a"  unfolding dvd_def by blast  
   335     with dc have th0: "a' dvd b*c" using dvd_trans[of a' a "b*c"] by simp
   335     with dc have th0: "a' dvd b*c" using dvd_trans[of a' a "b*c"] by simp
   336     from dc ab'(1,2) have "a'*?g dvd (b'*?g) *c" by auto
   336     from dc ab'(1,2) have "a'*?g dvd (b'*?g) *c" by auto
   337     hence "?g*a' dvd ?g * (b' * c)" by (simp add: mult_assoc)
   337     hence "?g*a' dvd ?g * (b' * c)" by (simp add: mult.assoc)
   338     with z have th_1: "a' dvd b'*c" by simp
   338     with z have th_1: "a' dvd b'*c" by simp
   339     from coprime_divprod[OF th_1 ab'(3)] have thc: "a' dvd c" . 
   339     from coprime_divprod[OF th_1 ab'(3)] have thc: "a' dvd c" . 
   340     from ab' have "a = ?g*a'" by algebra
   340     from ab' have "a = ?g*a'" by algebra
   341     with thb thc have ?thesis by blast }
   341     with thb thc have ?thesis by blast }
   342   ultimately show ?thesis by blast
   342   ultimately show ?thesis by blast
   353   {assume z: "?g \<noteq> 0"
   353   {assume z: "?g \<noteq> 0"
   354     hence zn: "?g ^ n \<noteq> 0" using n by simp
   354     hence zn: "?g ^ n \<noteq> 0" using n by simp
   355     from gcd_coprime_exists[OF z] 
   355     from gcd_coprime_exists[OF z] 
   356     obtain a' b' where ab': "a = a' * ?g" "b = b' * ?g" "coprime a' b'" by blast
   356     obtain a' b' where ab': "a = a' * ?g" "b = b' * ?g" "coprime a' b'" by blast
   357     from ab have "(a' * ?g) ^ n dvd (b' * ?g)^n" by (simp add: ab'(1,2)[symmetric])
   357     from ab have "(a' * ?g) ^ n dvd (b' * ?g)^n" by (simp add: ab'(1,2)[symmetric])
   358     hence "?g^n*a'^n dvd ?g^n *b'^n" by (simp only: power_mult_distrib mult_commute)
   358     hence "?g^n*a'^n dvd ?g^n *b'^n" by (simp only: power_mult_distrib mult.commute)
   359     with zn z n have th0:"a'^n dvd b'^n" by (auto simp add: nat_power_eq_0_iff)
   359     with zn z n have th0:"a'^n dvd b'^n" by (auto simp add: nat_power_eq_0_iff)
   360     have "a' dvd a'^n" by (simp add: m)
   360     have "a' dvd a'^n" by (simp add: m)
   361     with th0 have "a' dvd b'^n" using dvd_trans[of a' "a'^n" "b'^n"] by simp
   361     with th0 have "a' dvd b'^n" using dvd_trans[of a' "a'^n" "b'^n"] by simp
   362     hence th1: "a' dvd b'^m * b'" by (simp add: m mult_commute)
   362     hence th1: "a' dvd b'^m * b'" by (simp add: m mult.commute)
   363     from coprime_divprod[OF th1 coprime_exp[OF ab'(3), of m]]
   363     from coprime_divprod[OF th1 coprime_exp[OF ab'(3), of m]]
   364     have "a' dvd b'" .
   364     have "a' dvd b'" .
   365     hence "a'*?g dvd b'*?g" by simp
   365     hence "a'*?g dvd b'*?g" by simp
   366     with ab'(1,2)  have ?thesis by simp }
   366     with ab'(1,2)  have ?thesis by simp }
   367   ultimately show ?thesis by blast
   367   ultimately show ?thesis by blast
   370 lemma divides_mul: assumes mr: "m dvd r" and nr: "n dvd r" and mn:"coprime m n" 
   370 lemma divides_mul: assumes mr: "m dvd r" and nr: "n dvd r" and mn:"coprime m n" 
   371   shows "m * n dvd r"
   371   shows "m * n dvd r"
   372 proof-
   372 proof-
   373   from mr nr obtain m' n' where m': "r = m*m'" and n': "r = n*n'"
   373   from mr nr obtain m' n' where m': "r = m*m'" and n': "r = n*n'"
   374     unfolding dvd_def by blast
   374     unfolding dvd_def by blast
   375   from mr n' have "m dvd n'*n" by (simp add: mult_commute)
   375   from mr n' have "m dvd n'*n" by (simp add: mult.commute)
   376   hence "m dvd n'" using relprime_dvd_mult_iff[OF mn[unfolded coprime_def]] by simp
   376   hence "m dvd n'" using relprime_dvd_mult_iff[OF mn[unfolded coprime_def]] by simp
   377   then obtain k where k: "n' = m*k" unfolding dvd_def by blast
   377   then obtain k where k: "n' = m*k" unfolding dvd_def by blast
   378   from n' k show ?thesis unfolding dvd_def by auto
   378   from n' k show ?thesis unfolding dvd_def by auto
   379 qed
   379 qed
   380 
   380 
   607     from divides_exp2[OF n pab] have pab': "p dvd a*b" .
   607     from divides_exp2[OF n pab] have pab': "p dvd a*b" .
   608     from prime_divprod[OF p pab'] 
   608     from prime_divprod[OF p pab'] 
   609     have "p dvd a \<or> p dvd b" .
   609     have "p dvd a \<or> p dvd b" .
   610     moreover
   610     moreover
   611     {assume pa: "p dvd a"
   611     {assume pa: "p dvd a"
   612       have pnba: "p^n dvd b*a" using pab by (simp add: mult_commute)
   612       have pnba: "p^n dvd b*a" using pab by (simp add: mult.commute)
   613       from coprime_prime[OF ab, of p] p pa have "\<not> p dvd b" by blast
   613       from coprime_prime[OF ab, of p] p pa have "\<not> p dvd b" by blast
   614       with prime_coprime[OF p, of b] b 
   614       with prime_coprime[OF p, of b] b 
   615       have cpb: "coprime b p" using coprime_commute by blast 
   615       have cpb: "coprime b p" using coprime_commute by blast 
   616       from coprime_exp[OF cpb] have pnb: "coprime (p^n) b" 
   616       from coprime_exp[OF cpb] have pnb: "coprime (p^n) b" 
   617         by (simp add: coprime_commute)
   617         by (simp add: coprime_commute)
   618       from coprime_divprod[OF pnba pnb] have ?thesis by blast }
   618       from coprime_divprod[OF pnba pnb] have ?thesis by blast }
   619     moreover
   619     moreover
   620     {assume pb: "p dvd b"
   620     {assume pb: "p dvd b"
   621       have pnba: "p^n dvd b*a" using pab by (simp add: mult_commute)
   621       have pnba: "p^n dvd b*a" using pab by (simp add: mult.commute)
   622       from coprime_prime[OF ab, of p] p pb have "\<not> p dvd a" by blast
   622       from coprime_prime[OF ab, of p] p pb have "\<not> p dvd a" by blast
   623       with prime_coprime[OF p, of a] a
   623       with prime_coprime[OF p, of a] a
   624       have cpb: "coprime a p" using coprime_commute by blast 
   624       have cpb: "coprime a p" using coprime_commute by blast 
   625       from coprime_exp[OF cpb] have pnb: "coprime (p^n) a" 
   625       from coprime_exp[OF cpb] have pnb: "coprime (p^n) a" 
   626         by (simp add: coprime_commute)
   626         by (simp add: coprime_commute)
   630 qed
   630 qed
   631 
   631 
   632 lemma nat_mult_eq_one: "(n::nat) * m = 1 \<longleftrightarrow> n = 1 \<and> m = 1" (is "?lhs \<longleftrightarrow> ?rhs")
   632 lemma nat_mult_eq_one: "(n::nat) * m = 1 \<longleftrightarrow> n = 1 \<and> m = 1" (is "?lhs \<longleftrightarrow> ?rhs")
   633 proof
   633 proof
   634   assume H: "?lhs"
   634   assume H: "?lhs"
   635   hence "n dvd 1" "m dvd 1" unfolding dvd_def by (auto simp add: mult_commute)
   635   hence "n dvd 1" "m dvd 1" unfolding dvd_def by (auto simp add: mult.commute)
   636   thus ?rhs by auto
   636   thus ?rhs by auto
   637 next
   637 next
   638   assume ?rhs then show ?lhs by auto
   638   assume ?rhs then show ?lhs by auto
   639 qed
   639 qed
   640   
   640   
   703       moreover {assume "l = c" with l c  have "p = 1" by simp with p have False by simp}
   703       moreover {assume "l = c" with l c  have "p = 1" by simp with p have False by simp}
   704       ultimately have lc: "l < c" by arith
   704       ultimately have lc: "l < c" by arith
   705       from coprime_lmul2 [OF H(2)[unfolded k coprime_commute[of "p^n*k" a]]]
   705       from coprime_lmul2 [OF H(2)[unfolded k coprime_commute[of "p^n*k" a]]]
   706       have kb: "coprime k a" by (simp add: coprime_commute) 
   706       have kb: "coprime k a" by (simp add: coprime_commute) 
   707       from H(3) l k pn0 n have kbln: "k * a = l ^ n" 
   707       from H(3) l k pn0 n have kbln: "k * a = l ^ n" 
   708         by (simp add: power_mult_distrib mult_commute)
   708         by (simp add: power_mult_distrib mult.commute)
   709       from H(1)[rule_format, OF lc kb kbln]
   709       from H(1)[rule_format, OF lc kb kbln]
   710       obtain r s where rs: "k = r ^n" "a = s^n" by blast
   710       obtain r s where rs: "k = r ^n" "a = s^n" by blast
   711       from k rs(1) have "b = (p*r)^n" by (simp add: power_mult_distrib)
   711       from k rs(1) have "b = (p*r)^n" by (simp add: power_mult_distrib)
   712       with rs(2) have ?ths by blast }
   712       with rs(2) have ?ths by blast }
   713     ultimately have ?ths using pnab by blast}
   713     ultimately have ?ths using pnab by blast}
   770     with d have "x = p^Suc i" by simp 
   770     with d have "x = p^Suc i" by simp 
   771     with ij(2) have ?case by blast}
   771     with ij(2) have ?case by blast}
   772   moreover 
   772   moreover 
   773   {assume px: "p dvd y"
   773   {assume px: "p dvd y"
   774     then obtain d where d: "y = p*d" unfolding dvd_def by blast
   774     then obtain d where d: "y = p*d" unfolding dvd_def by blast
   775     from Suc.prems d  have "p*d*x = p^Suc k" by (simp add: mult_commute)
   775     from Suc.prems d  have "p*d*x = p^Suc k" by (simp add: mult.commute)
   776     hence th: "d*x = p^k" using p0 by simp
   776     hence th: "d*x = p^k" using p0 by simp
   777     from Suc.hyps[OF th] obtain i j where ij: "d = p^i" "x = p^j" by blast
   777     from Suc.hyps[OF th] obtain i j where ij: "d = p^i" "x = p^j" by blast
   778     with d have "y = p^Suc i" by simp 
   778     with d have "y = p^Suc i" by simp 
   779     with ij(2) have ?case by blast}
   779     with ij(2) have ?case by blast}
   780   ultimately show ?case  using pxyc by blast
   780   ultimately show ?case  using pxyc by blast
   798 
   798 
   799 lemma divides_primepow: assumes p: "prime p" 
   799 lemma divides_primepow: assumes p: "prime p" 
   800   shows "d dvd p^k \<longleftrightarrow> (\<exists> i. i \<le> k \<and> d = p ^i)"
   800   shows "d dvd p^k \<longleftrightarrow> (\<exists> i. i \<le> k \<and> d = p ^i)"
   801 proof
   801 proof
   802   assume H: "d dvd p^k" then obtain e where e: "d*e = p^k" 
   802   assume H: "d dvd p^k" then obtain e where e: "d*e = p^k" 
   803     unfolding dvd_def  apply (auto simp add: mult_commute) by blast
   803     unfolding dvd_def  apply (auto simp add: mult.commute) by blast
   804   from prime_power_mult[OF p e] obtain i j where ij: "d = p^i" "e=p^j" by blast
   804   from prime_power_mult[OF p e] obtain i j where ij: "d = p^i" "e=p^j" by blast
   805   from prime_ge_2[OF p] have p1: "p > 1" by arith
   805   from prime_ge_2[OF p] have p1: "p > 1" by arith
   806   from e ij have "p^(i + j) = p^k" by (simp add: power_add)
   806   from e ij have "p^(i + j) = p^k" by (simp add: power_add)
   807   hence "i + j = k" using power_inject_exp[of p "i+j" k, OF p1] by simp 
   807   hence "i + j = k" using power_inject_exp[of p "i+j" k, OF p1] by simp 
   808   hence "i \<le> k" by arith
   808   hence "i \<le> k" by arith