src/HOL/Number_Theory/Cong.thy
changeset 55371 cb0c6cb10681
parent 55337 5d45fb978d5a
child 57418 6ab1c7cb0b8d
equal deleted inserted replaced
55370:e6be866b5f5b 55371:cb0c6cb10681
   249   apply (unfold cong_nat_def)
   249   apply (unfold cong_nat_def)
   250   apply (simp add: dvd_eq_mod_eq_0 [symmetric])
   250   apply (simp add: dvd_eq_mod_eq_0 [symmetric])
   251   done
   251   done
   252 
   252 
   253 lemma cong_altdef_int: "[(a::int) = b] (mod m) = (m dvd (a - b))"
   253 lemma cong_altdef_int: "[(a::int) = b] (mod m) = (m dvd (a - b))"
   254   apply (subst cong_eq_diff_cong_0_int)
   254   by (metis cong_int_def zmod_eq_dvd_iff)
   255   apply (unfold cong_int_def)
       
   256   apply (simp add: dvd_eq_mod_eq_0 [symmetric])
       
   257   done
       
   258 
   255 
   259 lemma cong_abs_int: "[(x::int) = y] (mod abs m) = [x = y] (mod m)"
   256 lemma cong_abs_int: "[(x::int) = y] (mod abs m) = [x = y] (mod m)"
   260   by (simp add: cong_altdef_int)
   257   by (simp add: cong_altdef_int)
   261 
   258 
   262 lemma cong_square_int:
   259 lemma cong_square_int:
   268   apply (auto simp add: field_simps)
   265   apply (auto simp add: field_simps)
   269   done
   266   done
   270 
   267 
   271 lemma cong_mult_rcancel_int:
   268 lemma cong_mult_rcancel_int:
   272     "coprime k (m::int) \<Longrightarrow> [a * k = b * k] (mod m) = [a = b] (mod m)"
   269     "coprime k (m::int) \<Longrightarrow> [a * k = b * k] (mod m) = [a = b] (mod m)"
   273   apply (subst (1 2) cong_altdef_int)
   270   by (metis cong_altdef_int left_diff_distrib coprime_dvd_mult_iff_int gcd_int.commute)
   274   apply (subst left_diff_distrib [symmetric])
       
   275   apply (rule coprime_dvd_mult_iff_int)
       
   276   apply (subst gcd_commute_int, assumption)
       
   277   done
       
   278 
   271 
   279 lemma cong_mult_rcancel_nat:
   272 lemma cong_mult_rcancel_nat:
   280   assumes  "coprime k (m::nat)"
   273     "coprime k (m::nat) \<Longrightarrow> [a * k = b * k] (mod m) = [a = b] (mod m)"
   281   shows "[a * k = b * k] (mod m) = [a = b] (mod m)"
   274   by (metis cong_mult_rcancel_int [transferred])
   282   apply (rule cong_mult_rcancel_int [transferred])
       
   283   using assms apply auto
       
   284   done
       
   285 
   275 
   286 lemma cong_mult_lcancel_nat:
   276 lemma cong_mult_lcancel_nat:
   287     "coprime k (m::nat) \<Longrightarrow> [k * a = k * b ] (mod m) = [a = b] (mod m)"
   277     "coprime k (m::nat) \<Longrightarrow> [k * a = k * b ] (mod m) = [a = b] (mod m)"
   288   by (simp add: mult_commute cong_mult_rcancel_nat)
   278   by (simp add: mult_commute cong_mult_rcancel_nat)
   289 
   279 
   293 
   283 
   294 (* was zcong_zgcd_zmult_zmod *)
   284 (* was zcong_zgcd_zmult_zmod *)
   295 lemma coprime_cong_mult_int:
   285 lemma coprime_cong_mult_int:
   296   "[(a::int) = b] (mod m) \<Longrightarrow> [a = b] (mod n) \<Longrightarrow> coprime m n
   286   "[(a::int) = b] (mod m) \<Longrightarrow> [a = b] (mod n) \<Longrightarrow> coprime m n
   297     \<Longrightarrow> [a = b] (mod m * n)"
   287     \<Longrightarrow> [a = b] (mod m * n)"
   298   apply (simp only: cong_altdef_int)
   288 by (metis divides_mult_int cong_altdef_int)
   299   apply (erule (2) divides_mult_int)
       
   300   done
       
   301 
   289 
   302 lemma coprime_cong_mult_nat:
   290 lemma coprime_cong_mult_nat:
   303   assumes "[(a::nat) = b] (mod m)" and "[a = b] (mod n)" and "coprime m n"
   291   assumes "[(a::nat) = b] (mod m)" and "[a = b] (mod n)" and "coprime m n"
   304   shows "[a = b] (mod m * n)"
   292   shows "[a = b] (mod m * n)"
   305   apply (rule coprime_cong_mult_int [transferred])
   293   by (metis assms coprime_cong_mult_int [transferred])
   306   using assms apply auto
       
   307   done
       
   308 
   294 
   309 lemma cong_less_imp_eq_nat: "0 \<le> (a::nat) \<Longrightarrow>
   295 lemma cong_less_imp_eq_nat: "0 \<le> (a::nat) \<Longrightarrow>
   310     a < m \<Longrightarrow> 0 \<le> b \<Longrightarrow> b < m \<Longrightarrow> [a = b] (mod m) \<Longrightarrow> a = b"
   296     a < m \<Longrightarrow> 0 \<le> b \<Longrightarrow> b < m \<Longrightarrow> [a = b] (mod m) \<Longrightarrow> a = b"
   311   by (auto simp add: cong_nat_def)
   297   by (auto simp add: cong_nat_def)
   312 
   298 
   314     a < m \<Longrightarrow> 0 \<le> b \<Longrightarrow> b < m \<Longrightarrow> [a = b] (mod m) \<Longrightarrow> a = b"
   300     a < m \<Longrightarrow> 0 \<le> b \<Longrightarrow> b < m \<Longrightarrow> [a = b] (mod m) \<Longrightarrow> a = b"
   315   by (auto simp add: cong_int_def)
   301   by (auto simp add: cong_int_def)
   316 
   302 
   317 lemma cong_less_unique_nat:
   303 lemma cong_less_unique_nat:
   318     "0 < (m::nat) \<Longrightarrow> (\<exists>!b. 0 \<le> b \<and> b < m \<and> [a = b] (mod m))"
   304     "0 < (m::nat) \<Longrightarrow> (\<exists>!b. 0 \<le> b \<and> b < m \<and> [a = b] (mod m))"
   319   apply auto
   305   by (auto simp: cong_nat_def) (metis mod_less_divisor mod_mod_trivial)
   320   apply (rule_tac x = "a mod m" in exI)
       
   321   apply (unfold cong_nat_def, auto)
       
   322   done
       
   323 
   306 
   324 lemma cong_less_unique_int:
   307 lemma cong_less_unique_int:
   325     "0 < (m::int) \<Longrightarrow> (\<exists>!b. 0 \<le> b \<and> b < m \<and> [a = b] (mod m))"
   308     "0 < (m::int) \<Longrightarrow> (\<exists>!b. 0 \<le> b \<and> b < m \<and> [a = b] (mod m))"
   326   apply auto
   309   by (auto simp: cong_int_def)  (metis mod_mod_trivial pos_mod_conj)
   327   apply (rule_tac x = "a mod m" in exI)
       
   328   apply (unfold cong_int_def, auto)
       
   329   done
       
   330 
   310 
   331 lemma cong_iff_lin_int: "([(a::int) = b] (mod m)) = (\<exists>k. b = a + m * k)"
   311 lemma cong_iff_lin_int: "([(a::int) = b] (mod m)) = (\<exists>k. b = a + m * k)"
   332   apply (auto simp add: cong_altdef_int dvd_def field_simps)
   312   apply (auto simp add: cong_altdef_int dvd_def)
   333   apply (rule_tac [!] x = "-k" in exI, auto)
   313   apply (rule_tac [!] x = "-k" in exI, auto)
   334   done
   314   done
   335 
   315 
   336 lemma cong_iff_lin_nat: "([(a::nat) = b] (mod m)) =
   316 lemma cong_iff_lin_nat: 
   337     (\<exists>k1 k2. b + k1 * m = a + k2 * m)"
   317    "([(a::nat) = b] (mod m)) \<longleftrightarrow> (\<exists>k1 k2. b + k1 * m = a + k2 * m)" (is "?lhs = ?rhs")
   338   apply (rule iffI)
   318 proof (rule iffI)
   339   apply (cases "b <= a")
   319   assume eqm: ?lhs
   340   apply (subst (asm) cong_altdef_nat, assumption)
   320   show ?rhs
   341   apply (unfold dvd_def, auto)
   321   proof (cases "b \<le> a")
   342   apply (rule_tac x = k in exI)
   322     case True
   343   apply (rule_tac x = 0 in exI)
   323     then show ?rhs using eqm
   344   apply (auto simp add: field_simps)
   324       by (metis cong_altdef_nat dvd_def le_add_diff_inverse add_0_right mult_0 mult_commute)
   345   apply (subst (asm) cong_sym_eq_nat)
   325   next
   346   apply (subst (asm) cong_altdef_nat)
   326     case False
   347   apply force
   327     then show ?rhs using eqm 
   348   apply (unfold dvd_def, auto)
   328       apply (subst (asm) cong_sym_eq_nat)
   349   apply (rule_tac x = 0 in exI)
   329       apply (auto simp: cong_altdef_nat)
   350   apply (rule_tac x = k in exI)
   330       apply (metis add_0_right add_diff_inverse dvd_div_mult_self less_or_eq_imp_le mult_0)
   351   apply (auto simp add: field_simps)
   331       done
   352   apply (unfold cong_nat_def)
   332   qed
   353   apply (subgoal_tac "a mod m = (a + k2 * m) mod m")
   333 next
   354   apply (erule ssubst)back
   334   assume ?rhs
   355   apply (erule subst)
   335   then show ?lhs
   356   apply auto
   336     by (metis cong_nat_def mod_mult_self2 nat_mult_commute)
   357   done
   337 qed
   358 
   338 
   359 lemma cong_gcd_eq_int: "[(a::int) = b] (mod m) \<Longrightarrow> gcd a m = gcd b m"
   339 lemma cong_gcd_eq_int: "[(a::int) = b] (mod m) \<Longrightarrow> gcd a m = gcd b m"
   360   apply (subst (asm) cong_iff_lin_int, auto)
   340   by (metis cong_int_def gcd_red_int)
   361   apply (subst add_commute)
       
   362   apply (subst (2) gcd_commute_int)
       
   363   apply (subst mult_commute)
       
   364   apply (subst gcd_add_mult_int)
       
   365   apply (rule gcd_commute_int)
       
   366   done
       
   367 
   341 
   368 lemma cong_gcd_eq_nat:
   342 lemma cong_gcd_eq_nat:
   369   assumes "[(a::nat) = b] (mod m)"
   343     "[(a::nat) = b] (mod m) \<Longrightarrow>gcd a m = gcd b m"
   370   shows "gcd a m = gcd b m"
   344   by (metis assms cong_gcd_eq_int [transferred])
   371   apply (rule cong_gcd_eq_int [transferred])
       
   372   using assms apply auto
       
   373   done
       
   374 
   345 
   375 lemma cong_imp_coprime_nat: "[(a::nat) = b] (mod m) \<Longrightarrow> coprime a m \<Longrightarrow> coprime b m"
   346 lemma cong_imp_coprime_nat: "[(a::nat) = b] (mod m) \<Longrightarrow> coprime a m \<Longrightarrow> coprime b m"
   376   by (auto simp add: cong_gcd_eq_nat)
   347   by (auto simp add: cong_gcd_eq_nat)
   377 
   348 
   378 lemma cong_imp_coprime_int: "[(a::int) = b] (mod m) \<Longrightarrow> coprime a m \<Longrightarrow> coprime b m"
   349 lemma cong_imp_coprime_int: "[(a::int) = b] (mod m) \<Longrightarrow> coprime a m \<Longrightarrow> coprime b m"
   383 
   354 
   384 lemma cong_cong_mod_int: "[(a::int) = b] (mod m) = [a mod m = b mod m] (mod m)"
   355 lemma cong_cong_mod_int: "[(a::int) = b] (mod m) = [a mod m = b mod m] (mod m)"
   385   by (auto simp add: cong_int_def)
   356   by (auto simp add: cong_int_def)
   386 
   357 
   387 lemma cong_minus_int [iff]: "[(a::int) = b] (mod -m) = [a = b] (mod m)"
   358 lemma cong_minus_int [iff]: "[(a::int) = b] (mod -m) = [a = b] (mod m)"
   388   apply (subst (1 2) cong_altdef_int)
   359   by (metis cong_iff_lin_int minus_equation_iff mult_minus_left mult_minus_right)
   389   apply auto
       
   390   done
       
   391 
   360 
   392 (*
   361 (*
   393 lemma mod_dvd_mod_int:
   362 lemma mod_dvd_mod_int:
   394     "0 < (m::int) \<Longrightarrow> m dvd b \<Longrightarrow> (a mod b mod m) = (a mod m)"
   363     "0 < (m::int) \<Longrightarrow> m dvd b \<Longrightarrow> (a mod b mod m) = (a mod m)"
   395   apply (unfold dvd_def, auto)
   364   apply (unfold dvd_def, auto)
   458 lemma mod_mult_cong_nat: "(a::nat) ~= 0 \<Longrightarrow> b ~= 0
   427 lemma mod_mult_cong_nat: "(a::nat) ~= 0 \<Longrightarrow> b ~= 0
   459     \<Longrightarrow> [x mod (a * b) = y] (mod a) \<longleftrightarrow> [x = y] (mod a)"
   428     \<Longrightarrow> [x mod (a * b) = y] (mod a) \<longleftrightarrow> [x = y] (mod a)"
   460   by (simp add: cong_nat_def mod_mult2_eq  mod_add_left_eq)
   429   by (simp add: cong_nat_def mod_mult2_eq  mod_add_left_eq)
   461 
   430 
   462 lemma neg_cong_int: "([(a::int) = b] (mod m)) = ([-a = -b] (mod m))"
   431 lemma neg_cong_int: "([(a::int) = b] (mod m)) = ([-a = -b] (mod m))"
   463   apply (simp add: cong_altdef_int)
   432   by (metis cong_int_def minus_minus zminus_zmod)
   464   apply (subst dvd_minus_iff [symmetric])
       
   465   apply (simp add: field_simps)
       
   466   done
       
   467 
   433 
   468 lemma cong_modulus_neg_int: "([(a::int) = b] (mod m)) = ([a = b] (mod -m))"
   434 lemma cong_modulus_neg_int: "([(a::int) = b] (mod m)) = ([a = b] (mod -m))"
   469   by (auto simp add: cong_altdef_int)
   435   by (auto simp add: cong_altdef_int)
   470 
   436 
   471 lemma mod_mult_cong_int: "(a::int) ~= 0 \<Longrightarrow> b ~= 0
   437 lemma mod_mult_cong_int: "(a::int) ~= 0 \<Longrightarrow> b ~= 0
   472     \<Longrightarrow> [x mod (a * b) = y] (mod a) \<longleftrightarrow> [x = y] (mod a)"
   438     \<Longrightarrow> [x mod (a * b) = y] (mod a) \<longleftrightarrow> [x = y] (mod a)"
   473   apply (cases "b > 0")
   439   apply (cases "b > 0", simp add: cong_int_def mod_mod_cancel mod_add_left_eq)
   474   apply (simp add: cong_int_def mod_mod_cancel mod_add_left_eq)
       
   475   apply (subst (1 2) cong_modulus_neg_int)
   440   apply (subst (1 2) cong_modulus_neg_int)
   476   apply (unfold cong_int_def)
   441   apply (unfold cong_int_def)
   477   apply (subgoal_tac "a * b = (-a * -b)")
   442   apply (subgoal_tac "a * b = (-a * -b)")
   478   apply (erule ssubst)
   443   apply (erule ssubst)
   479   apply (subst zmod_zmult2_eq)
   444   apply (subst zmod_zmult2_eq)
   480   apply (auto simp add: mod_add_left_eq mod_minus_right div_minus_right)
   445   apply (auto simp add: mod_add_left_eq mod_minus_right div_minus_right)
   481   apply (metis mod_diff_left_eq mod_diff_right_eq mod_mult_self1_is_0 semiring_numeral_div_class.diff_zero)+
   446   apply (metis mod_diff_left_eq mod_diff_right_eq mod_mult_self1_is_0 semiring_numeral_div_class.diff_zero)+
   482   done
   447   done
   483 
   448 
   484 lemma cong_to_1_nat: "([(a::nat) = 1] (mod n)) \<Longrightarrow> (n dvd (a - 1))"
   449 lemma cong_to_1_nat: "([(a::nat) = 1] (mod n)) \<Longrightarrow> (n dvd (a - 1))"
   485   apply (cases "a = 0")
   450   apply (cases "a = 0", force)
   486   apply force
   451   by (metis cong_altdef_nat leI less_one)
   487   apply (subst (asm) cong_altdef_nat)
       
   488   apply auto
       
   489   done
       
   490 
   452 
   491 lemma cong_0_1_nat': "[(0::nat) = Suc 0] (mod n) = (n = Suc 0)"
   453 lemma cong_0_1_nat': "[(0::nat) = Suc 0] (mod n) = (n = Suc 0)"
   492   unfolding cong_nat_def by auto
   454   unfolding cong_nat_def by auto
   493 
   455 
   494 lemma cong_0_1_nat: "[(0::nat) = 1] (mod n) = (n = 1)"
   456 lemma cong_0_1_nat: "[(0::nat) = 1] (mod n) = (n = 1)"
   501     a = 0 \<and> n = 1 \<or> (\<exists>m. a = 1 + m * n)"
   463     a = 0 \<and> n = 1 \<or> (\<exists>m. a = 1 + m * n)"
   502   apply (cases "n = 1")
   464   apply (cases "n = 1")
   503   apply auto [1]
   465   apply auto [1]
   504   apply (drule_tac x = "a - 1" in spec)
   466   apply (drule_tac x = "a - 1" in spec)
   505   apply force
   467   apply force
   506   apply (cases "a = 0")
   468   apply (cases "a = 0", simp add: cong_0_1_nat)
   507   apply (metis add_is_0 cong_0_1_nat zero_neq_one)
       
   508   apply (rule iffI)
   469   apply (rule iffI)
   509   apply (drule cong_to_1_nat)
   470   apply (metis cong_to_1_nat dvd_def monoid_mult_class.mult.right_neutral mult_commute mult_eq_if)
   510   apply (unfold dvd_def)
   471   apply (metis cong_add_lcancel_0_nat cong_mult_self_nat)
   511   apply auto [1]
       
   512   apply (rule_tac x = k in exI)
       
   513   apply (auto simp add: field_simps) [1]
       
   514   apply (subst cong_altdef_nat)
       
   515   apply (auto simp add: dvd_def)
       
   516   done
   472   done
   517 
   473 
   518 lemma cong_le_nat: "(y::nat) <= x \<Longrightarrow> [x = y] (mod n) \<longleftrightarrow> (\<exists>q. x = q * n + y)"
   474 lemma cong_le_nat: "(y::nat) <= x \<Longrightarrow> [x = y] (mod n) \<longleftrightarrow> (\<exists>q. x = q * n + y)"
   519   apply (subst cong_altdef_nat)
   475   by (metis cong_altdef_nat Nat.le_imp_diff_is_add dvd_def nat_mult_commute)
   520   apply assumption
       
   521   apply (unfold dvd_def, auto simp add: field_simps)
       
   522   apply (rule_tac x = k in exI)
       
   523   apply auto
       
   524   done
       
   525 
   476 
   526 lemma cong_solve_nat: "(a::nat) \<noteq> 0 \<Longrightarrow> EX x. [a * x = gcd a n] (mod n)"
   477 lemma cong_solve_nat: "(a::nat) \<noteq> 0 \<Longrightarrow> EX x. [a * x = gcd a n] (mod n)"
   527   apply (cases "n = 0")
   478   apply (cases "n = 0")
   528   apply force
   479   apply force
   529   apply (frule bezout_nat [of a n], auto)
   480   apply (frule bezout_nat [of a n], auto)
   530   apply (rule exI, erule ssubst)
   481   by (metis cong_add_rcancel_0_nat cong_mult_self_nat mult_commute)
   531   apply (rule cong_trans_nat)
       
   532   apply (rule cong_add_nat)
       
   533   apply (subst mult_commute)
       
   534   apply (rule cong_mult_self_nat)
       
   535   prefer 2
       
   536   apply simp
       
   537   apply (rule cong_refl_nat)
       
   538   apply (rule cong_refl_nat)
       
   539   done
       
   540 
   482 
   541 lemma cong_solve_int: "(a::int) \<noteq> 0 \<Longrightarrow> EX x. [a * x = gcd a n] (mod n)"
   483 lemma cong_solve_int: "(a::int) \<noteq> 0 \<Longrightarrow> EX x. [a * x = gcd a n] (mod n)"
   542   apply (cases "n = 0")
   484   apply (cases "n = 0")
   543   apply (cases "a \<ge> 0")
   485   apply (cases "a \<ge> 0")
   544   apply auto
   486   apply auto
   545   apply (rule_tac x = "-1" in exI)
   487   apply (rule_tac x = "-1" in exI)
   546   apply auto
   488   apply auto
   547   apply (insert bezout_int [of a n], auto)
   489   apply (insert bezout_int [of a n], auto)
   548   apply (rule exI)
   490   by (metis cong_iff_lin_int mult_commute)
   549   apply (erule subst)
       
   550   apply (rule cong_trans_int)
       
   551   prefer 2
       
   552   apply (rule cong_add_int)
       
   553   apply (rule cong_refl_int)
       
   554   apply (rule cong_sym_int)
       
   555   apply (rule cong_mult_self_int)
       
   556   apply simp
       
   557   apply (subst mult_commute)
       
   558   apply (rule cong_refl_int)
       
   559   done
       
   560 
   491 
   561 lemma cong_solve_dvd_nat:
   492 lemma cong_solve_dvd_nat:
   562   assumes a: "(a::nat) \<noteq> 0" and b: "gcd a n dvd d"
   493   assumes a: "(a::nat) \<noteq> 0" and b: "gcd a n dvd d"
   563   shows "EX x. [a * x = d] (mod n)"
   494   shows "EX x. [a * x = d] (mod n)"
   564 proof -
   495 proof -
   619 lemma coprime_iff_invertible'_nat: "m > 0 \<Longrightarrow> coprime a m =
   550 lemma coprime_iff_invertible'_nat: "m > 0 \<Longrightarrow> coprime a m =
   620     (EX x. 0 \<le> x & x < m & [a * x = Suc 0] (mod m))"
   551     (EX x. 0 \<le> x & x < m & [a * x = Suc 0] (mod m))"
   621   apply (subst coprime_iff_invertible_nat)
   552   apply (subst coprime_iff_invertible_nat)
   622   apply auto
   553   apply auto
   623   apply (auto simp add: cong_nat_def)
   554   apply (auto simp add: cong_nat_def)
   624   apply (rule_tac x = "x mod m" in exI)
       
   625   apply (metis mod_less_divisor mod_mult_right_eq)
   555   apply (metis mod_less_divisor mod_mult_right_eq)
   626   done
   556   done
   627 
   557 
   628 lemma coprime_iff_invertible'_int: "m > (0::int) \<Longrightarrow> coprime a m =
   558 lemma coprime_iff_invertible'_int: "m > (0::int) \<Longrightarrow> coprime a m =
   629     (EX x. 0 <= x & x < m & [a * x = 1] (mod m))"
   559     (EX x. 0 <= x & x < m & [a * x = 1] (mod m))"
   630   apply (subst coprime_iff_invertible_int)
   560   apply (subst coprime_iff_invertible_int)
   631   apply auto
       
   632   apply (auto simp add: cong_int_def)
   561   apply (auto simp add: cong_int_def)
   633   apply (rule_tac x = "x mod m" in exI)
   562   apply (metis mod_mult_right_eq pos_mod_conj)
   634   apply (auto simp add: mod_mult_right_eq [symmetric])
       
   635   done
   563   done
   636 
   564 
   637 lemma cong_cong_lcm_nat: "[(x::nat) = y] (mod a) \<Longrightarrow>
   565 lemma cong_cong_lcm_nat: "[(x::nat) = y] (mod a) \<Longrightarrow>
   638     [x = y] (mod b) \<Longrightarrow> [x = y] (mod lcm a b)"
   566     [x = y] (mod b) \<Longrightarrow> [x = y] (mod lcm a b)"
   639   apply (cases "y \<le> x")
   567   apply (cases "y \<le> x")
   640   apply (auto simp add: cong_altdef_nat lcm_least_nat) [1]
   568   apply (metis cong_altdef_nat lcm_least_nat)
   641   apply (rule cong_sym_nat)
   569   apply (metis cong_altdef_nat cong_diff_cong_0'_nat lcm_semilattice_nat.sup.bounded_iff le0 minus_nat.diff_0)
   642   apply (subst (asm) (1 2) cong_sym_eq_nat)
       
   643   apply (auto simp add: cong_altdef_nat lcm_least_nat)
       
   644   done
   570   done
   645 
   571 
   646 lemma cong_cong_lcm_int: "[(x::int) = y] (mod a) \<Longrightarrow>
   572 lemma cong_cong_lcm_int: "[(x::int) = y] (mod a) \<Longrightarrow>
   647     [x = y] (mod b) \<Longrightarrow> [x = y] (mod lcm a b)"
   573     [x = y] (mod b) \<Longrightarrow> [x = y] (mod lcm a b)"
   648   by (auto simp add: cong_altdef_int lcm_least_int) [1]
   574   by (auto simp add: cong_altdef_int lcm_least_int) [1]
   649 
       
   650 lemma cong_cong_coprime_nat: "coprime a b \<Longrightarrow> [(x::nat) = y] (mod a) \<Longrightarrow>
       
   651     [x = y] (mod b) \<Longrightarrow> [x = y] (mod a * b)"
       
   652   apply (frule (1) cong_cong_lcm_nat)
       
   653   back
       
   654   apply (simp add: lcm_nat_def)
       
   655   done
       
   656 
       
   657 lemma cong_cong_coprime_int: "coprime a b \<Longrightarrow> [(x::int) = y] (mod a) \<Longrightarrow>
       
   658     [x = y] (mod b) \<Longrightarrow> [x = y] (mod a * b)"
       
   659   apply (frule (1) cong_cong_lcm_int)
       
   660   back
       
   661   apply (simp add: lcm_altdef_int cong_abs_int abs_mult [symmetric])
       
   662   done
       
   663 
   575 
   664 lemma cong_cong_setprod_coprime_nat [rule_format]: "finite A \<Longrightarrow>
   576 lemma cong_cong_setprod_coprime_nat [rule_format]: "finite A \<Longrightarrow>
   665     (ALL i:A. (ALL j:A. i \<noteq> j \<longrightarrow> coprime (m i) (m j))) \<longrightarrow>
   577     (ALL i:A. (ALL j:A. i \<noteq> j \<longrightarrow> coprime (m i) (m j))) \<longrightarrow>
   666     (ALL i:A. [(x::nat) = y] (mod m i)) \<longrightarrow>
   578     (ALL i:A. [(x::nat) = y] (mod m i)) \<longrightarrow>
   667       [x = y] (mod (PROD i:A. m i))"
   579       [x = y] (mod (PROD i:A. m i))"
   668   apply (induct set: finite)
   580   apply (induct set: finite)
   669   apply auto
   581   apply auto
   670   apply (rule cong_cong_coprime_nat)
   582   apply (metis coprime_cong_mult_nat gcd_semilattice_nat.inf_commute setprod_coprime_nat)
   671   apply (subst gcd_commute_nat)
       
   672   apply (rule setprod_coprime_nat)
       
   673   apply auto
       
   674   done
   583   done
   675 
   584 
   676 lemma cong_cong_setprod_coprime_int [rule_format]: "finite A \<Longrightarrow>
   585 lemma cong_cong_setprod_coprime_int [rule_format]: "finite A \<Longrightarrow>
   677     (ALL i:A. (ALL j:A. i \<noteq> j \<longrightarrow> coprime (m i) (m j))) \<longrightarrow>
   586     (ALL i:A. (ALL j:A. i \<noteq> j \<longrightarrow> coprime (m i) (m j))) \<longrightarrow>
   678     (ALL i:A. [(x::int) = y] (mod m i)) \<longrightarrow>
   587     (ALL i:A. [(x::int) = y] (mod m i)) \<longrightarrow>
   679       [x = y] (mod (PROD i:A. m i))"
   588       [x = y] (mod (PROD i:A. m i))"
   680   apply (induct set: finite)
   589   apply (induct set: finite)
   681   apply auto
   590   apply auto
   682   apply (rule cong_cong_coprime_int)
   591   apply (metis coprime_cong_mult_int gcd_int.commute setprod_coprime_int)
   683   apply (subst gcd_commute_int)
       
   684   apply (rule setprod_coprime_int)
       
   685   apply auto
       
   686   done
   592   done
   687 
   593 
   688 lemma binary_chinese_remainder_aux_nat:
   594 lemma binary_chinese_remainder_aux_nat:
   689   assumes a: "coprime (m1::nat) m2"
   595   assumes a: "coprime (m1::nat) m2"
   690   shows "EX b1 b2. [b1 = 1] (mod m1) \<and> [b1 = 0] (mod m2) \<and>
   596   shows "EX b1 b2. [b1 = 1] (mod m1) \<and> [b1 = 0] (mod m2) \<and>
   927     (ALL i: A. (ALL j: A. i \<noteq> j \<longrightarrow> coprime (m i) (m j))) \<longrightarrow>
   833     (ALL i: A. (ALL j: A. i \<noteq> j \<longrightarrow> coprime (m i) (m j))) \<longrightarrow>
   928       (ALL i: A. [(x::nat) = y] (mod m i)) \<longrightarrow>
   834       (ALL i: A. [(x::nat) = y] (mod m i)) \<longrightarrow>
   929          [x = y] (mod (PROD i:A. m i))"
   835          [x = y] (mod (PROD i:A. m i))"
   930   apply (induct set: finite)
   836   apply (induct set: finite)
   931   apply auto
   837   apply auto
   932   apply (erule (1) coprime_cong_mult_nat)
   838   apply (metis coprime_cong_mult_nat nat_mult_commute setprod_coprime_nat)
   933   apply (subst gcd_commute_nat)
       
   934   apply (rule setprod_coprime_nat)
       
   935   apply auto
       
   936   done
   839   done
   937 
   840 
   938 lemma chinese_remainder_unique_nat:
   841 lemma chinese_remainder_unique_nat:
   939   fixes A :: "'a set"
   842   fixes A :: "'a set"
   940     and m :: "'a \<Rightarrow> nat"
   843     and m :: "'a \<Rightarrow> nat"