src/HOL/Number_Theory/Cong.thy
changeset 66954 0230af0f3c59
parent 66888 930abfdf8727
child 67051 e7e54a0b9197
equal deleted inserted replaced
66953:826a5fd4d36c 66954:0230af0f3c59
   159 end
   159 end
   160 
   160 
   161 
   161 
   162 subsection \<open>Congruences on @{typ nat} and @{typ int}\<close>
   162 subsection \<open>Congruences on @{typ nat} and @{typ int}\<close>
   163 
   163 
   164 lemma transfer_nat_int_cong:
       
   165   "x \<ge> 0 \<Longrightarrow> y \<ge> 0 \<Longrightarrow> m \<ge> 0 \<Longrightarrow> [nat x = nat y] (mod (nat m)) \<longleftrightarrow> [x = y] (mod m)"
       
   166   for x y m :: int
       
   167   by (auto simp add: cong_def nat_mod_distrib [symmetric])
       
   168      (metis eq_nat_nat_iff le_less mod_by_0 pos_mod_conj)
       
   169 
       
   170 declare transfer_morphism_nat_int [transfer add return: transfer_nat_int_cong]
       
   171 
       
   172 lemma cong_int_iff:
   164 lemma cong_int_iff:
   173   "[int m = int q] (mod int n) \<longleftrightarrow> [m = q] (mod n)"
   165   "[int m = int q] (mod int n) \<longleftrightarrow> [m = q] (mod n)"
   174   by (simp add: cong_def of_nat_mod [symmetric])
   166   by (simp add: cong_def of_nat_mod [symmetric])
   175 
   167 
   176 lemma transfer_int_nat_cong:
       
   177   "[int x = int y] (mod (int m)) = [x = y] (mod m)"
       
   178   by (fact cong_int_iff)
       
   179 
       
   180 declare transfer_morphism_int_nat [transfer add return: transfer_int_nat_cong]
       
   181 
       
   182 lemma cong_Suc_0 [simp, presburger]:
   168 lemma cong_Suc_0 [simp, presburger]:
   183   "[m = n] (mod Suc 0)"
   169   "[m = n] (mod Suc 0)"
   184   using cong_1 [of m n] by simp
   170   using cong_1 [of m n] by simp
   185 
   171 
   186 lemma cong_diff_aux_int:
       
   187   "[a = b] (mod m) \<Longrightarrow> [c = d] (mod m) \<Longrightarrow>
       
   188     a \<ge> c \<Longrightarrow> b \<ge> d \<Longrightarrow> [tsub a c = tsub b d] (mod m)"
       
   189   for a b c d :: int
       
   190   by (metis cong_diff tsub_eq)
       
   191 
       
   192 lemma cong_diff_nat:
   172 lemma cong_diff_nat:
   193   "[a - c = b - d] (mod m)" if "[a = b] (mod m)" "[c = d] (mod m)"
   173   "[a - c = b - d] (mod m)" if "[a = b] (mod m)" "[c = d] (mod m)"
   194     and "a \<ge> c" "b \<ge> d" for a b c d m :: nat 
   174     and "a \<ge> c" "b \<ge> d" for a b c d m :: nat
   195   using that by (rule cong_diff_aux_int [transferred])
   175 proof -
   196 
   176   have "[c + (a - c) = d + (b - d)] (mod m)"
   197 lemma cong_diff_iff_cong_0_aux_int: "a \<ge> b \<Longrightarrow> [tsub a b = 0] (mod m) = [a = b] (mod m)"
   177     using that by simp
   198   for a b :: int
   178   with \<open>[c = d] (mod m)\<close> have "[c + (a - c) = c + (b - d)] (mod m)"
   199   by (subst tsub_eq, assumption, rule cong_diff_iff_cong_0)
   179     using mod_add_cong by (auto simp add: cong_def) fastforce
       
   180   then show ?thesis
       
   181     by (simp add: cong_def nat_mod_eq_iff)
       
   182 qed
   200 
   183 
   201 lemma cong_diff_iff_cong_0_nat:
   184 lemma cong_diff_iff_cong_0_nat:
   202   fixes a b :: nat
   185   "[a - b = 0] (mod m) \<longleftrightarrow> [a = b] (mod m)" if "a \<ge> b" for a b :: nat
   203   assumes "a \<ge> b"
   186   using that by (auto simp add: cong_def le_imp_diff_is_add dest: nat_mod_eq_lemma)
   204   shows "[a - b = 0] (mod m) = [a = b] (mod m)"
   187 
   205   using assms by (rule cong_diff_iff_cong_0_aux_int [transferred])
   188 lemma cong_diff_iff_cong_0_nat':
   206 
   189   "[nat \<bar>int a - int b\<bar> = 0] (mod m) \<longleftrightarrow> [a = b] (mod m)"
   207 lemma cong_altdef_nat: "a \<ge> b \<Longrightarrow> [a = b] (mod m) \<longleftrightarrow> m dvd (a - b)"
   190 proof (cases "b \<le> a")
       
   191   case True
       
   192   then show ?thesis
       
   193     by (simp add: nat_diff_distrib' cong_diff_iff_cong_0_nat [of b a m])
       
   194 next
       
   195   case False
       
   196   then have "a \<le> b"
       
   197     by simp
       
   198   then show ?thesis
       
   199     by (simp add: nat_diff_distrib' cong_diff_iff_cong_0_nat [of a b m])
       
   200       (auto simp add: cong_def)
       
   201 qed
       
   202 
       
   203 lemma cong_altdef_nat:
       
   204   "a \<ge> b \<Longrightarrow> [a = b] (mod m) \<longleftrightarrow> m dvd (a - b)"
   208   for a b :: nat
   205   for a b :: nat
   209   by (simp add: cong_0_iff [symmetric] cong_diff_iff_cong_0_nat)
   206   by (simp add: cong_0_iff [symmetric] cong_diff_iff_cong_0_nat)
   210 
   207 
   211 lemma cong_altdef_int: "[a = b] (mod m) \<longleftrightarrow> m dvd (a - b)"
   208 lemma cong_altdef_nat':
       
   209   "[a = b] (mod m) \<longleftrightarrow> m dvd nat \<bar>int a - int b\<bar>"
       
   210   by (simp add: cong_0_iff [symmetric] cong_diff_iff_cong_0_nat')
       
   211 
       
   212 lemma cong_altdef_int:
       
   213   "[a = b] (mod m) \<longleftrightarrow> m dvd (a - b)"
   212   for a b :: int
   214   for a b :: int
   213   by (simp add: cong_0_iff [symmetric] cong_diff_iff_cong_0)
   215   by (simp add: cong_0_iff [symmetric] cong_diff_iff_cong_0)
   214 
   216 
   215 lemma cong_abs_int [simp]: "[x = y] (mod abs m) \<longleftrightarrow> [x = y] (mod m)"
   217 lemma cong_abs_int [simp]: "[x = y] (mod abs m) \<longleftrightarrow> [x = y] (mod m)"
   216   for x y :: int
   218   for x y :: int
   222   apply (simp only: cong_altdef_int)
   224   apply (simp only: cong_altdef_int)
   223   apply (subst prime_dvd_mult_eq_int [symmetric], assumption)
   225   apply (subst prime_dvd_mult_eq_int [symmetric], assumption)
   224   apply (auto simp add: field_simps)
   226   apply (auto simp add: field_simps)
   225   done
   227   done
   226 
   228 
   227 lemma cong_mult_rcancel_int: "coprime k m \<Longrightarrow> [a * k = b * k] (mod m) = [a = b] (mod m)"
   229 lemma cong_mult_rcancel_int:
   228   for a k m :: int
   230   "[a * k = b * k] (mod m) \<longleftrightarrow> [a = b] (mod m)"
   229   by (metis cong_altdef_int left_diff_distrib coprime_dvd_mult_iff gcd.commute)
   231   if "coprime k m" for a k m :: int
   230 
   232   by (metis that cong_altdef_int left_diff_distrib coprime_dvd_mult_iff gcd.commute)
   231 lemma cong_mult_rcancel_nat: "coprime k m \<Longrightarrow> [a * k = b * k] (mod m) = [a = b] (mod m)"
   233 
   232   for a k m :: nat
   234 lemma cong_mult_rcancel_nat:
   233   by (metis cong_mult_rcancel_int [transferred])
   235   "[a * k = b * k] (mod m) \<longleftrightarrow> [a = b] (mod m)"
   234 
   236   if "coprime k m" for a k m :: nat
   235 lemma cong_mult_lcancel_nat: "coprime k m \<Longrightarrow> [k * a = k * b ] (mod m) = [a = b] (mod m)"
   237 proof -
   236   for a k m :: nat
   238   have "[a * k = b * k] (mod m) \<longleftrightarrow> m dvd nat \<bar>int (a * k) - int (b * k)\<bar>"
   237   by (simp add: mult.commute cong_mult_rcancel_nat)
   239     by (simp add: cong_altdef_nat')
   238 
   240   also have "\<dots> \<longleftrightarrow> m dvd nat \<bar>(int a - int b) * int k\<bar>"
   239 lemma cong_mult_lcancel_int: "coprime k m \<Longrightarrow> [k * a = k * b] (mod m) = [a = b] (mod m)"
   241     by (simp add: algebra_simps)
   240   for a k m :: int
   242   also have "\<dots> \<longleftrightarrow> m dvd nat \<bar>int a - int b\<bar> * k"
   241   by (simp add: mult.commute cong_mult_rcancel_int)
   243     by (simp add: abs_mult nat_times_as_int)
       
   244   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   also have "\<dots> \<longleftrightarrow> [a = b] (mod m)"
       
   247     by (simp add: cong_altdef_nat')
       
   248   finally show ?thesis .
       
   249 qed
       
   250 
       
   251 lemma cong_mult_lcancel_int:
       
   252   "[k * a = k * b] (mod m) = [a = b] (mod m)"
       
   253   if "coprime k m" for a k m :: int
       
   254   using that by (simp add: cong_mult_rcancel_int ac_simps)
       
   255 
       
   256 lemma cong_mult_lcancel_nat:
       
   257   "[k * a = k * b] (mod m) = [a = b] (mod m)"
       
   258   if "coprime k m" for a k m :: nat
       
   259   using that by (simp add: cong_mult_rcancel_nat ac_simps)
   242 
   260 
   243 lemma coprime_cong_mult_int:
   261 lemma coprime_cong_mult_int:
   244   "[a = b] (mod m) \<Longrightarrow> [a = b] (mod n) \<Longrightarrow> coprime m n \<Longrightarrow> [a = b] (mod m * n)"
   262   "[a = b] (mod m) \<Longrightarrow> [a = b] (mod n) \<Longrightarrow> coprime m n \<Longrightarrow> [a = b] (mod m * n)"
   245   for a b :: int
   263   for a b :: int
   246   by (metis divides_mult cong_altdef_int)
   264   by (simp add: cong_altdef_int divides_mult)
   247 
   265 
   248 lemma coprime_cong_mult_nat:
   266 lemma coprime_cong_mult_nat:
   249   "[a = b] (mod m) \<Longrightarrow> [a = b] (mod n) \<Longrightarrow> coprime m n \<Longrightarrow> [a = b] (mod m * n)"
   267   "[a = b] (mod m) \<Longrightarrow> [a = b] (mod n) \<Longrightarrow> coprime m n \<Longrightarrow> [a = b] (mod m * n)"
   250   for a b :: nat
   268   for a b :: nat
   251   by (metis coprime_cong_mult_int [transferred])
   269   by (simp add: cong_altdef_nat' divides_mult)
   252 
   270 
   253 lemma cong_less_imp_eq_nat: "0 \<le> a \<Longrightarrow> a < m \<Longrightarrow> 0 \<le> b \<Longrightarrow> b < m \<Longrightarrow> [a = b] (mod m) \<Longrightarrow> a = b"
   271 lemma cong_less_imp_eq_nat: "0 \<le> a \<Longrightarrow> a < m \<Longrightarrow> 0 \<le> b \<Longrightarrow> b < m \<Longrightarrow> [a = b] (mod m) \<Longrightarrow> a = b"
   254   for a b :: nat
   272   for a b :: nat
   255   by (auto simp add: cong_def)
   273   by (auto simp add: cong_def)
   256 
   274 
   290   assume ?rhs
   308   assume ?rhs
   291   then show ?lhs
   309   then show ?lhs
   292     by (metis cong_def mult.commute nat_mod_eq_iff) 
   310     by (metis cong_def mult.commute nat_mod_eq_iff) 
   293 qed
   311 qed
   294 
   312 
       
   313 lemma cong_gcd_eq_nat: "[a = b] (mod m) \<Longrightarrow> gcd a m = gcd b m"
       
   314   for a b :: nat
       
   315   by (auto simp add: cong_def) (metis gcd_red_nat)
       
   316 
   295 lemma cong_gcd_eq_int: "[a = b] (mod m) \<Longrightarrow> gcd a m = gcd b m"
   317 lemma cong_gcd_eq_int: "[a = b] (mod m) \<Longrightarrow> gcd a m = gcd b m"
   296   for a b :: int
   318   for a b :: int
   297   by (auto simp add: cong_def) (metis gcd_red_int)
   319   by (auto simp add: cong_def) (metis gcd_red_int)
   298 
       
   299 lemma cong_gcd_eq_nat: "[a = b] (mod m) \<Longrightarrow> gcd a m = gcd b m"
       
   300   for a b :: nat
       
   301   by (metis cong_gcd_eq_int [transferred])
       
   302 
   320 
   303 lemma cong_imp_coprime_nat: "[a = b] (mod m) \<Longrightarrow> coprime a m \<Longrightarrow> coprime b m"
   321 lemma cong_imp_coprime_nat: "[a = b] (mod m) \<Longrightarrow> coprime a m \<Longrightarrow> coprime b m"
   304   for a b :: nat
   322   for a b :: nat
   305   by (auto simp add: cong_gcd_eq_nat)
   323   by (auto simp add: cong_gcd_eq_nat)
   306 
   324