src/HOL/NumberTheory/IntPrimes.thy
changeset 23839 d9fa0f457d9a
parent 21404 eb85850d3eb7
child 24181 102ebceaa495
equal deleted inserted replaced
23838:d2a8f1544bc9 23839:d9fa0f457d9a
   164   done
   164   done
   165 
   165 
   166 lemma zprime_imp_zrelprime:
   166 lemma zprime_imp_zrelprime:
   167     "zprime p ==> \<not> p dvd n ==> zgcd (n, p) = 1"
   167     "zprime p ==> \<not> p dvd n ==> zgcd (n, p) = 1"
   168   apply (auto simp add: zprime_def)
   168   apply (auto simp add: zprime_def)
   169   apply (drule_tac x = "zgcd(n, p)" in allE)
   169   apply (metis zgcd_commute zgcd_geq_zero zgcd_zdvd1 zgcd_zdvd2)
   170   apply (auto simp add: zgcd_zdvd2 [of n p] zgcd_geq_zero)
       
   171   apply (insert zgcd_zdvd1 [of n p], auto)
       
   172   done
   170   done
   173 
   171 
   174 lemma zless_zprime_imp_zrelprime:
   172 lemma zless_zprime_imp_zrelprime:
   175     "zprime p ==> 0 < n ==> n < p ==> zgcd (n, p) = 1"
   173     "zprime p ==> 0 < n ==> n < p ==> zgcd (n, p) = 1"
   176   apply (erule zprime_imp_zrelprime)
   174   apply (erule zprime_imp_zrelprime)
   177   apply (erule zdvd_not_zless, assumption)
   175   apply (erule zdvd_not_zless, assumption)
   178   done
   176   done
   179 
   177 
   180 lemma zprime_zdvd_zmult:
   178 lemma zprime_zdvd_zmult:
   181     "0 \<le> (m::int) ==> zprime p ==> p dvd m * n ==> p dvd m \<or> p dvd n"
   179     "0 \<le> (m::int) ==> zprime p ==> p dvd m * n ==> p dvd m \<or> p dvd n"
   182   apply safe
   180   by (metis igcd_dvd1 igcd_dvd2 igcd_pos zprime_def zrelprime_dvd_mult)
   183   apply (rule zrelprime_zdvd_zmult)
       
   184    apply (rule zprime_imp_zrelprime, auto)
       
   185   done
       
   186 
   181 
   187 lemma zgcd_zadd_zmult [simp]: "zgcd (m + n * k, n) = zgcd (m, n)"
   182 lemma zgcd_zadd_zmult [simp]: "zgcd (m + n * k, n) = zgcd (m, n)"
   188   apply (rule zgcd_eq [THEN trans])
   183   apply (rule zgcd_eq [THEN trans])
   189   apply (simp add: zmod_zadd1_eq)
   184   apply (simp add: zmod_zadd1_eq)
   190   apply (rule zgcd_eq [symmetric])
   185   apply (rule zgcd_eq [symmetric])
   199     "zgcd (k, n) = 1 ==> zgcd (k * m, n) dvd zgcd (m, n)"
   194     "zgcd (k, n) = 1 ==> zgcd (k * m, n) dvd zgcd (m, n)"
   200   apply (simp add: zgcd_greatest_iff)
   195   apply (simp add: zgcd_greatest_iff)
   201   apply (rule_tac n = k in zrelprime_zdvd_zmult)
   196   apply (rule_tac n = k in zrelprime_zdvd_zmult)
   202    prefer 2
   197    prefer 2
   203    apply (simp add: zmult_commute)
   198    apply (simp add: zmult_commute)
   204   apply (subgoal_tac "zgcd (k, zgcd (k * m, n)) = zgcd (k * m, zgcd (k, n))")
   199   apply (metis zgcd_1 zgcd_commute zgcd_left_commute)
   205    apply simp
       
   206   apply (simp (no_asm) add: zgcd_ac)
       
   207   done
   200   done
   208 
   201 
   209 lemma zgcd_zmult_cancel: "zgcd (k, n) = 1 ==> zgcd (k * m, n) = zgcd (m, n)"
   202 lemma zgcd_zmult_cancel: "zgcd (k, n) = 1 ==> zgcd (k * m, n) = zgcd (m, n)"
   210   by (simp add: zgcd_def nat_abs_mult_distrib gcd_mult_cancel)
   203   by (simp add: zgcd_def nat_abs_mult_distrib gcd_mult_cancel)
   211 
   204 
   212 lemma zgcd_zgcd_zmult:
   205 lemma zgcd_zgcd_zmult:
   213     "zgcd (k, m) = 1 ==> zgcd (n, m) = 1 ==> zgcd (k * n, m) = 1"
   206     "zgcd (k, m) = 1 ==> zgcd (n, m) = 1 ==> zgcd (k * n, m) = 1"
   214   by (simp add: zgcd_zmult_cancel)
   207   by (simp add: zgcd_zmult_cancel)
   215 
   208 
   216 lemma zdvd_iff_zgcd: "0 < m ==> (m dvd n) = (zgcd (n, m) = m)"
   209 lemma zdvd_iff_zgcd: "0 < m ==> (m dvd n) = (zgcd (n, m) = m)"
   217   apply safe
   210   by (metis abs_of_pos zdvd_mult_div_cancel zgcd_0 zgcd_commute zgcd_geq_zero zgcd_zdvd2 zgcd_zmult_eq_self)
   218    apply (rule_tac [2] n = "zgcd (n, m)" in zdvd_trans)
   211 
   219     apply (rule_tac [3] zgcd_zdvd1, simp_all)
       
   220   apply (unfold dvd_def, auto)
       
   221   done
       
   222 
   212 
   223 
   213 
   224 subsection {* Congruences *}
   214 subsection {* Congruences *}
   225 
   215 
   226 lemma zcong_1 [simp]: "[a = b] (mod 1)"
   216 lemma zcong_1 [simp]: "[a = b] (mod 1)"
   255   apply (simp add: zadd_ac zadd_zmult_distrib2)
   245   apply (simp add: zadd_ac zadd_zmult_distrib2)
   256   done
   246   done
   257 
   247 
   258 lemma zcong_zmult:
   248 lemma zcong_zmult:
   259     "[a = b] (mod m) ==> [c = d] (mod m) ==> [a * c = b * d] (mod m)"
   249     "[a = b] (mod m) ==> [c = d] (mod m) ==> [a * c = b * d] (mod m)"
       
   250 
   260   apply (rule_tac b = "b * c" in zcong_trans)
   251   apply (rule_tac b = "b * c" in zcong_trans)
   261    apply (unfold zcong_def)
   252    apply (unfold zcong_def)
   262    apply (rule_tac s = "c * (a - b)" in subst)
   253   apply (metis zdiff_zmult_distrib2 zdvd_zmult zmult_commute)
   263     apply (rule_tac [3] s = "b * (c - d)" in subst)
   254   apply (metis zdiff_zmult_distrib2 zdvd_zmult)
   264      prefer 4
       
   265      apply (blast intro: zdvd_zmult)
       
   266     prefer 2
       
   267     apply (blast intro: zdvd_zmult)
       
   268    apply (simp_all add: zdiff_zmult_distrib2 zmult_commute)
       
   269   done
   255   done
   270 
   256 
   271 lemma zcong_scalar: "[a = b] (mod m) ==> [a * k = b * k] (mod m)"
   257 lemma zcong_scalar: "[a = b] (mod m) ==> [a * k = b * k] (mod m)"
   272   by (rule zcong_zmult, simp_all)
   258   by (rule zcong_zmult, simp_all)
   273 
   259 
   317     ==> [a = b] (mod m * n)"
   303     ==> [a = b] (mod m * n)"
   318   apply (unfold zcong_def dvd_def, auto)
   304   apply (unfold zcong_def dvd_def, auto)
   319   apply (subgoal_tac "m dvd n * ka")
   305   apply (subgoal_tac "m dvd n * ka")
   320    apply (subgoal_tac "m dvd ka")
   306    apply (subgoal_tac "m dvd ka")
   321     apply (case_tac [2] "0 \<le> ka")
   307     apply (case_tac [2] "0 \<le> ka")
   322      prefer 3
   308   apply (metis zdvd_mult_div_cancel zdvd_refl zdvd_zminus2_iff zdvd_zmultD2 zgcd_zminus zmult_commute zmult_zminus zrelprime_zdvd_zmult)
   323      apply (subst zdvd_zminus_iff [symmetric])
   309   apply (metis IntDiv.zdvd_abs1 abs_of_nonneg zadd_0 zgcd_0_left zgcd_commute zgcd_zadd_zmult zgcd_zdvd_zgcd_zmult zgcd_zmult_distrib2_abs zmult_1_right zmult_commute)
   324      apply (rule_tac n = n in zrelprime_zdvd_zmult)
   310   apply (metis abs_eq_0 int_0_neq_1 mult_le_0_iff  zdvd_mono zdvd_mult_cancel zdvd_mult_cancel1 zdvd_refl zdvd_triv_left zdvd_zmult2 zero_le_mult_iff zgcd_greatest_iff zle_anti_sym zle_linear zle_refl zmult_commute zrelprime_zdvd_zmult)
   325       apply (simp add: zgcd_commute)
   311   apply (metis zdvd_triv_left)
   326      apply (simp add: zmult_commute zdvd_zminus_iff)
       
   327     prefer 2
       
   328     apply (rule_tac n = n in zrelprime_zdvd_zmult)
       
   329      apply (simp add: zgcd_commute)
       
   330     apply (simp add: zmult_commute)
       
   331    apply (auto simp add: dvd_def)
       
   332   done
   312   done
   333 
   313 
   334 lemma zcong_zless_imp_eq:
   314 lemma zcong_zless_imp_eq:
   335   "0 \<le> a ==>
   315   "0 \<le> a ==>
   336     a < m ==> 0 \<le> b ==> b < m ==> [a = b] (mod m) ==> a = b"
   316     a < m ==> 0 \<le> b ==> b < m ==> [a = b] (mod m) ==> a = b"
   337   apply (unfold zcong_def dvd_def, auto)
   317   apply (unfold zcong_def dvd_def, auto)
   338   apply (drule_tac f = "\<lambda>z. z mod m" in arg_cong)
   318   apply (drule_tac f = "\<lambda>z. z mod m" in arg_cong)
   339   apply (cut_tac x = a and y = b in linorder_less_linear, auto)
   319   apply (metis diff_add_cancel mod_pos_pos_trivial zadd_0 zadd_commute zmod_eq_0_iff zmod_zadd_right_eq)
   340    apply (subgoal_tac [2] "(a - b) mod m = a - b")
       
   341     apply (rule_tac [3] mod_pos_pos_trivial, auto)
       
   342   apply (subgoal_tac "(m + (a - b)) mod m = m + (a - b)")
       
   343    apply (rule_tac [2] mod_pos_pos_trivial, auto)
       
   344   done
   320   done
   345 
   321 
   346 lemma zcong_square_zless:
   322 lemma zcong_square_zless:
   347   "zprime p ==> 0 < a ==> a < p ==>
   323   "zprime p ==> 0 < a ==> a < p ==>
   348     [a * a = 1] (mod p) ==> a = 1 \<or> a = p - 1"
   324     [a * a = 1] (mod p) ==> a = 1 \<or> a = p - 1"
   358   done
   334   done
   359 
   335 
   360 lemma zcong_zless_0:
   336 lemma zcong_zless_0:
   361     "0 \<le> a ==> a < m ==> [a = 0] (mod m) ==> a = 0"
   337     "0 \<le> a ==> a < m ==> [a = 0] (mod m) ==> a = 0"
   362   apply (unfold zcong_def dvd_def, auto)
   338   apply (unfold zcong_def dvd_def, auto)
   363   apply (subgoal_tac "0 < m")
   339   apply (metis div_pos_pos_trivial linorder_not_less zdiv_zmult_self2 zle_refl zle_trans)
   364    apply (simp add: zero_le_mult_iff)
       
   365    apply (subgoal_tac "m * k < m * 1")
       
   366     apply (drule mult_less_cancel_left [THEN iffD1])
       
   367     apply (auto simp add: linorder_neq_iff)
       
   368   done
   340   done
   369 
   341 
   370 lemma zcong_zless_unique:
   342 lemma zcong_zless_unique:
   371     "0 < m ==> (\<exists>!b. 0 \<le> b \<and> b < m \<and> [a = b] (mod m))"
   343     "0 < m ==> (\<exists>!b. 0 \<le> b \<and> b < m \<and> [a = b] (mod m))"
   372   apply auto
   344   apply auto
   373    apply (subgoal_tac [2] "[b = y] (mod m)")
   345    prefer 2 apply (metis zcong_sym zcong_trans zcong_zless_imp_eq)
   374     apply (case_tac [2] "b = 0")
       
   375      apply (case_tac [3] "y = 0")
       
   376       apply (auto intro: zcong_trans zcong_zless_0 zcong_zless_imp_eq order_less_le
       
   377         simp add: zcong_sym)
       
   378   apply (unfold zcong_def dvd_def)
   346   apply (unfold zcong_def dvd_def)
   379   apply (rule_tac x = "a mod m" in exI, auto)
   347   apply (rule_tac x = "a mod m" in exI, auto)
   380   apply (rule_tac x = "-(a div m)" in exI)
   348   apply (metis zmult_div_cancel)
   381   apply (simp add: diff_eq_eq eq_diff_eq add_commute)
       
   382   done
   349   done
   383 
   350 
   384 lemma zcong_iff_lin: "([a = b] (mod m)) = (\<exists>k. b = a + m * k)"
   351 lemma zcong_iff_lin: "([a = b] (mod m)) = (\<exists>k. b = a + m * k)"
   385   apply (unfold zcong_def dvd_def, auto)
   352   apply (unfold zcong_def dvd_def, auto)
   386    apply (rule_tac [!] x = "-k" in exI, auto)
   353    apply (rule_tac [!] x = "-k" in exI, auto)
   404   apply (simp add: zadd_commute)
   371   apply (simp add: zadd_commute)
   405   done
   372   done
   406 
   373 
   407 lemma zcong_zmod_eq: "0 < m ==> [a = b] (mod m) = (a mod m = b mod m)"
   374 lemma zcong_zmod_eq: "0 < m ==> [a = b] (mod m) = (a mod m = b mod m)"
   408   apply auto
   375   apply auto
   409    apply (rule_tac m = m in zcong_zless_imp_eq)
   376   apply (metis pos_mod_conj zcong_zless_imp_eq zcong_zmod)
   410        prefer 5
   377   apply (metis zcong_refl zcong_zmod)
   411        apply (subst zcong_zmod [symmetric], simp_all)
       
   412   apply (unfold zcong_def dvd_def)
       
   413   apply (rule_tac x = "a div m - b div m" in exI)
       
   414   apply (rule_tac m1 = m in zcong_zmod_aux [THEN trans], auto)
       
   415   done
   378   done
   416 
   379 
   417 lemma zcong_zminus [iff]: "[a = b] (mod -m) = [a = b] (mod m)"
   380 lemma zcong_zminus [iff]: "[a = b] (mod -m) = [a = b] (mod m)"
   418   by (auto simp add: zcong_def)
   381   by (auto simp add: zcong_def)
   419 
   382 
   455     (\<exists>sn tn. xzgcda (m, n, r', r, s', s, t', t) = (k, sn, tn))"
   418     (\<exists>sn tn. xzgcda (m, n, r', r, s', s, t', t) = (k, sn, tn))"
   456   apply (rule_tac u = m and v = n and w = r' and x = r and y = s' and
   419   apply (rule_tac u = m and v = n and w = r' and x = r and y = s' and
   457     z = s and aa = t' and ab = t in xzgcda.induct)
   420     z = s and aa = t' and ab = t in xzgcda.induct)
   458   apply (subst zgcd_eq)
   421   apply (subst zgcd_eq)
   459   apply (subst xzgcda.simps, auto)
   422   apply (subst xzgcda.simps, auto)
   460   apply (case_tac "r' mod r = 0")
   423   apply (metis abs_of_pos pos_mod_conj simps zgcd_0 zgcd_eq zle_refl zless_le)
   461    prefer 2
       
   462    apply (frule_tac a = "r'" in pos_mod_sign, auto)
       
   463   apply (rule exI)
       
   464   apply (rule exI)
       
   465   apply (subst xzgcda.simps, auto)
       
   466   done
   424   done
   467 
   425 
   468 lemma xzgcd_correct_aux2:
   426 lemma xzgcd_correct_aux2:
   469   "(\<exists>sn tn. xzgcda (m, n, r', r, s', s, t', t) = (k, sn, tn)) --> 0 < r -->
   427   "(\<exists>sn tn. xzgcda (m, n, r', r, s', s, t', t) = (k, sn, tn)) --> 0 < r -->
   470     zgcd (r', r) = k"
   428     zgcd (r', r) = k"
   474   apply (subst xzgcda.simps)
   432   apply (subst xzgcda.simps)
   475   apply (auto simp add: linorder_not_le)
   433   apply (auto simp add: linorder_not_le)
   476   apply (case_tac "r' mod r = 0")
   434   apply (case_tac "r' mod r = 0")
   477    prefer 2
   435    prefer 2
   478    apply (frule_tac a = "r'" in pos_mod_sign, auto)
   436    apply (frule_tac a = "r'" in pos_mod_sign, auto)
   479   apply (erule_tac P = "xzgcda ?u = ?v" in rev_mp)
   437   apply (metis Pair_eq simps zle_refl)
   480   apply (subst xzgcda.simps, auto)
       
   481   done
   438   done
   482 
   439 
   483 lemma xzgcd_correct:
   440 lemma xzgcd_correct:
   484     "0 < n ==> (zgcd (m, n) = k) = (\<exists>s t. xzgcd m n = (k, s, t))"
   441     "0 < n ==> (zgcd (m, n) = k) = (\<exists>s t. xzgcd m n = (k, s, t))"
   485   apply (unfold xzgcd_def)
   442   apply (unfold xzgcd_def)
   559    prefer 2
   516    prefer 2
   560    apply (simp add: zcong_sym)
   517    apply (simp add: zcong_sym)
   561   apply (cut_tac a = a and n = n in zcong_lineq_ex, auto)
   518   apply (cut_tac a = a and n = n in zcong_lineq_ex, auto)
   562   apply (rule_tac x = "x * b mod n" in exI, safe)
   519   apply (rule_tac x = "x * b mod n" in exI, safe)
   563     apply (simp_all (no_asm_simp))
   520     apply (simp_all (no_asm_simp))
   564   apply (subst zcong_zmod)
   521   apply (metis zcong_scalar zcong_zmod zmod_zmult1_eq zmult_1 zmult_assoc)
   565   apply (subst zmod_zmult1_eq [symmetric])
       
   566   apply (subst zcong_zmod [symmetric])
       
   567   apply (subgoal_tac "[a * x * b = 1 * b] (mod n)")
       
   568    apply (rule_tac [2] zcong_zmult)
       
   569     apply (simp_all add: zmult_assoc)
       
   570   done
   522   done
   571 
   523 
   572 end
   524 end