src/HOL/Number_Theory/Cong.thy
changeset 67051 e7e54a0b9197
parent 66954 0230af0f3c59
child 67085 f5d7f37b4143
equal deleted inserted replaced
67050:1e29e2666a15 67051:e7e54a0b9197
   227   done
   227   done
   228 
   228 
   229 lemma cong_mult_rcancel_int:
   229 lemma cong_mult_rcancel_int:
   230   "[a * k = b * k] (mod m) \<longleftrightarrow> [a = b] (mod m)"
   230   "[a * k = b * k] (mod m) \<longleftrightarrow> [a = b] (mod m)"
   231   if "coprime k m" for a k m :: int
   231   if "coprime k m" for a k m :: int
   232   by (metis that cong_altdef_int left_diff_distrib coprime_dvd_mult_iff gcd.commute)
   232   using that by (simp add: cong_altdef_int)
       
   233     (metis coprime_commute coprime_dvd_mult_right_iff mult.commute right_diff_distrib') 
   233 
   234 
   234 lemma cong_mult_rcancel_nat:
   235 lemma cong_mult_rcancel_nat:
   235   "[a * k = b * k] (mod m) \<longleftrightarrow> [a = b] (mod m)"
   236   "[a * k = b * k] (mod m) \<longleftrightarrow> [a = b] (mod m)"
   236   if "coprime k m" for a k m :: nat
   237   if "coprime k m" for a k m :: nat
   237 proof -
   238 proof -
   240   also have "\<dots> \<longleftrightarrow> m dvd nat \<bar>(int a - int b) * int k\<bar>"
   241   also have "\<dots> \<longleftrightarrow> m dvd nat \<bar>(int a - int b) * int k\<bar>"
   241     by (simp add: algebra_simps)
   242     by (simp add: algebra_simps)
   242   also have "\<dots> \<longleftrightarrow> m dvd nat \<bar>int a - int b\<bar> * k"
   243   also have "\<dots> \<longleftrightarrow> m dvd nat \<bar>int a - int b\<bar> * k"
   243     by (simp add: abs_mult nat_times_as_int)
   244     by (simp add: abs_mult nat_times_as_int)
   244   also have "\<dots> \<longleftrightarrow> m dvd nat \<bar>int a - int b\<bar>"
   245   also have "\<dots> \<longleftrightarrow> m dvd nat \<bar>int a - int b\<bar>"
   245     by (rule coprime_dvd_mult_iff) (use \<open>coprime k m\<close> in \<open>simp add: ac_simps\<close>)
   246     by (rule coprime_dvd_mult_left_iff) (use \<open>coprime k m\<close> in \<open>simp add: ac_simps\<close>)
   246   also have "\<dots> \<longleftrightarrow> [a = b] (mod m)"
   247   also have "\<dots> \<longleftrightarrow> [a = b] (mod m)"
   247     by (simp add: cong_altdef_nat')
   248     by (simp add: cong_altdef_nat')
   248   finally show ?thesis .
   249   finally show ?thesis .
   249 qed
   250 qed
   250 
   251 
   318   for a b :: int
   319   for a b :: int
   319   by (auto simp add: cong_def) (metis gcd_red_int)
   320   by (auto simp add: cong_def) (metis gcd_red_int)
   320 
   321 
   321 lemma cong_imp_coprime_nat: "[a = b] (mod m) \<Longrightarrow> coprime a m \<Longrightarrow> coprime b m"
   322 lemma cong_imp_coprime_nat: "[a = b] (mod m) \<Longrightarrow> coprime a m \<Longrightarrow> coprime b m"
   322   for a b :: nat
   323   for a b :: nat
   323   by (auto simp add: cong_gcd_eq_nat)
   324   by (auto simp add: cong_gcd_eq_nat coprime_iff_gcd_eq_1)
   324 
   325 
   325 lemma cong_imp_coprime_int: "[a = b] (mod m) \<Longrightarrow> coprime a m \<Longrightarrow> coprime b m"
   326 lemma cong_imp_coprime_int: "[a = b] (mod m) \<Longrightarrow> coprime a m \<Longrightarrow> coprime b m"
   326   for a b :: int
   327   for a b :: int
   327   by (auto simp add: cong_gcd_eq_int)
   328   by (auto simp add: cong_gcd_eq_int coprime_iff_gcd_eq_1)
   328 
   329 
   329 lemma cong_cong_mod_nat: "[a = b] (mod m) \<longleftrightarrow> [a mod m = b mod m] (mod m)"
   330 lemma cong_cong_mod_nat: "[a = b] (mod m) \<longleftrightarrow> [a mod m = b mod m] (mod m)"
   330   for a b :: nat
   331   for a b :: nat
   331   by simp
   332   by simp
   332 
   333 
   488   finally show ?thesis
   489   finally show ?thesis
   489     by auto
   490     by auto
   490 qed
   491 qed
   491 
   492 
   492 lemma cong_solve_coprime_nat:
   493 lemma cong_solve_coprime_nat:
   493   fixes a :: nat
   494   "\<exists>x. [a * x = Suc 0] (mod n)" if "coprime a n"
   494   assumes "coprime a n"
   495   using that cong_solve_nat [of a n] by (cases "a = 0") simp_all
   495   shows "\<exists>x. [a * x = 1] (mod n)"
   496 
   496 proof (cases "a = 0")
   497 lemma cong_solve_coprime_int:
   497   case True
   498   "\<exists>x. [a * x = 1] (mod n)" if "coprime a n" for a n x :: int
   498   with assms show ?thesis
   499   using that cong_solve_int [of a n] by (cases "a = 0")
   499     by (simp add: cong_0_1_nat') 
   500     (auto simp add: zabs_def split: if_splits)
   500 next
       
   501   case False
       
   502   with assms show ?thesis
       
   503     by (metis cong_solve_nat)
       
   504 qed
       
   505 
       
   506 lemma cong_solve_coprime_int: "coprime (a::int) n \<Longrightarrow> \<exists>x. [a * x = 1] (mod n)"
       
   507   apply (cases "a = 0")
       
   508    apply auto
       
   509    apply (cases "n \<ge> 0")
       
   510     apply auto
       
   511   apply (metis cong_solve_int)
       
   512   done
       
   513 
   501 
   514 lemma coprime_iff_invertible_nat:
   502 lemma coprime_iff_invertible_nat:
   515   "m > 0 \<Longrightarrow> coprime a m = (\<exists>x. [a * x = Suc 0] (mod m))"
   503   "m > 0 \<Longrightarrow> coprime a m \<longleftrightarrow> (\<exists>x. [a * x = Suc 0] (mod m))"
   516   by (metis One_nat_def cong_gcd_eq_nat cong_solve_coprime_nat coprime_lmult gcd.commute gcd_Suc_0)
   504   by (auto intro: cong_solve_coprime_nat)
   517 
   505     (use cong_imp_coprime_nat cong_sym coprime_Suc_0_left coprime_mult_left_iff in blast)
   518 lemma coprime_iff_invertible_int: "m > 0 \<Longrightarrow> coprime a m \<longleftrightarrow> (\<exists>x. [a * x = 1] (mod m))"
   506 
       
   507 lemma coprime_iff_invertible_int:
       
   508   "m > 0 \<Longrightarrow> coprime a m \<longleftrightarrow> (\<exists>x. [a * x = 1] (mod m))"
   519   for m :: int
   509   for m :: int
   520   apply (auto intro: cong_solve_coprime_int)
   510   by (auto intro: cong_solve_coprime_int)
   521   using cong_gcd_eq_int coprime_mul_eq' apply fastforce
   511     (meson cong_imp_coprime_int cong_sym coprime_1_left coprime_mult_left_iff)
   522   done
       
   523 
   512 
   524 lemma coprime_iff_invertible'_nat:
   513 lemma coprime_iff_invertible'_nat:
   525   "m > 0 \<Longrightarrow> coprime a m \<longleftrightarrow> (\<exists>x. 0 \<le> x \<and> x < m \<and> [a * x = Suc 0] (mod m))"
   514   "m > 0 \<Longrightarrow> coprime a m \<longleftrightarrow> (\<exists>x. 0 \<le> x \<and> x < m \<and> [a * x = Suc 0] (mod m))"
   526   apply (subst coprime_iff_invertible_nat)
   515   apply (subst coprime_iff_invertible_nat)
   527    apply auto
   516    apply auto
   552   "[x = y] (mod (\<Prod>i\<in>A. m i))" if
   541   "[x = y] (mod (\<Prod>i\<in>A. m i))" if
   553     "(\<forall>i\<in>A. [(x::nat) = y] (mod m i))"
   542     "(\<forall>i\<in>A. [(x::nat) = y] (mod m i))"
   554     and "(\<forall>i\<in>A. (\<forall>j\<in>A. i \<noteq> j \<longrightarrow> coprime (m i) (m j)))"
   543     and "(\<forall>i\<in>A. (\<forall>j\<in>A. i \<noteq> j \<longrightarrow> coprime (m i) (m j)))"
   555   using that apply (induct A rule: infinite_finite_induct)
   544   using that apply (induct A rule: infinite_finite_induct)
   556     apply auto
   545     apply auto
   557   apply (metis One_nat_def coprime_cong_mult_nat gcd.commute prod_coprime)
   546   apply (metis coprime_cong_mult_nat prod_coprime_right)
   558   done
   547   done
   559 
   548 
   560 lemma cong_cong_prod_coprime_int [rule_format]:
   549 lemma cong_cong_prod_coprime_int:
   561   "[x = y] (mod (\<Prod>i\<in>A. m i))" if
   550   "[x = y] (mod (\<Prod>i\<in>A. m i))" if
   562     "(\<forall>i\<in>A. [(x::int) = y] (mod m i))"
   551     "(\<forall>i\<in>A. [(x::int) = y] (mod m i))"
   563     "(\<forall>i\<in>A. (\<forall>j\<in>A. i \<noteq> j \<longrightarrow> coprime (m i) (m j)))"
   552     "(\<forall>i\<in>A. (\<forall>j\<in>A. i \<noteq> j \<longrightarrow> coprime (m i) (m j)))"
   564   using that apply (induct A rule: infinite_finite_induct)
   553   using that apply (induct A rule: infinite_finite_induct)
   565   apply auto
   554     apply auto
   566   apply (metis coprime_cong_mult_int gcd.commute prod_coprime)
   555   apply (metis coprime_cong_mult_int prod_coprime_right)
   567   done
   556   done
   568 
   557 
   569 lemma binary_chinese_remainder_aux_nat:
   558 lemma binary_chinese_remainder_aux_nat:
   570   fixes m1 m2 :: nat
   559   fixes m1 m2 :: nat
   571   assumes a: "coprime m1 m2"
   560   assumes a: "coprime m1 m2"
   572   shows "\<exists>b1 b2. [b1 = 1] (mod m1) \<and> [b1 = 0] (mod m2) \<and> [b2 = 0] (mod m1) \<and> [b2 = 1] (mod m2)"
   561   shows "\<exists>b1 b2. [b1 = 1] (mod m1) \<and> [b1 = 0] (mod m2) \<and> [b2 = 0] (mod m1) \<and> [b2 = 1] (mod m2)"
   573 proof -
   562 proof -
   574   from cong_solve_coprime_nat [OF a] obtain x1 where 1: "[m1 * x1 = 1] (mod m2)"
   563   from cong_solve_coprime_nat [OF a] obtain x1 where 1: "[m1 * x1 = 1] (mod m2)"
   575     by auto
   564     by auto
   576   from a have b: "coprime m2 m1"
   565   from a have b: "coprime m2 m1"
   577     by (subst gcd.commute)
   566     by (simp add: ac_simps)
   578   from cong_solve_coprime_nat [OF b] obtain x2 where 2: "[m2 * x2 = 1] (mod m1)"
   567   from cong_solve_coprime_nat [OF b] obtain x2 where 2: "[m2 * x2 = 1] (mod m1)"
   579     by auto
   568     by auto
   580   have "[m1 * x1 = 0] (mod m1)"
   569   have "[m1 * x1 = 0] (mod m1)"
   581     by (simp add: cong_mult_self_left)
   570     by (simp add: cong_mult_self_left)
   582   moreover have "[m2 * x2 = 0] (mod m2)"
   571   moreover have "[m2 * x2 = 0] (mod m2)"
   591   shows "\<exists>b1 b2. [b1 = 1] (mod m1) \<and> [b1 = 0] (mod m2) \<and> [b2 = 0] (mod m1) \<and> [b2 = 1] (mod m2)"
   580   shows "\<exists>b1 b2. [b1 = 1] (mod m1) \<and> [b1 = 0] (mod m2) \<and> [b2 = 0] (mod m1) \<and> [b2 = 1] (mod m2)"
   592 proof -
   581 proof -
   593   from cong_solve_coprime_int [OF a] obtain x1 where 1: "[m1 * x1 = 1] (mod m2)"
   582   from cong_solve_coprime_int [OF a] obtain x1 where 1: "[m1 * x1 = 1] (mod m2)"
   594     by auto
   583     by auto
   595   from a have b: "coprime m2 m1"
   584   from a have b: "coprime m2 m1"
   596     by (subst gcd.commute)
   585     by (simp add: ac_simps)
   597   from cong_solve_coprime_int [OF b] obtain x2 where 2: "[m2 * x2 = 1] (mod m1)"
   586   from cong_solve_coprime_int [OF b] obtain x2 where 2: "[m2 * x2 = 1] (mod m1)"
   598     by auto
   587     by auto
   599   have "[m1 * x1 = 0] (mod m1)"
   588   have "[m1 * x1 = 0] (mod m1)"
   600     by (simp add: cong_mult_self_left)
   589     by (simp add: cong_mult_self_left)
   601   moreover have "[m2 * x2 = 0] (mod m2)"
   590   moreover have "[m2 * x2 = 0] (mod m2)"
   728   shows "\<exists>b. (\<forall>i \<in> A. [b i = 1] (mod m i) \<and> [b i = 0] (mod (\<Prod>j \<in> A - {i}. m j)))"
   717   shows "\<exists>b. (\<forall>i \<in> A. [b i = 1] (mod m i) \<and> [b i = 0] (mod (\<Prod>j \<in> A - {i}. m j)))"
   729 proof (rule finite_set_choice, rule fin, rule ballI)
   718 proof (rule finite_set_choice, rule fin, rule ballI)
   730   fix i
   719   fix i
   731   assume "i \<in> A"
   720   assume "i \<in> A"
   732   with cop have "coprime (\<Prod>j \<in> A - {i}. m j) (m i)"
   721   with cop have "coprime (\<Prod>j \<in> A - {i}. m j) (m i)"
   733     by (intro prod_coprime) auto
   722     by (intro prod_coprime_left) auto
   734   then have "\<exists>x. [(\<Prod>j \<in> A - {i}. m j) * x = 1] (mod m i)"
   723   then have "\<exists>x. [(\<Prod>j \<in> A - {i}. m j) * x = Suc 0] (mod m i)"
   735     by (elim cong_solve_coprime_nat)
   724     by (elim cong_solve_coprime_nat)
   736   then obtain x where "[(\<Prod>j \<in> A - {i}. m j) * x = 1] (mod m i)"
   725   then obtain x where "[(\<Prod>j \<in> A - {i}. m j) * x = 1] (mod m i)"
   737     by auto
   726     by auto
   738   moreover have "[(\<Prod>j \<in> A - {i}. m j) * x = 0] (mod (\<Prod>j \<in> A - {i}. m j))"
   727   moreover have "[(\<Prod>j \<in> A - {i}. m j) * x = 0] (mod (\<Prod>j \<in> A - {i}. m j))"
   739     by (simp add: cong_0_iff)
   728     by (simp add: cong_0_iff)
   787 lemma coprime_cong_prod_nat:
   776 lemma coprime_cong_prod_nat:
   788   "[x = y] (mod (\<Prod>i\<in>A. m i))"
   777   "[x = y] (mod (\<Prod>i\<in>A. m i))"
   789   if "\<forall>i\<in>A. (\<forall>j\<in>A. i \<noteq> j \<longrightarrow> coprime (m i) (m j))"
   778   if "\<forall>i\<in>A. (\<forall>j\<in>A. i \<noteq> j \<longrightarrow> coprime (m i) (m j))"
   790     and "\<forall>i\<in>A. [x = y] (mod m i)" for x y :: nat
   779     and "\<forall>i\<in>A. [x = y] (mod m i)" for x y :: nat
   791   using that apply (induct A rule: infinite_finite_induct)
   780   using that apply (induct A rule: infinite_finite_induct)
   792   apply auto
   781     apply auto
   793   apply (metis One_nat_def coprime_cong_mult_nat gcd.commute prod_coprime)
   782   apply (metis coprime_cong_mult_nat prod_coprime_right)
   794   done
   783   done
   795 
   784 
   796 lemma chinese_remainder_unique_nat:
   785 lemma chinese_remainder_unique_nat:
   797   fixes A :: "'a set"
   786   fixes A :: "'a set"
   798     and m :: "'a \<Rightarrow> nat"
   787     and m :: "'a \<Rightarrow> nat"