src/HOL/Number_Theory/Cong.thy
changeset 67085 f5d7f37b4143
parent 67051 e7e54a0b9197
child 67086 59d07a95be0e
equal deleted inserted replaced
67084:e138d96ed083 67085:f5d7f37b4143
    41   where "cong b c a \<longleftrightarrow> b mod a = c mod a"
    41   where "cong b c a \<longleftrightarrow> b mod a = c mod a"
    42   
    42   
    43 abbreviation notcong :: "'a \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> bool"  ("(1[_ \<noteq> _] '(()mod _'))")
    43 abbreviation notcong :: "'a \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> bool"  ("(1[_ \<noteq> _] '(()mod _'))")
    44   where "notcong b c a \<equiv> \<not> cong b c a"
    44   where "notcong b c a \<equiv> \<not> cong b c a"
    45 
    45 
       
    46 lemma cong_refl [simp]:
       
    47   "[b = b] (mod a)"
       
    48   by (simp add: cong_def)
       
    49 
       
    50 lemma cong_sym: 
       
    51   "[b = c] (mod a) \<Longrightarrow> [c = b] (mod a)"
       
    52   by (simp add: cong_def)
       
    53 
       
    54 lemma cong_sym_eq:
       
    55   "[b = c] (mod a) \<longleftrightarrow> [c = b] (mod a)"
       
    56   by (auto simp add: cong_def)
       
    57 
       
    58 lemma cong_trans [trans]:
       
    59   "[b = c] (mod a) \<Longrightarrow> [c = d] (mod a) \<Longrightarrow> [b = d] (mod a)"
       
    60   by (simp add: cong_def)
       
    61 
       
    62 lemma cong_mult_self_right:
       
    63   "[b * a = 0] (mod a)"
       
    64   by (simp add: cong_def)
       
    65 
       
    66 lemma cong_mult_self_left:
       
    67   "[a * b = 0] (mod a)"
       
    68   by (simp add: cong_def)
       
    69 
    46 lemma cong_mod_left [simp]:
    70 lemma cong_mod_left [simp]:
    47   "[b mod a = c] (mod a) \<longleftrightarrow> [b = c] (mod a)"
    71   "[b mod a = c] (mod a) \<longleftrightarrow> [b = c] (mod a)"
    48   by (simp add: cong_def)  
    72   by (simp add: cong_def)  
    49 
    73 
    50 lemma cong_mod_right [simp]:
    74 lemma cong_mod_right [simp]:
    51   "[b = c mod a] (mod a) \<longleftrightarrow> [b = c] (mod a)"
    75   "[b = c mod a] (mod a) \<longleftrightarrow> [b = c] (mod a)"
    52   by (simp add: cong_def)  
    76   by (simp add: cong_def)  
    53 
    77 
       
    78 lemma cong_0 [simp, presburger]:
       
    79   "[b = c] (mod 0) \<longleftrightarrow> b = c"
       
    80   by (simp add: cong_def)
       
    81 
       
    82 lemma cong_1 [simp, presburger]:
       
    83   "[b = c] (mod 1)"
       
    84   by (simp add: cong_def)
       
    85 
    54 lemma cong_dvd_iff:
    86 lemma cong_dvd_iff:
    55   "a dvd b \<longleftrightarrow> a dvd c" if "[b = c] (mod a)"
    87   "a dvd b \<longleftrightarrow> a dvd c" if "[b = c] (mod a)"
    56   using that by (auto simp: cong_def dvd_eq_mod_eq_0)
    88   using that by (auto simp: cong_def dvd_eq_mod_eq_0)
    57 
    89 
    58 lemma cong_0 [simp, presburger]:
    90 lemma cong_0_iff: "[b = 0] (mod a) \<longleftrightarrow> a dvd b"
    59   "[b = c] (mod 0) \<longleftrightarrow> b = c"
    91   by (simp add: cong_def dvd_eq_mod_eq_0)
    60   by (simp add: cong_def)
       
    61 
       
    62 lemma cong_1 [simp, presburger]:
       
    63   "[b = c] (mod 1)"
       
    64   by (simp add: cong_def)
       
    65 
       
    66 lemma cong_refl [simp]:
       
    67   "[b = b] (mod a)"
       
    68   by (simp add: cong_def)
       
    69 
       
    70 lemma cong_sym: 
       
    71   "[b = c] (mod a) \<Longrightarrow> [c = b] (mod a)"
       
    72   by (simp add: cong_def)
       
    73 
       
    74 lemma cong_sym_eq:
       
    75   "[b = c] (mod a) \<longleftrightarrow> [c = b] (mod a)"
       
    76   by (auto simp add: cong_def)
       
    77 
       
    78 lemma cong_trans [trans]:
       
    79   "[b = c] (mod a) \<Longrightarrow> [c = d] (mod a) \<Longrightarrow> [b = d] (mod a)"
       
    80   by (simp add: cong_def)
       
    81 
    92 
    82 lemma cong_add:
    93 lemma cong_add:
    83   "[b = c] (mod a) \<Longrightarrow> [d = e] (mod a) \<Longrightarrow> [b + d = c + e] (mod a)"
    94   "[b = c] (mod a) \<Longrightarrow> [d = e] (mod a) \<Longrightarrow> [b + d = c + e] (mod a)"
    84   by (auto simp add: cong_def intro: mod_add_cong)
    95   by (auto simp add: cong_def intro: mod_add_cong)
    85 
    96 
    86 lemma cong_mult:
    97 lemma cong_mult:
    87   "[b = c] (mod a) \<Longrightarrow> [d = e] (mod a) \<Longrightarrow> [b * d = c * e] (mod a)"
    98   "[b = c] (mod a) \<Longrightarrow> [d = e] (mod a) \<Longrightarrow> [b * d = c * e] (mod a)"
    88   by (auto simp add: cong_def intro: mod_mult_cong)
    99   by (auto simp add: cong_def intro: mod_mult_cong)
    89 
   100 
       
   101 lemma cong_scalar_right:
       
   102   "[b = c] (mod a) \<Longrightarrow> [b * d = c * d] (mod a)"
       
   103   by (simp add: cong_mult)
       
   104 
       
   105 lemma cong_scalar_left:
       
   106   "[b = c] (mod a) \<Longrightarrow> [d * b = d * c] (mod a)"
       
   107   by (simp add: cong_mult)
       
   108 
    90 lemma cong_pow:
   109 lemma cong_pow:
    91   "[b = c] (mod a) \<Longrightarrow> [b ^ n = c ^ n] (mod a)"
   110   "[b = c] (mod a) \<Longrightarrow> [b ^ n = c ^ n] (mod a)"
    92   by (simp add: cong_def power_mod [symmetric, of b n a] power_mod [symmetric, of c n a])
   111   by (simp add: cong_def power_mod [symmetric, of b n a] power_mod [symmetric, of c n a])
    93 
   112 
    94 lemma cong_sum:
   113 lemma cong_sum:
    96   using that by (induct A rule: infinite_finite_induct) (auto intro: cong_add)
   115   using that by (induct A rule: infinite_finite_induct) (auto intro: cong_add)
    97 
   116 
    98 lemma cong_prod:
   117 lemma cong_prod:
    99   "[prod f A = prod g A] (mod a)" if "(\<And>x. x \<in> A \<Longrightarrow> [f x = g x] (mod a))"
   118   "[prod f A = prod g A] (mod a)" if "(\<And>x. x \<in> A \<Longrightarrow> [f x = g x] (mod a))"
   100   using that by (induct A rule: infinite_finite_induct) (auto intro: cong_mult)
   119   using that by (induct A rule: infinite_finite_induct) (auto intro: cong_mult)
   101 
       
   102 lemma cong_scalar_right:
       
   103   "[b = c] (mod a) \<Longrightarrow> [b * d = c * d] (mod a)"
       
   104   by (simp add: cong_mult)
       
   105 
       
   106 lemma cong_scalar_left:
       
   107   "[b = c] (mod a) \<Longrightarrow> [d * b = d * c] (mod a)"
       
   108   by (simp add: cong_mult)
       
   109 
       
   110 lemma cong_mult_self_right: "[b * a = 0] (mod a)"
       
   111   by (simp add: cong_def)
       
   112 
       
   113 lemma cong_mult_self_left: "[a * b = 0] (mod a)"
       
   114   by (simp add: cong_def)
       
   115 
       
   116 lemma cong_0_iff: "[b = 0] (mod a) \<longleftrightarrow> a dvd b"
       
   117   by (simp add: cong_def dvd_eq_mod_eq_0)
       
   118 
   120 
   119 lemma mod_mult_cong_right:
   121 lemma mod_mult_cong_right:
   120   "[c mod (a * b) = d] (mod a) \<longleftrightarrow> [c = d] (mod a)"
   122   "[c mod (a * b) = d] (mod a) \<longleftrightarrow> [c = d] (mod a)"
   121   by (simp add: cong_def mod_mod_cancel mod_add_left_eq)
   123   by (simp add: cong_def mod_mod_cancel mod_add_left_eq)
   122 
   124 
   205   for a b :: nat
   207   for a b :: nat
   206   by (simp add: cong_0_iff [symmetric] cong_diff_iff_cong_0_nat)
   208   by (simp add: cong_0_iff [symmetric] cong_diff_iff_cong_0_nat)
   207 
   209 
   208 lemma cong_altdef_nat':
   210 lemma cong_altdef_nat':
   209   "[a = b] (mod m) \<longleftrightarrow> m dvd nat \<bar>int a - int b\<bar>"
   211   "[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')
   212   using cong_diff_iff_cong_0_nat' [of a b m]
       
   213   by (simp only: cong_0_iff [symmetric])
   211 
   214 
   212 lemma cong_altdef_int:
   215 lemma cong_altdef_int:
   213   "[a = b] (mod m) \<longleftrightarrow> m dvd (a - b)"
   216   "[a = b] (mod m) \<longleftrightarrow> m dvd (a - b)"
   214   for a b :: int
   217   for a b :: int
   215   by (simp add: cong_0_iff [symmetric] cong_diff_iff_cong_0)
   218   by (simp add: cong_0_iff [symmetric] cong_diff_iff_cong_0)
   216 
   219 
   217 lemma cong_abs_int [simp]: "[x = y] (mod abs m) \<longleftrightarrow> [x = y] (mod m)"
   220 lemma cong_abs_int [simp]: "[x = y] (mod \<bar>m\<bar>) \<longleftrightarrow> [x = y] (mod m)"
   218   for x y :: int
   221   for x y :: int
   219   by (simp add: cong_altdef_int)
   222   by (simp add: cong_altdef_int)
   220 
   223 
   221 lemma cong_square_int:
   224 lemma cong_square_int:
   222   "prime p \<Longrightarrow> 0 < a \<Longrightarrow> [a * a = 1] (mod p) \<Longrightarrow> [a = 1] (mod p) \<or> [a = - 1] (mod p)"
   225   "prime p \<Longrightarrow> 0 < a \<Longrightarrow> [a * a = 1] (mod p) \<Longrightarrow> [a = 1] (mod p) \<or> [a = - 1] (mod p)"
   319   for a b :: int
   322   for a b :: int
   320   by (auto simp add: cong_def) (metis gcd_red_int)
   323   by (auto simp add: cong_def) (metis gcd_red_int)
   321 
   324 
   322 lemma cong_imp_coprime_nat: "[a = b] (mod m) \<Longrightarrow> coprime a m \<Longrightarrow> coprime b m"
   325 lemma cong_imp_coprime_nat: "[a = b] (mod m) \<Longrightarrow> coprime a m \<Longrightarrow> coprime b m"
   323   for a b :: nat
   326   for a b :: nat
   324   by (auto simp add: cong_gcd_eq_nat coprime_iff_gcd_eq_1)
   327   by (auto simp add: coprime_iff_gcd_eq_1 dest: cong_gcd_eq_nat)
   325 
   328 
   326 lemma cong_imp_coprime_int: "[a = b] (mod m) \<Longrightarrow> coprime a m \<Longrightarrow> coprime b m"
   329 lemma cong_imp_coprime_int: "[a = b] (mod m) \<Longrightarrow> coprime a m \<Longrightarrow> coprime b m"
   327   for a b :: int
   330   for a b :: int
   328   by (auto simp add: cong_gcd_eq_int coprime_iff_gcd_eq_1)
   331   by (auto simp add: coprime_iff_gcd_eq_1 dest: cong_gcd_eq_int)
   329 
   332 
   330 lemma cong_cong_mod_nat: "[a = b] (mod m) \<longleftrightarrow> [a mod m = b mod m] (mod m)"
   333 lemma cong_cong_mod_nat: "[a = b] (mod m) \<longleftrightarrow> [a mod m = b mod m] (mod m)"
   331   for a b :: nat
   334   for a b :: nat
   332   by simp
   335   by simp
   333 
   336 
   337 
   340 
   338 lemma cong_minus_int [iff]: "[a = b] (mod - m) \<longleftrightarrow> [a = b] (mod m)"
   341 lemma cong_minus_int [iff]: "[a = b] (mod - m) \<longleftrightarrow> [a = b] (mod m)"
   339   for a b :: int
   342   for a b :: int
   340   by (metis cong_iff_lin_int minus_equation_iff mult_minus_left mult_minus_right)
   343   by (metis cong_iff_lin_int minus_equation_iff mult_minus_left mult_minus_right)
   341 
   344 
   342 (*
       
   343 lemma mod_dvd_mod_int:
       
   344     "0 < (m::int) \<Longrightarrow> m dvd b \<Longrightarrow> (a mod b mod m) = (a mod m)"
       
   345   apply (unfold dvd_def, auto)
       
   346   apply (rule mod_mod_cancel)
       
   347   apply auto
       
   348   done
       
   349 
       
   350 lemma mod_dvd_mod:
       
   351   assumes "0 < (m::nat)" and "m dvd b"
       
   352   shows "(a mod b mod m) = (a mod m)"
       
   353 
       
   354   apply (rule mod_dvd_mod_int [transferred])
       
   355   using assms apply auto
       
   356   done
       
   357 *)
       
   358 
       
   359 lemma cong_add_lcancel_nat: "[a + x = a + y] (mod n) \<longleftrightarrow> [x = y] (mod n)"
   345 lemma cong_add_lcancel_nat: "[a + x = a + y] (mod n) \<longleftrightarrow> [x = y] (mod n)"
   360   for a x y :: nat
   346   for a x y :: nat
   361   by (simp add: cong_iff_lin_nat)
   347   by (simp add: cong_iff_lin_nat)
   362 
   348 
   363 lemma cong_add_lcancel_int: "[a + x = a + y] (mod n) \<longleftrightarrow> [x = y] (mod n)"
   349 lemma cong_add_lcancel_int: "[a + x = a + y] (mod n) \<longleftrightarrow> [x = y] (mod n)"
   372   for a x y :: int
   358   for a x y :: int
   373   by (simp add: cong_iff_lin_int)
   359   by (simp add: cong_iff_lin_int)
   374 
   360 
   375 lemma cong_add_lcancel_0_nat: "[a + x = a] (mod n) \<longleftrightarrow> [x = 0] (mod n)"
   361 lemma cong_add_lcancel_0_nat: "[a + x = a] (mod n) \<longleftrightarrow> [x = 0] (mod n)"
   376   for a x :: nat
   362   for a x :: nat
   377   by (simp add: cong_iff_lin_nat)
   363   using cong_add_lcancel_nat [of a x 0 n] by simp
   378 
   364 
   379 lemma cong_add_lcancel_0_int: "[a + x = a] (mod n) \<longleftrightarrow> [x = 0] (mod n)"
   365 lemma cong_add_lcancel_0_int: "[a + x = a] (mod n) \<longleftrightarrow> [x = 0] (mod n)"
   380   for a x :: int
   366   for a x :: int
   381   by (simp add: cong_iff_lin_int)
   367   using cong_add_lcancel_int [of a x 0 n] by simp
   382 
   368 
   383 lemma cong_add_rcancel_0_nat: "[x + a = a] (mod n) \<longleftrightarrow> [x = 0] (mod n)"
   369 lemma cong_add_rcancel_0_nat: "[x + a = a] (mod n) \<longleftrightarrow> [x = 0] (mod n)"
   384   for a x :: nat
   370   for a x :: nat
   385   by (simp add: cong_iff_lin_nat)
   371   using cong_add_rcancel_nat [of x a 0 n] by simp
   386 
   372 
   387 lemma cong_add_rcancel_0_int: "[x + a = a] (mod n) \<longleftrightarrow> [x = 0] (mod n)"
   373 lemma cong_add_rcancel_0_int: "[x + a = a] (mod n) \<longleftrightarrow> [x = 0] (mod n)"
   388   for a x :: int
   374   for a x :: int
   389   by (simp add: cong_iff_lin_int)
   375   using cong_add_rcancel_int [of x a 0 n] by simp
   390 
   376 
   391 lemma cong_dvd_modulus_nat: "[x = y] (mod m) \<Longrightarrow> n dvd m \<Longrightarrow> [x = y] (mod n)"
   377 lemma cong_dvd_modulus_nat: "[x = y] (mod m) \<Longrightarrow> n dvd m \<Longrightarrow> [x = y] (mod n)"
   392   for x y :: nat
   378   for x y :: nat
   393   apply (auto simp add: cong_iff_lin_nat dvd_def)
   379   apply (auto simp add: cong_iff_lin_nat dvd_def)
   394   apply (rule_tac x= "k1 * k" in exI)
   380   apply (rule_tac x= "k1 * k" in exI)
   498   "\<exists>x. [a * x = 1] (mod n)" if "coprime a n" for a n x :: int
   484   "\<exists>x. [a * x = 1] (mod n)" if "coprime a n" for a n x :: int
   499   using that cong_solve_int [of a n] by (cases "a = 0")
   485   using that cong_solve_int [of a n] by (cases "a = 0")
   500     (auto simp add: zabs_def split: if_splits)
   486     (auto simp add: zabs_def split: if_splits)
   501 
   487 
   502 lemma coprime_iff_invertible_nat:
   488 lemma coprime_iff_invertible_nat:
   503   "m > 0 \<Longrightarrow> coprime a m \<longleftrightarrow> (\<exists>x. [a * x = Suc 0] (mod m))"
   489   "coprime a m \<longleftrightarrow> (\<exists>x. [a * x = Suc 0] (mod m))" (is "?P \<longleftrightarrow> ?Q")
   504   by (auto intro: cong_solve_coprime_nat)
   490 proof
   505     (use cong_imp_coprime_nat cong_sym coprime_Suc_0_left coprime_mult_left_iff in blast)
   491   assume ?P then show ?Q
       
   492     by (auto dest!: cong_solve_coprime_nat)
       
   493 next
       
   494   assume ?Q
       
   495   then obtain b where "[a * b = Suc 0] (mod m)"
       
   496     by blast
       
   497   with coprime_mod_left_iff [of m "a * b"] show ?P
       
   498     by (cases "m = 0 \<or> m = 1")
       
   499       (unfold cong_def, auto simp add: cong_def)
       
   500 qed
   506 
   501 
   507 lemma coprime_iff_invertible_int:
   502 lemma coprime_iff_invertible_int:
   508   "m > 0 \<Longrightarrow> coprime a m \<longleftrightarrow> (\<exists>x. [a * x = 1] (mod m))"
   503   "coprime a m \<longleftrightarrow> (\<exists>x. [a * x = 1] (mod m))" (is "?P \<longleftrightarrow> ?Q") for m :: int
   509   for m :: int
   504 proof
   510   by (auto intro: cong_solve_coprime_int)
   505   assume ?P then show ?Q
   511     (meson cong_imp_coprime_int cong_sym coprime_1_left coprime_mult_left_iff)
   506     by (auto dest: cong_solve_coprime_int)
       
   507 next
       
   508   assume ?Q
       
   509   then obtain b where "[a * b = 1] (mod m)"
       
   510     by blast
       
   511   with coprime_mod_left_iff [of m "a * b"] show ?P
       
   512     by (cases "m = 0 \<or> m = 1")
       
   513       (unfold cong_def, auto simp add: zmult_eq_1_iff)
       
   514 qed
   512 
   515 
   513 lemma coprime_iff_invertible'_nat:
   516 lemma coprime_iff_invertible'_nat:
   514   "m > 0 \<Longrightarrow> coprime a m \<longleftrightarrow> (\<exists>x. 0 \<le> x \<and> x < m \<and> [a * x = Suc 0] (mod m))"
   517   "m > 0 \<Longrightarrow> coprime a m \<longleftrightarrow> (\<exists>x. 0 \<le> x \<and> x < m \<and> [a * x = Suc 0] (mod m))"
   515   apply (subst coprime_iff_invertible_nat)
   518   apply (subst coprime_iff_invertible_nat)
   516    apply auto
   519    apply auto
   635 qed
   638 qed
   636 
   639 
   637 lemma cong_modulus_mult_nat: "[x = y] (mod m * n) \<Longrightarrow> [x = y] (mod m)"
   640 lemma cong_modulus_mult_nat: "[x = y] (mod m * n) \<Longrightarrow> [x = y] (mod m)"
   638   for x y :: nat
   641   for x y :: nat
   639   apply (cases "y \<le> x")
   642   apply (cases "y \<le> x")
   640    apply (simp add: cong_altdef_nat)
   643    apply (auto simp add: cong_altdef_nat elim: dvd_mult_left)
   641    apply (erule dvd_mult_left)
   644   apply (metis cong_def mod_mult_cong_right)
   642   apply (rule cong_sym)
       
   643   apply (subst (asm) cong_sym_eq)
       
   644   apply (simp add: cong_altdef_nat)
       
   645   apply (erule dvd_mult_left)
       
   646   done
   645   done
   647 
   646 
   648 lemma cong_modulus_mult_int: "[x = y] (mod m * n) \<Longrightarrow> [x = y] (mod m)"
   647 lemma cong_modulus_mult_int: "[x = y] (mod m * n) \<Longrightarrow> [x = y] (mod m)"
   649   for x y :: int
   648   for x y :: int
   650   apply (simp add: cong_altdef_int)
   649   apply (simp add: cong_altdef_int)
   700       apply (rule \<open>[z = u2] (mod m2)\<close>)
   699       apply (rule \<open>[z = u2] (mod m2)\<close>)
   701       done
   700       done
   702     ultimately have "[?x = z] (mod m1 * m2)"
   701     ultimately have "[?x = z] (mod m1 * m2)"
   703       using a by (auto intro: coprime_cong_mult_nat simp add: mod_mult_cong_left mod_mult_cong_right)
   702       using a by (auto intro: coprime_cong_mult_nat simp add: mod_mult_cong_left mod_mult_cong_right)
   704     with \<open>z < m1 * m2\<close> \<open>?x < m1 * m2\<close> show "z = ?x"
   703     with \<open>z < m1 * m2\<close> \<open>?x < m1 * m2\<close> show "z = ?x"
   705       apply (intro cong_less_modulus_unique_nat)
   704       by (auto simp add: cong_def)
   706         apply (auto, erule cong_sym)
       
   707       done
       
   708   qed
   705   qed
   709   with less 1 2 show ?thesis by auto
   706   with less 1 2 show ?thesis by auto
   710  qed
   707  qed
   711 
   708 
   712 lemma chinese_remainder_aux_nat:
   709 lemma chinese_remainder_aux_nat:
   757         apply (rule cong_add)
   754         apply (rule cong_add)
   758          apply (rule cong_scalar_left)
   755          apply (rule cong_scalar_left)
   759         using b a apply blast
   756         using b a apply blast
   760         apply (rule cong_sum)
   757         apply (rule cong_sum)
   761         apply (rule cong_scalar_left)
   758         apply (rule cong_scalar_left)
   762         using b apply auto
   759         using b apply (auto simp add: mod_eq_0_iff_dvd cong_def)
   763         apply (rule cong_dvd_modulus_nat)
   760         apply (rule dvd_trans [of _ "prod m (A - {x})" "b x" for x])
   764          apply (drule (1) bspec)
   761         using a fin apply auto
   765          apply (erule conjE)
       
   766          apply assumption
       
   767         apply rule
       
   768         using fin a apply auto
       
   769         done
   762         done
   770       finally show ?thesis
   763       finally show ?thesis
   771         by simp
   764         by simp
   772     qed
   765     qed
   773   qed
   766   qed
   798   from fin nz have prodnz: "(\<Prod>i\<in>A. m i) \<noteq> 0"
   791   from fin nz have prodnz: "(\<Prod>i\<in>A. m i) \<noteq> 0"
   799     by auto
   792     by auto
   800   then have less: "?x < (\<Prod>i\<in>A. m i)"
   793   then have less: "?x < (\<Prod>i\<in>A. m i)"
   801     by auto
   794     by auto
   802   have cong: "\<forall>i\<in>A. [?x = u i] (mod m i)"
   795   have cong: "\<forall>i\<in>A. [?x = u i] (mod m i)"
   803     apply auto
   796     using fin one
   804     apply (rule cong_trans)
   797     by (auto simp add: cong_def dvd_prod_eqI mod_mod_cancel) 
   805      prefer 2
       
   806     using one apply auto
       
   807     apply (rule cong_dvd_modulus_nat [of _ _ "prod m A"])
       
   808      apply simp
       
   809     using fin apply auto
       
   810     done
       
   811   have unique: "\<forall>z. z < (\<Prod>i\<in>A. m i) \<and> (\<forall>i\<in>A. [z = u i] (mod m i)) \<longrightarrow> z = ?x"
   798   have unique: "\<forall>z. z < (\<Prod>i\<in>A. m i) \<and> (\<forall>i\<in>A. [z = u i] (mod m i)) \<longrightarrow> z = ?x"
   812   proof clarify
   799   proof clarify
   813     fix z
   800     fix z
   814     assume zless: "z < (\<Prod>i\<in>A. m i)"
   801     assume zless: "z < (\<Prod>i\<in>A. m i)"
   815     assume zcong: "(\<forall>i\<in>A. [z = u i] (mod m i))"
   802     assume zcong: "(\<forall>i\<in>A. [z = u i] (mod m i))"
   816     have "\<forall>i\<in>A. [?x = z] (mod m i)"
   803     have "\<forall>i\<in>A. [?x = z] (mod m i)"
   817       apply clarify
   804       using cong zcong by (auto simp add: cong_def)
   818       apply (rule cong_trans)
       
   819       using cong apply (erule bspec)
       
   820       apply (rule cong_sym)
       
   821       using zcong apply auto
       
   822       done
       
   823     with fin cop have "[?x = z] (mod (\<Prod>i\<in>A. m i))"
   805     with fin cop have "[?x = z] (mod (\<Prod>i\<in>A. m i))"
   824       apply (intro coprime_cong_prod_nat)
   806       by (intro coprime_cong_prod_nat) auto
   825         apply auto
       
   826       done
       
   827     with zless less show "z = ?x"
   807     with zless less show "z = ?x"
   828       apply (intro cong_less_modulus_unique_nat)
   808       by (auto simp add: cong_def)
   829         apply auto
       
   830       apply (erule cong_sym)
       
   831       done
       
   832   qed
   809   qed
   833   from less cong unique show ?thesis
   810   from less cong unique show ?thesis
   834     by blast
   811     by blast
   835 qed
   812 qed
   836 
   813