src/HOL/Number_Theory/Cong.thy
changeset 66888 930abfdf8727
parent 66837 6ba663ff2b1c
child 66954 0230af0f3c59
equal deleted inserted replaced
66887:72b78ee82f7b 66888:930abfdf8727
    30 
    30 
    31 theory Cong
    31 theory Cong
    32   imports "HOL-Computational_Algebra.Primes"
    32   imports "HOL-Computational_Algebra.Primes"
    33 begin
    33 begin
    34 
    34 
    35 subsection \<open>Turn off \<open>One_nat_def\<close>\<close>
    35 subsection \<open>Generic congruences\<close>
    36 
    36  
    37 lemma power_eq_one_eq_nat [simp]: "x^m = 1 \<longleftrightarrow> m = 0 \<or> x = 1"
    37 context unique_euclidean_semiring
    38   for x m :: nat
       
    39   by (induct m) auto
       
    40 
       
    41 declare mod_pos_pos_trivial [simp]
       
    42 
       
    43 
       
    44 subsection \<open>Main definitions\<close>
       
    45 
       
    46 class cong =
       
    47   fixes cong :: "'a \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> bool"  ("(1[_ = _] '(()mod _'))")
       
    48 begin
    38 begin
    49 
    39 
       
    40 definition cong :: "'a \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> bool"  ("(1[_ = _] '(()mod _'))")
       
    41   where "cong b c a \<longleftrightarrow> b mod a = c mod a"
       
    42   
    50 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 _'))")
    51   where "notcong x y m \<equiv> \<not> cong x y m"
    44   where "notcong b c a \<equiv> \<not> cong b c a"
       
    45 
       
    46 lemma cong_mod_left [simp]:
       
    47   "[b mod a = c] (mod a) \<longleftrightarrow> [b = c] (mod a)"
       
    48   by (simp add: cong_def)  
       
    49 
       
    50 lemma cong_mod_right [simp]:
       
    51   "[b = c mod a] (mod a) \<longleftrightarrow> [b = c] (mod a)"
       
    52   by (simp add: cong_def)  
       
    53 
       
    54 lemma cong_dvd_iff:
       
    55   "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)
       
    57 
       
    58 lemma cong_0 [simp, presburger]:
       
    59   "[b = c] (mod 0) \<longleftrightarrow> b = c"
       
    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 
       
    82 lemma cong_add:
       
    83   "[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)
       
    85 
       
    86 lemma cong_mult:
       
    87   "[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)
       
    89 
       
    90 lemma cong_pow:
       
    91   "[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])
       
    93 
       
    94 lemma cong_sum:
       
    95   "[sum f A = sum g A] (mod a)" if "\<And>x. x \<in> A \<Longrightarrow> [f x = g x] (mod a)"
       
    96   using that by (induct A rule: infinite_finite_induct) (auto intro: cong_add)
       
    97 
       
    98 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))"
       
   100   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 
       
   119 lemma mod_mult_cong_right:
       
   120   "[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)
       
   122 
       
   123 lemma mod_mult_cong_left:
       
   124   "[c mod (b * a) = d] (mod a) \<longleftrightarrow> [c = d] (mod a)"
       
   125   using mod_mult_cong_right [of c a b d] by (simp add: ac_simps)
    52 
   126 
    53 end
   127 end
    54 
   128 
    55 
   129 context unique_euclidean_ring
    56 subsubsection \<open>Definitions for the natural numbers\<close>
       
    57 
       
    58 instantiation nat :: cong
       
    59 begin
   130 begin
    60 
   131 
    61 definition cong_nat :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> bool"
   132 lemma cong_diff:
    62   where "cong_nat x y m \<longleftrightarrow> x mod m = y mod m"
   133   "[b = c] (mod a) \<Longrightarrow> [d = e] (mod a) \<Longrightarrow> [b - d = c - e] (mod a)"
    63 
   134   by (auto simp add: cong_def intro: mod_diff_cong)
    64 instance ..
   135 
       
   136 lemma cong_diff_iff_cong_0:
       
   137   "[b - c = 0] (mod a) \<longleftrightarrow> [b = c] (mod a)" (is "?P \<longleftrightarrow> ?Q")
       
   138 proof
       
   139   assume ?P
       
   140   then have "[b - c + c = 0 + c] (mod a)"
       
   141     by (rule cong_add) simp
       
   142   then show ?Q
       
   143     by simp
       
   144 next
       
   145   assume ?Q
       
   146   with cong_diff [of b c a c c] show ?P
       
   147     by simp
       
   148 qed
       
   149 
       
   150 lemma cong_minus_minus_iff:
       
   151   "[- b = - c] (mod a) \<longleftrightarrow> [b = c] (mod a)"
       
   152   using cong_diff_iff_cong_0 [of b c a] cong_diff_iff_cong_0 [of "- b" "- c" a]
       
   153   by (simp add: cong_0_iff dvd_diff_commute)
       
   154 
       
   155 lemma cong_modulus_minus_iff: "[b = c] (mod - a) \<longleftrightarrow> [b = c] (mod a)"
       
   156   using cong_diff_iff_cong_0 [of b c a] cong_diff_iff_cong_0 [of b c " -a"]
       
   157   by (simp add: cong_0_iff)
    65 
   158 
    66 end
   159 end
    67 
   160 
    68 
   161 
    69 subsubsection \<open>Definitions for the integers\<close>
   162 subsection \<open>Congruences on @{typ nat} and @{typ int}\<close>
    70 
       
    71 instantiation int :: cong
       
    72 begin
       
    73 
       
    74 definition cong_int :: "int \<Rightarrow> int \<Rightarrow> int \<Rightarrow> bool"
       
    75   where "cong_int x y m \<longleftrightarrow> x mod m = y mod m"
       
    76 
       
    77 instance ..
       
    78 
       
    79 end
       
    80 
       
    81 
       
    82 subsection \<open>Set up Transfer\<close>
       
    83 
       
    84 
   163 
    85 lemma transfer_nat_int_cong:
   164 lemma transfer_nat_int_cong:
    86   "x \<ge> 0 \<Longrightarrow> y \<ge> 0 \<Longrightarrow> m \<ge> 0 \<Longrightarrow> [nat x = nat y] (mod (nat m)) \<longleftrightarrow> [x = y] (mod m)"
   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)"
    87   for x y m :: int
   166   for x y m :: int
    88   unfolding cong_int_def cong_nat_def
   167   by (auto simp add: cong_def nat_mod_distrib [symmetric])
    89   by (metis int_nat_eq nat_mod_distrib zmod_int)
   168      (metis eq_nat_nat_iff le_less mod_by_0 pos_mod_conj)
    90 
   169 
    91 declare transfer_morphism_nat_int [transfer add return: transfer_nat_int_cong]
   170 declare transfer_morphism_nat_int [transfer add return: transfer_nat_int_cong]
    92 
   171 
    93 lemma transfer_int_nat_cong: "[int x = int y] (mod (int m)) = [x = y] (mod m)"
   172 lemma cong_int_iff:
    94   by (auto simp add: cong_int_def cong_nat_def) (auto simp add: zmod_int [symmetric])
   173   "[int m = int q] (mod int n) \<longleftrightarrow> [m = q] (mod n)"
       
   174   by (simp add: cong_def of_nat_mod [symmetric])
       
   175 
       
   176 lemma transfer_int_nat_cong:
       
   177   "[int x = int y] (mod (int m)) = [x = y] (mod m)"
       
   178   by (fact cong_int_iff)
    95 
   179 
    96 declare transfer_morphism_int_nat [transfer add return: transfer_int_nat_cong]
   180 declare transfer_morphism_int_nat [transfer add return: transfer_int_nat_cong]
    97 
   181 
    98 
   182 lemma cong_Suc_0 [simp, presburger]:
    99 subsection \<open>Congruence\<close>
   183   "[m = n] (mod Suc 0)"
   100 
   184   using cong_1 [of m n] by simp
   101 (* was zcong_0, etc. *)
       
   102 lemma cong_0_nat [simp, presburger]: "[a = b] (mod 0) \<longleftrightarrow> a = b"
       
   103   for a b :: nat
       
   104   by (auto simp: cong_nat_def)
       
   105 
       
   106 lemma cong_0_int [simp, presburger]: "[a = b] (mod 0) \<longleftrightarrow> a = b"
       
   107   for a b :: int
       
   108   by (auto simp: cong_int_def)
       
   109 
       
   110 lemma cong_1_nat [simp, presburger]: "[a = b] (mod 1)"
       
   111   for a b :: nat
       
   112   by (auto simp: cong_nat_def)
       
   113 
       
   114 lemma cong_Suc_0_nat [simp, presburger]: "[a = b] (mod Suc 0)"
       
   115   for a b :: nat
       
   116   by (auto simp: cong_nat_def)
       
   117 
       
   118 lemma cong_1_int [simp, presburger]: "[a = b] (mod 1)"
       
   119   for a b :: int
       
   120   by (auto simp: cong_int_def)
       
   121 
       
   122 lemma cong_refl_nat [simp]: "[k = k] (mod m)"
       
   123   for k :: nat
       
   124   by (auto simp: cong_nat_def)
       
   125 
       
   126 lemma cong_refl_int [simp]: "[k = k] (mod m)"
       
   127   for k :: int
       
   128   by (auto simp: cong_int_def)
       
   129 
       
   130 lemma cong_sym_nat: "[a = b] (mod m) \<Longrightarrow> [b = a] (mod m)"
       
   131   for a b :: nat
       
   132   by (auto simp: cong_nat_def)
       
   133 
       
   134 lemma cong_sym_int: "[a = b] (mod m) \<Longrightarrow> [b = a] (mod m)"
       
   135   for a b :: int
       
   136   by (auto simp: cong_int_def)
       
   137 
       
   138 lemma cong_sym_eq_nat: "[a = b] (mod m) = [b = a] (mod m)"
       
   139   for a b :: nat
       
   140   by (auto simp: cong_nat_def)
       
   141 
       
   142 lemma cong_sym_eq_int: "[a = b] (mod m) = [b = a] (mod m)"
       
   143   for a b :: int
       
   144   by (auto simp: cong_int_def)
       
   145 
       
   146 lemma cong_trans_nat [trans]: "[a = b] (mod m) \<Longrightarrow> [b = c] (mod m) \<Longrightarrow> [a = c] (mod m)"
       
   147   for a b c :: nat
       
   148   by (auto simp: cong_nat_def)
       
   149 
       
   150 lemma cong_trans_int [trans]: "[a = b] (mod m) \<Longrightarrow> [b = c] (mod m) \<Longrightarrow> [a = c] (mod m)"
       
   151   for a b c :: int
       
   152   by (auto simp: cong_int_def)
       
   153 
       
   154 lemma cong_add_nat: "[a = b] (mod m) \<Longrightarrow> [c = d] (mod m) \<Longrightarrow> [a + c = b + d] (mod m)"
       
   155   for a b c :: nat
       
   156   unfolding cong_nat_def by (metis mod_add_cong)
       
   157 
       
   158 lemma cong_add_int: "[a = b] (mod m) \<Longrightarrow> [c = d] (mod m) \<Longrightarrow> [a + c = b + d] (mod m)"
       
   159   for a b c :: int
       
   160   unfolding cong_int_def by (metis mod_add_cong)
       
   161 
       
   162 lemma cong_diff_int: "[a = b] (mod m) \<Longrightarrow> [c = d] (mod m) \<Longrightarrow> [a - c = b - d] (mod m)"
       
   163   for a b c :: int
       
   164   unfolding cong_int_def by (metis mod_diff_cong)
       
   165 
   185 
   166 lemma cong_diff_aux_int:
   186 lemma cong_diff_aux_int:
   167   "[a = b] (mod m) \<Longrightarrow> [c = d] (mod m) \<Longrightarrow>
   187   "[a = b] (mod m) \<Longrightarrow> [c = d] (mod m) \<Longrightarrow>
   168     a \<ge> c \<Longrightarrow> b \<ge> d \<Longrightarrow> [tsub a c = tsub b d] (mod m)"
   188     a \<ge> c \<Longrightarrow> b \<ge> d \<Longrightarrow> [tsub a c = tsub b d] (mod m)"
   169   for a b c d :: int
   189   for a b c d :: int
   170   by (metis cong_diff_int tsub_eq)
   190   by (metis cong_diff tsub_eq)
   171 
   191 
   172 lemma cong_diff_nat:
   192 lemma cong_diff_nat:
   173   fixes a b c d :: nat
   193   "[a - c = b - d] (mod m)" if "[a = b] (mod m)" "[c = d] (mod m)"
   174   assumes "[a = b] (mod m)" "[c = d] (mod m)" "a \<ge> c" "b \<ge> d"
   194     and "a \<ge> c" "b \<ge> d" for a b c d m :: nat 
   175   shows "[a - c = b - d] (mod m)"
   195   using that by (rule cong_diff_aux_int [transferred])
   176   using assms by (rule cong_diff_aux_int [transferred])
   196 
   177 
   197 lemma cong_diff_iff_cong_0_aux_int: "a \<ge> b \<Longrightarrow> [tsub a b = 0] (mod m) = [a = b] (mod m)"
   178 lemma cong_mult_nat: "[a = b] (mod m) \<Longrightarrow> [c = d] (mod m) \<Longrightarrow> [a * c = b * d] (mod m)"
       
   179   for a b c d :: nat
       
   180   unfolding cong_nat_def  by (metis mod_mult_cong)
       
   181 
       
   182 lemma cong_mult_int: "[a = b] (mod m) \<Longrightarrow> [c = d] (mod m) \<Longrightarrow> [a * c = b * d] (mod m)"
       
   183   for a b c d :: int
       
   184   unfolding cong_int_def  by (metis mod_mult_cong)
       
   185 
       
   186 lemma cong_exp_nat: "[x = y] (mod n) \<Longrightarrow> [x^k = y^k] (mod n)"
       
   187   for x y :: nat
       
   188   by (induct k) (auto simp: cong_mult_nat)
       
   189 
       
   190 lemma cong_exp_int: "[x = y] (mod n) \<Longrightarrow> [x^k = y^k] (mod n)"
       
   191   for x y :: int
       
   192   by (induct k) (auto simp: cong_mult_int)
       
   193 
       
   194 lemma cong_sum_nat: "(\<And>x. x \<in> A \<Longrightarrow> [f x = g x] (mod m)) \<Longrightarrow> [(\<Sum>x\<in>A. f x) = (\<Sum>x\<in>A. g x)] (mod m)"
       
   195   for f g :: "'a \<Rightarrow> nat"
       
   196   by (induct A rule: infinite_finite_induct) (auto intro: cong_add_nat)
       
   197 
       
   198 lemma cong_sum_int: "(\<And>x. x \<in> A \<Longrightarrow> [f x = g x] (mod m)) \<Longrightarrow> [(\<Sum>x\<in>A. f x) = (\<Sum>x\<in>A. g x)] (mod m)"
       
   199   for f g :: "'a \<Rightarrow> int"
       
   200   by (induct A rule: infinite_finite_induct) (auto intro: cong_add_int)
       
   201 
       
   202 lemma cong_prod_nat: "(\<And>x. x \<in> A \<Longrightarrow> [f x = g x] (mod m)) \<Longrightarrow> [(\<Prod>x\<in>A. f x) = (\<Prod>x\<in>A. g x)] (mod m)"
       
   203   for f g :: "'a \<Rightarrow> nat"
       
   204   by (induct A rule: infinite_finite_induct) (auto intro: cong_mult_nat)
       
   205 
       
   206 lemma cong_prod_int: "(\<And>x. x \<in> A \<Longrightarrow> [f x = g x] (mod m)) \<Longrightarrow> [(\<Prod>x\<in>A. f x) = (\<Prod>x\<in>A. g x)] (mod m)"
       
   207   for f g :: "'a \<Rightarrow> int"
       
   208   by (induct A rule: infinite_finite_induct) (auto intro: cong_mult_int)
       
   209 
       
   210 lemma cong_scalar_nat: "[a = b] (mod m) \<Longrightarrow> [a * k = b * k] (mod m)"
       
   211   for a b k :: nat
       
   212   by (rule cong_mult_nat) simp_all
       
   213 
       
   214 lemma cong_scalar_int: "[a = b] (mod m) \<Longrightarrow> [a * k = b * k] (mod m)"
       
   215   for a b k :: int
       
   216   by (rule cong_mult_int) simp_all
       
   217 
       
   218 lemma cong_scalar2_nat: "[a = b] (mod m) \<Longrightarrow> [k * a = k * b] (mod m)"
       
   219   for a b k :: nat
       
   220   by (rule cong_mult_nat) simp_all
       
   221 
       
   222 lemma cong_scalar2_int: "[a = b] (mod m) \<Longrightarrow> [k * a = k * b] (mod m)"
       
   223   for a b k :: int
       
   224   by (rule cong_mult_int) simp_all
       
   225 
       
   226 lemma cong_mult_self_nat: "[a * m = 0] (mod m)"
       
   227   for a m :: nat
       
   228   by (auto simp: cong_nat_def)
       
   229 
       
   230 lemma cong_mult_self_int: "[a * m = 0] (mod m)"
       
   231   for a m :: int
       
   232   by (auto simp: cong_int_def)
       
   233 
       
   234 lemma cong_eq_diff_cong_0_int: "[a = b] (mod m) = [a - b = 0] (mod m)"
       
   235   for a b :: int
   198   for a b :: int
   236   by (metis cong_add_int cong_diff_int cong_refl_int diff_add_cancel diff_self)
   199   by (subst tsub_eq, assumption, rule cong_diff_iff_cong_0)
   237 
   200 
   238 lemma cong_eq_diff_cong_0_aux_int: "a \<ge> b \<Longrightarrow> [a = b] (mod m) = [tsub a b = 0] (mod m)"
   201 lemma cong_diff_iff_cong_0_nat:
   239   for a b :: int
       
   240   by (subst tsub_eq, assumption, rule cong_eq_diff_cong_0_int)
       
   241 
       
   242 lemma cong_eq_diff_cong_0_nat:
       
   243   fixes a b :: nat
   202   fixes a b :: nat
   244   assumes "a \<ge> b"
   203   assumes "a \<ge> b"
   245   shows "[a = b] (mod m) = [a - b = 0] (mod m)"
   204   shows "[a - b = 0] (mod m) = [a = b] (mod m)"
   246   using assms by (rule cong_eq_diff_cong_0_aux_int [transferred])
   205   using assms by (rule cong_diff_iff_cong_0_aux_int [transferred])
   247 
       
   248 lemma cong_diff_cong_0'_nat:
       
   249   "[x = y] (mod n) \<longleftrightarrow> (if x \<le> y then [y - x = 0] (mod n) else [x - y = 0] (mod n))"
       
   250   for x y :: nat
       
   251   by (metis cong_eq_diff_cong_0_nat cong_sym_nat nat_le_linear)
       
   252 
   206 
   253 lemma cong_altdef_nat: "a \<ge> b \<Longrightarrow> [a = b] (mod m) \<longleftrightarrow> m dvd (a - b)"
   207 lemma cong_altdef_nat: "a \<ge> b \<Longrightarrow> [a = b] (mod m) \<longleftrightarrow> m dvd (a - b)"
   254   for a b :: nat
   208   for a b :: nat
   255   apply (subst cong_eq_diff_cong_0_nat, assumption)
   209   by (simp add: cong_0_iff [symmetric] cong_diff_iff_cong_0_nat)
   256   apply (unfold cong_nat_def)
       
   257   apply (simp add: dvd_eq_mod_eq_0 [symmetric])
       
   258   done
       
   259 
   210 
   260 lemma cong_altdef_int: "[a = b] (mod m) \<longleftrightarrow> m dvd (a - b)"
   211 lemma cong_altdef_int: "[a = b] (mod m) \<longleftrightarrow> m dvd (a - b)"
   261   for a b :: int
   212   for a b :: int
   262   by (metis cong_int_def mod_eq_dvd_iff)
   213   by (simp add: cong_0_iff [symmetric] cong_diff_iff_cong_0)
   263 
   214 
   264 lemma cong_abs_int: "[x = y] (mod abs m) \<longleftrightarrow> [x = y] (mod m)"
   215 lemma cong_abs_int [simp]: "[x = y] (mod abs m) \<longleftrightarrow> [x = y] (mod m)"
   265   for x y :: int
   216   for x y :: int
   266   by (simp add: cong_altdef_int)
   217   by (simp add: cong_altdef_int)
   267 
   218 
   268 lemma cong_square_int:
   219 lemma cong_square_int:
   269   "prime p \<Longrightarrow> 0 < a \<Longrightarrow> [a * a = 1] (mod p) \<Longrightarrow> [a = 1] (mod p) \<or> [a = - 1] (mod p)"
   220   "prime p \<Longrightarrow> 0 < a \<Longrightarrow> [a * a = 1] (mod p) \<Longrightarrow> [a = 1] (mod p) \<or> [a = - 1] (mod p)"
   287 
   238 
   288 lemma cong_mult_lcancel_int: "coprime k m \<Longrightarrow> [k * a = k * b] (mod m) = [a = b] (mod m)"
   239 lemma cong_mult_lcancel_int: "coprime k m \<Longrightarrow> [k * a = k * b] (mod m) = [a = b] (mod m)"
   289   for a k m :: int
   240   for a k m :: int
   290   by (simp add: mult.commute cong_mult_rcancel_int)
   241   by (simp add: mult.commute cong_mult_rcancel_int)
   291 
   242 
   292 (* was zcong_zgcd_zmult_zmod *)
       
   293 lemma coprime_cong_mult_int:
   243 lemma coprime_cong_mult_int:
   294   "[a = b] (mod m) \<Longrightarrow> [a = b] (mod n) \<Longrightarrow> coprime m n \<Longrightarrow> [a = b] (mod m * n)"
   244   "[a = b] (mod m) \<Longrightarrow> [a = b] (mod n) \<Longrightarrow> coprime m n \<Longrightarrow> [a = b] (mod m * n)"
   295   for a b :: int
   245   for a b :: int
   296   by (metis divides_mult cong_altdef_int)
   246   by (metis divides_mult cong_altdef_int)
   297 
   247 
   300   for a b :: nat
   250   for a b :: nat
   301   by (metis coprime_cong_mult_int [transferred])
   251   by (metis coprime_cong_mult_int [transferred])
   302 
   252 
   303 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"
   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"
   304   for a b :: nat
   254   for a b :: nat
   305   by (auto simp add: cong_nat_def)
   255   by (auto simp add: cong_def)
   306 
   256 
   307 lemma cong_less_imp_eq_int: "0 \<le> a \<Longrightarrow> a < m \<Longrightarrow> 0 \<le> b \<Longrightarrow> b < m \<Longrightarrow> [a = b] (mod m) \<Longrightarrow> a = b"
   257 lemma cong_less_imp_eq_int: "0 \<le> a \<Longrightarrow> a < m \<Longrightarrow> 0 \<le> b \<Longrightarrow> b < m \<Longrightarrow> [a = b] (mod m) \<Longrightarrow> a = b"
   308   for a b :: int
   258   for a b :: int
   309   by (auto simp add: cong_int_def)
   259   by (auto simp add: cong_def)
   310 
   260 
   311 lemma cong_less_unique_nat: "0 < m \<Longrightarrow> (\<exists>!b. 0 \<le> b \<and> b < m \<and> [a = b] (mod m))"
   261 lemma cong_less_unique_nat: "0 < m \<Longrightarrow> (\<exists>!b. 0 \<le> b \<and> b < m \<and> [a = b] (mod m))"
   312   for a m :: nat
   262   for a m :: nat
   313   by (auto simp: cong_nat_def) (metis mod_less_divisor mod_mod_trivial)
   263   by (auto simp: cong_def) (metis mod_less_divisor mod_mod_trivial)
   314 
   264 
   315 lemma cong_less_unique_int: "0 < m \<Longrightarrow> (\<exists>!b. 0 \<le> b \<and> b < m \<and> [a = b] (mod m))"
   265 lemma cong_less_unique_int: "0 < m \<Longrightarrow> (\<exists>!b. 0 \<le> b \<and> b < m \<and> [a = b] (mod m))"
   316   for a m :: int
   266   for a m :: int
   317   by (auto simp: cong_int_def)  (metis mod_mod_trivial pos_mod_conj)
   267   by (auto simp: cong_def)  (metis mod_mod_trivial pos_mod_conj)
   318 
   268 
   319 lemma cong_iff_lin_int: "[a = b] (mod m) \<longleftrightarrow> (\<exists>k. b = a + m * k)"
   269 lemma cong_iff_lin_int: "[a = b] (mod m) \<longleftrightarrow> (\<exists>k. b = a + m * k)"
   320   for a b :: int
   270   for a b :: int
   321   by (auto simp add: cong_altdef_int algebra_simps elim!: dvdE)
   271   by (auto simp add: cong_altdef_int algebra_simps elim!: dvdE)
   322     (simp add: distrib_right [symmetric] add_eq_0_iff)
   272     (simp add: distrib_right [symmetric] add_eq_0_iff)
   332     with \<open>?lhs\<close> show ?rhs
   282     with \<open>?lhs\<close> show ?rhs
   333       by (metis cong_altdef_nat dvd_def le_add_diff_inverse add_0_right mult_0 mult.commute)
   283       by (metis cong_altdef_nat dvd_def le_add_diff_inverse add_0_right mult_0 mult.commute)
   334   next
   284   next
   335     case False
   285     case False
   336     with \<open>?lhs\<close> show ?rhs
   286     with \<open>?lhs\<close> show ?rhs
   337       apply (subst (asm) cong_sym_eq_nat)
   287       by (metis cong_def mult.commute nat_le_linear nat_mod_eq_lemma)
   338       apply (auto simp: cong_altdef_nat)
       
   339       apply (metis add_0_right add_diff_inverse dvd_div_mult_self less_or_eq_imp_le mult_0)
       
   340       done
       
   341   qed
   288   qed
   342 next
   289 next
   343   assume ?rhs
   290   assume ?rhs
   344   then show ?lhs
   291   then show ?lhs
   345     by (metis cong_nat_def mod_mult_self2 mult.commute)
   292     by (metis cong_def mult.commute nat_mod_eq_iff) 
   346 qed
   293 qed
   347 
   294 
   348 lemma cong_gcd_eq_int: "[a = b] (mod m) \<Longrightarrow> gcd a m = gcd b m"
   295 lemma cong_gcd_eq_int: "[a = b] (mod m) \<Longrightarrow> gcd a m = gcd b m"
   349   for a b :: int
   296   for a b :: int
   350   by (metis cong_int_def gcd_red_int)
   297   by (auto simp add: cong_def) (metis gcd_red_int)
   351 
   298 
   352 lemma cong_gcd_eq_nat: "[a = b] (mod m) \<Longrightarrow> gcd a m = gcd b m"
   299 lemma cong_gcd_eq_nat: "[a = b] (mod m) \<Longrightarrow> gcd a m = gcd b m"
   353   for a b :: nat
   300   for a b :: nat
   354   by (metis cong_gcd_eq_int [transferred])
   301   by (metis cong_gcd_eq_int [transferred])
   355 
   302 
   361   for a b :: int
   308   for a b :: int
   362   by (auto simp add: cong_gcd_eq_int)
   309   by (auto simp add: cong_gcd_eq_int)
   363 
   310 
   364 lemma cong_cong_mod_nat: "[a = b] (mod m) \<longleftrightarrow> [a mod m = b mod m] (mod m)"
   311 lemma cong_cong_mod_nat: "[a = b] (mod m) \<longleftrightarrow> [a mod m = b mod m] (mod m)"
   365   for a b :: nat
   312   for a b :: nat
   366   by (auto simp add: cong_nat_def)
   313   by simp
   367 
   314 
   368 lemma cong_cong_mod_int: "[a = b] (mod m) \<longleftrightarrow> [a mod m = b mod m] (mod m)"
   315 lemma cong_cong_mod_int: "[a = b] (mod m) \<longleftrightarrow> [a mod m = b mod m] (mod m)"
   369   for a b :: int
   316   for a b :: int
   370   by (auto simp add: cong_int_def)
   317   by simp
   371 
   318 
   372 lemma cong_minus_int [iff]: "[a = b] (mod - m) \<longleftrightarrow> [a = b] (mod m)"
   319 lemma cong_minus_int [iff]: "[a = b] (mod - m) \<longleftrightarrow> [a = b] (mod m)"
   373   for a b :: int
   320   for a b :: int
   374   by (metis cong_iff_lin_int minus_equation_iff mult_minus_left mult_minus_right)
   321   by (metis cong_iff_lin_int minus_equation_iff mult_minus_left mult_minus_right)
   375 
   322 
   431   done
   378   done
   432 
   379 
   433 lemma cong_dvd_modulus_int: "[x = y] (mod m) \<Longrightarrow> n dvd m \<Longrightarrow> [x = y] (mod n)"
   380 lemma cong_dvd_modulus_int: "[x = y] (mod m) \<Longrightarrow> n dvd m \<Longrightarrow> [x = y] (mod n)"
   434   for x y :: int
   381   for x y :: int
   435   by (auto simp add: cong_altdef_int dvd_def)
   382   by (auto simp add: cong_altdef_int dvd_def)
   436 
       
   437 lemma cong_dvd_eq_nat: "[x = y] (mod n) \<Longrightarrow> n dvd x \<longleftrightarrow> n dvd y"
       
   438   for x y :: nat
       
   439   by (auto simp: cong_nat_def dvd_eq_mod_eq_0)
       
   440 
       
   441 lemma cong_dvd_eq_int: "[x = y] (mod n) \<Longrightarrow> n dvd x \<longleftrightarrow> n dvd y"
       
   442   for x y :: int
       
   443   by (auto simp: cong_int_def dvd_eq_mod_eq_0)
       
   444 
       
   445 lemma cong_mod_nat: "n \<noteq> 0 \<Longrightarrow> [a mod n = a] (mod n)"
       
   446   for a n :: nat
       
   447   by (simp add: cong_nat_def)
       
   448 
       
   449 lemma cong_mod_int: "n \<noteq> 0 \<Longrightarrow> [a mod n = a] (mod n)"
       
   450   for a n :: int
       
   451   by (simp add: cong_int_def)
       
   452 
       
   453 lemma mod_mult_cong_nat: "a \<noteq> 0 \<Longrightarrow> b \<noteq> 0 \<Longrightarrow> [x mod (a * b) = y] (mod a) \<longleftrightarrow> [x = y] (mod a)"
       
   454   for a b :: nat
       
   455   by (simp add: cong_nat_def mod_mult2_eq  mod_add_left_eq)
       
   456 
       
   457 lemma neg_cong_int: "[a = b] (mod m) \<longleftrightarrow> [- a = - b] (mod m)"
       
   458   for a b :: int
       
   459   by (metis cong_int_def minus_minus mod_minus_cong)
       
   460 
       
   461 lemma cong_modulus_neg_int: "[a = b] (mod m) \<longleftrightarrow> [a = b] (mod - m)"
       
   462   for a b :: int
       
   463   by (auto simp add: cong_altdef_int)
       
   464 
       
   465 lemma mod_mult_cong_int: "a \<noteq> 0 \<Longrightarrow> b \<noteq> 0 \<Longrightarrow> [x mod (a * b) = y] (mod a) \<longleftrightarrow> [x = y] (mod a)"
       
   466   for a b :: int
       
   467 proof (cases "b > 0")
       
   468   case True
       
   469   then show ?thesis
       
   470     by (simp add: cong_int_def mod_mod_cancel mod_add_left_eq)
       
   471 next
       
   472   case False
       
   473   then show ?thesis
       
   474     apply (subst (1 2) cong_modulus_neg_int)
       
   475     apply (unfold cong_int_def)
       
   476     apply (subgoal_tac "a * b = (- a * - b)")
       
   477      apply (erule ssubst)
       
   478      apply (subst zmod_zmult2_eq)
       
   479       apply (auto simp add: mod_add_left_eq mod_minus_right div_minus_right)
       
   480      apply (metis mod_diff_left_eq mod_diff_right_eq mod_mult_self1_is_0 diff_zero)+
       
   481     done
       
   482 qed
       
   483 
   383 
   484 lemma cong_to_1_nat:
   384 lemma cong_to_1_nat:
   485   fixes a :: nat
   385   fixes a :: nat
   486   assumes "[a = 1] (mod n)"
   386   assumes "[a = 1] (mod n)"
   487   shows "n dvd (a - 1)"
   387   shows "n dvd (a - 1)"
   492   case False
   392   case False
   493   with assms show ?thesis by (metis cong_altdef_nat leI less_one)
   393   with assms show ?thesis by (metis cong_altdef_nat leI less_one)
   494 qed
   394 qed
   495 
   395 
   496 lemma cong_0_1_nat': "[0 = Suc 0] (mod n) \<longleftrightarrow> n = Suc 0"
   396 lemma cong_0_1_nat': "[0 = Suc 0] (mod n) \<longleftrightarrow> n = Suc 0"
   497   by (auto simp: cong_nat_def)
   397   by (auto simp: cong_def)
   498 
   398 
   499 lemma cong_0_1_nat: "[0 = 1] (mod n) \<longleftrightarrow> n = 1"
   399 lemma cong_0_1_nat: "[0 = 1] (mod n) \<longleftrightarrow> n = 1"
   500   for n :: nat
   400   for n :: nat
   501   by (auto simp: cong_nat_def)
   401   by (auto simp: cong_def)
   502 
   402 
   503 lemma cong_0_1_int: "[0 = 1] (mod n) \<longleftrightarrow> n = 1 \<or> n = - 1"
   403 lemma cong_0_1_int: "[0 = 1] (mod n) \<longleftrightarrow> n = 1 \<or> n = - 1"
   504   for n :: int
   404   for n :: int
   505   by (auto simp: cong_int_def zmult_eq_1_iff)
   405   by (auto simp: cong_def zmult_eq_1_iff)
   506 
   406 
   507 lemma cong_to_1'_nat: "[a = 1] (mod n) \<longleftrightarrow> a = 0 \<and> n = 1 \<or> (\<exists>m. a = 1 + m * n)"
   407 lemma cong_to_1'_nat: "[a = 1] (mod n) \<longleftrightarrow> a = 0 \<and> n = 1 \<or> (\<exists>m. a = 1 + m * n)"
   508   for a :: nat
   408   for a :: nat
   509   by (metis add.right_neutral cong_0_1_nat cong_iff_lin_nat cong_to_1_nat
   409   by (metis add.right_neutral cong_0_1_nat cong_iff_lin_nat cong_to_1_nat
   510       dvd_div_mult_self leI le_add_diff_inverse less_one mult_eq_if)
   410       dvd_div_mult_self leI le_add_diff_inverse less_one mult_eq_if)
   522   then show ?thesis by force
   422   then show ?thesis by force
   523 next
   423 next
   524   case False
   424   case False
   525   then show ?thesis
   425   then show ?thesis
   526     using bezout_nat [of a n, OF \<open>a \<noteq> 0\<close>]
   426     using bezout_nat [of a n, OF \<open>a \<noteq> 0\<close>]
   527     by auto (metis cong_add_rcancel_0_nat cong_mult_self_nat mult.commute)
   427     by auto (metis cong_add_rcancel_0_nat cong_mult_self_left)
   528 qed
   428 qed
   529 
   429 
   530 lemma cong_solve_int: "a \<noteq> 0 \<Longrightarrow> \<exists>x. [a * x = gcd a n] (mod n)"
   430 lemma cong_solve_int: "a \<noteq> 0 \<Longrightarrow> \<exists>x. [a * x = gcd a n] (mod n)"
   531   for a :: int
   431   for a :: int
   532   apply (cases "n = 0")
   432   apply (cases "n = 0")
   544   shows "\<exists>x. [a * x = d] (mod n)"
   444   shows "\<exists>x. [a * x = d] (mod n)"
   545 proof -
   445 proof -
   546   from cong_solve_nat [OF a] obtain x where "[a * x = gcd a n](mod n)"
   446   from cong_solve_nat [OF a] obtain x where "[a * x = gcd a n](mod n)"
   547     by auto
   447     by auto
   548   then have "[(d div gcd a n) * (a * x) = (d div gcd a n) * gcd a n] (mod n)"
   448   then have "[(d div gcd a n) * (a * x) = (d div gcd a n) * gcd a n] (mod n)"
   549     by (elim cong_scalar2_nat)
   449     using cong_scalar_left by blast
   550   also from b have "(d div gcd a n) * gcd a n = d"
   450   also from b have "(d div gcd a n) * gcd a n = d"
   551     by (rule dvd_div_mult_self)
   451     by (rule dvd_div_mult_self)
   552   also have "(d div gcd a n) * (a * x) = a * (d div gcd a n * x)"
   452   also have "(d div gcd a n) * (a * x) = a * (d div gcd a n * x)"
   553     by auto
   453     by auto
   554   finally show ?thesis
   454   finally show ?thesis
   560   shows "\<exists>x. [a * x = d] (mod n)"
   460   shows "\<exists>x. [a * x = d] (mod n)"
   561 proof -
   461 proof -
   562   from cong_solve_int [OF a] obtain x where "[a * x = gcd a n](mod n)"
   462   from cong_solve_int [OF a] obtain x where "[a * x = gcd a n](mod n)"
   563     by auto
   463     by auto
   564   then have "[(d div gcd a n) * (a * x) = (d div gcd a n) * gcd a n] (mod n)"
   464   then have "[(d div gcd a n) * (a * x) = (d div gcd a n) * gcd a n] (mod n)"
   565     by (elim cong_scalar2_int)
   465     using cong_scalar_left by blast
   566   also from b have "(d div gcd a n) * gcd a n = d"
   466   also from b have "(d div gcd a n) * gcd a n = d"
   567     by (rule dvd_div_mult_self)
   467     by (rule dvd_div_mult_self)
   568   also have "(d div gcd a n) * (a * x) = a * (d div gcd a n * x)"
   468   also have "(d div gcd a n) * (a * x) = a * (d div gcd a n * x)"
   569     by auto
   469     by auto
   570   finally show ?thesis
   470   finally show ?thesis
   575   fixes a :: nat
   475   fixes a :: nat
   576   assumes "coprime a n"
   476   assumes "coprime a n"
   577   shows "\<exists>x. [a * x = 1] (mod n)"
   477   shows "\<exists>x. [a * x = 1] (mod n)"
   578 proof (cases "a = 0")
   478 proof (cases "a = 0")
   579   case True
   479   case True
   580   with assms show ?thesis by force
   480   with assms show ?thesis
       
   481     by (simp add: cong_0_1_nat') 
   581 next
   482 next
   582   case False
   483   case False
   583   with assms show ?thesis by (metis cong_solve_nat)
   484   with assms show ?thesis
       
   485     by (metis cong_solve_nat)
   584 qed
   486 qed
   585 
   487 
   586 lemma cong_solve_coprime_int: "coprime (a::int) n \<Longrightarrow> \<exists>x. [a * x = 1] (mod n)"
   488 lemma cong_solve_coprime_int: "coprime (a::int) n \<Longrightarrow> \<exists>x. [a * x = 1] (mod n)"
   587   apply (cases "a = 0")
   489   apply (cases "a = 0")
   588    apply auto
   490    apply auto
   596   by (metis One_nat_def cong_gcd_eq_nat cong_solve_coprime_nat coprime_lmult gcd.commute gcd_Suc_0)
   498   by (metis One_nat_def cong_gcd_eq_nat cong_solve_coprime_nat coprime_lmult gcd.commute gcd_Suc_0)
   597 
   499 
   598 lemma coprime_iff_invertible_int: "m > 0 \<Longrightarrow> coprime a m \<longleftrightarrow> (\<exists>x. [a * x = 1] (mod m))"
   500 lemma coprime_iff_invertible_int: "m > 0 \<Longrightarrow> coprime a m \<longleftrightarrow> (\<exists>x. [a * x = 1] (mod m))"
   599   for m :: int
   501   for m :: int
   600   apply (auto intro: cong_solve_coprime_int)
   502   apply (auto intro: cong_solve_coprime_int)
   601   apply (metis cong_int_def coprime_mul_eq gcd_1_int gcd.commute gcd_red_int)
   503   using cong_gcd_eq_int coprime_mul_eq' apply fastforce
   602   done
   504   done
   603 
   505 
   604 lemma coprime_iff_invertible'_nat:
   506 lemma coprime_iff_invertible'_nat:
   605   "m > 0 \<Longrightarrow> coprime a m \<longleftrightarrow> (\<exists>x. 0 \<le> x \<and> x < m \<and> [a * x = Suc 0] (mod m))"
   507   "m > 0 \<Longrightarrow> coprime a m \<longleftrightarrow> (\<exists>x. 0 \<le> x \<and> x < m \<and> [a * x = Suc 0] (mod m))"
   606   apply (subst coprime_iff_invertible_nat)
   508   apply (subst coprime_iff_invertible_nat)
   607    apply auto
   509    apply auto
   608   apply (auto simp add: cong_nat_def)
   510   apply (auto simp add: cong_def)
   609   apply (metis mod_less_divisor mod_mult_right_eq)
   511   apply (metis mod_less_divisor mod_mult_right_eq)
   610   done
   512   done
   611 
   513 
   612 lemma coprime_iff_invertible'_int:
   514 lemma coprime_iff_invertible'_int:
   613   "m > 0 \<Longrightarrow> coprime a m \<longleftrightarrow> (\<exists>x. 0 \<le> x \<and> x < m \<and> [a * x = 1] (mod m))"
   515   "m > 0 \<Longrightarrow> coprime a m \<longleftrightarrow> (\<exists>x. 0 \<le> x \<and> x < m \<and> [a * x = 1] (mod m))"
   614   for m :: int
   516   for m :: int
   615   apply (subst coprime_iff_invertible_int)
   517   apply (subst coprime_iff_invertible_int)
   616    apply (auto simp add: cong_int_def)
   518    apply (auto simp add: cong_def)
   617   apply (metis mod_mult_right_eq pos_mod_conj)
   519   apply (metis mod_mult_right_eq pos_mod_conj)
   618   done
   520   done
   619 
   521 
   620 lemma cong_cong_lcm_nat: "[x = y] (mod a) \<Longrightarrow> [x = y] (mod b) \<Longrightarrow> [x = y] (mod lcm a b)"
   522 lemma cong_cong_lcm_nat: "[x = y] (mod a) \<Longrightarrow> [x = y] (mod b) \<Longrightarrow> [x = y] (mod lcm a b)"
   621   for x y :: nat
   523   for x y :: nat
   622   apply (cases "y \<le> x")
   524   apply (cases "y \<le> x")
   623   apply (metis cong_altdef_nat lcm_least)
   525    apply (simp add: cong_altdef_nat)
   624   apply (meson cong_altdef_nat cong_sym_nat lcm_least_iff nat_le_linear)
   526   apply (meson cong_altdef_nat cong_sym lcm_least_iff nat_le_linear)
   625   done
   527   done
   626 
   528 
   627 lemma cong_cong_lcm_int: "[x = y] (mod a) \<Longrightarrow> [x = y] (mod b) \<Longrightarrow> [x = y] (mod lcm a b)"
   529 lemma cong_cong_lcm_int: "[x = y] (mod a) \<Longrightarrow> [x = y] (mod b) \<Longrightarrow> [x = y] (mod lcm a b)"
   628   for x y :: int
   530   for x y :: int
   629   by (auto simp add: cong_altdef_int lcm_least)
   531   by (auto simp add: cong_altdef_int lcm_least)
   630 
   532 
   631 lemma cong_cong_prod_coprime_nat [rule_format]: "finite A \<Longrightarrow>
   533 lemma cong_cong_prod_coprime_nat:
   632     (\<forall>i\<in>A. (\<forall>j\<in>A. i \<noteq> j \<longrightarrow> coprime (m i) (m j))) \<longrightarrow>
   534   "[x = y] (mod (\<Prod>i\<in>A. m i))" if
   633     (\<forall>i\<in>A. [(x::nat) = y] (mod m i)) \<longrightarrow>
   535     "(\<forall>i\<in>A. [(x::nat) = y] (mod m i))"
   634       [x = y] (mod (\<Prod>i\<in>A. m i))"
   536     and "(\<forall>i\<in>A. (\<forall>j\<in>A. i \<noteq> j \<longrightarrow> coprime (m i) (m j)))"
   635   apply (induct set: finite)
   537   using that apply (induct A rule: infinite_finite_induct)
   636   apply auto
   538     apply auto
   637   apply (metis One_nat_def coprime_cong_mult_nat gcd.commute prod_coprime)
   539   apply (metis One_nat_def coprime_cong_mult_nat gcd.commute prod_coprime)
   638   done
   540   done
   639 
   541 
   640 lemma cong_cong_prod_coprime_int [rule_format]: "finite A \<Longrightarrow>
   542 lemma cong_cong_prod_coprime_int [rule_format]:
   641     (\<forall>i\<in>A. (\<forall>j\<in>A. i \<noteq> j \<longrightarrow> coprime (m i) (m j))) \<longrightarrow>
   543   "[x = y] (mod (\<Prod>i\<in>A. m i))" if
   642     (\<forall>i\<in>A. [(x::int) = y] (mod m i)) \<longrightarrow>
   544     "(\<forall>i\<in>A. [(x::int) = y] (mod m i))"
   643       [x = y] (mod (\<Prod>i\<in>A. m i))"
   545     "(\<forall>i\<in>A. (\<forall>j\<in>A. i \<noteq> j \<longrightarrow> coprime (m i) (m j)))"
   644   apply (induct set: finite)
   546   using that apply (induct A rule: infinite_finite_induct)
   645   apply auto
   547   apply auto
   646   apply (metis coprime_cong_mult_int gcd.commute prod_coprime)
   548   apply (metis coprime_cong_mult_int gcd.commute prod_coprime)
   647   done
   549   done
   648 
   550 
   649 lemma binary_chinese_remainder_aux_nat:
   551 lemma binary_chinese_remainder_aux_nat:
   656   from a have b: "coprime m2 m1"
   558   from a have b: "coprime m2 m1"
   657     by (subst gcd.commute)
   559     by (subst gcd.commute)
   658   from cong_solve_coprime_nat [OF b] obtain x2 where 2: "[m2 * x2 = 1] (mod m1)"
   560   from cong_solve_coprime_nat [OF b] obtain x2 where 2: "[m2 * x2 = 1] (mod m1)"
   659     by auto
   561     by auto
   660   have "[m1 * x1 = 0] (mod m1)"
   562   have "[m1 * x1 = 0] (mod m1)"
   661     by (subst mult.commute) (rule cong_mult_self_nat)
   563     by (simp add: cong_mult_self_left)
   662   moreover have "[m2 * x2 = 0] (mod m2)"
   564   moreover have "[m2 * x2 = 0] (mod m2)"
   663     by (subst mult.commute) (rule cong_mult_self_nat)
   565     by (simp add: cong_mult_self_left)
   664   ultimately show ?thesis
   566   ultimately show ?thesis
   665     using 1 2 by blast
   567     using 1 2 by blast
   666 qed
   568 qed
   667 
   569 
   668 lemma binary_chinese_remainder_aux_int:
   570 lemma binary_chinese_remainder_aux_int:
   675   from a have b: "coprime m2 m1"
   577   from a have b: "coprime m2 m1"
   676     by (subst gcd.commute)
   578     by (subst gcd.commute)
   677   from cong_solve_coprime_int [OF b] obtain x2 where 2: "[m2 * x2 = 1] (mod m1)"
   579   from cong_solve_coprime_int [OF b] obtain x2 where 2: "[m2 * x2 = 1] (mod m1)"
   678     by auto
   580     by auto
   679   have "[m1 * x1 = 0] (mod m1)"
   581   have "[m1 * x1 = 0] (mod m1)"
   680     by (subst mult.commute) (rule cong_mult_self_int)
   582     by (simp add: cong_mult_self_left)
   681   moreover have "[m2 * x2 = 0] (mod m2)"
   583   moreover have "[m2 * x2 = 0] (mod m2)"
   682     by (subst mult.commute) (rule cong_mult_self_int)
   584     by (simp add: cong_mult_self_left)
   683   ultimately show ?thesis
   585   ultimately show ?thesis
   684     using 1 2 by blast
   586     using 1 2 by blast
   685 qed
   587 qed
   686 
   588 
   687 lemma binary_chinese_remainder_nat:
   589 lemma binary_chinese_remainder_nat:
   693     where "[b1 = 1] (mod m1)" and "[b1 = 0] (mod m2)"
   595     where "[b1 = 1] (mod m1)" and "[b1 = 0] (mod m2)"
   694       and "[b2 = 0] (mod m1)" and "[b2 = 1] (mod m2)"
   596       and "[b2 = 0] (mod m1)" and "[b2 = 1] (mod m2)"
   695     by blast
   597     by blast
   696   let ?x = "u1 * b1 + u2 * b2"
   598   let ?x = "u1 * b1 + u2 * b2"
   697   have "[?x = u1 * 1 + u2 * 0] (mod m1)"
   599   have "[?x = u1 * 1 + u2 * 0] (mod m1)"
   698     apply (rule cong_add_nat)
   600     using \<open>[b1 = 1] (mod m1)\<close> \<open>[b2 = 0] (mod m1)\<close> cong_add cong_scalar_left by blast
   699      apply (rule cong_scalar2_nat)
       
   700      apply (rule \<open>[b1 = 1] (mod m1)\<close>)
       
   701     apply (rule cong_scalar2_nat)
       
   702     apply (rule \<open>[b2 = 0] (mod m1)\<close>)
       
   703     done
       
   704   then have "[?x = u1] (mod m1)" by simp
   601   then have "[?x = u1] (mod m1)" by simp
   705   have "[?x = u1 * 0 + u2 * 1] (mod m2)"
   602   have "[?x = u1 * 0 + u2 * 1] (mod m2)"
   706     apply (rule cong_add_nat)
   603     using \<open>[b1 = 0] (mod m2)\<close> \<open>[b2 = 1] (mod m2)\<close> cong_add cong_scalar_left by blast
   707      apply (rule cong_scalar2_nat)
       
   708      apply (rule \<open>[b1 = 0] (mod m2)\<close>)
       
   709     apply (rule cong_scalar2_nat)
       
   710     apply (rule \<open>[b2 = 1] (mod m2)\<close>)
       
   711     done
       
   712   then have "[?x = u2] (mod m2)"
   604   then have "[?x = u2] (mod m2)"
   713     by simp
   605     by simp
   714   with \<open>[?x = u1] (mod m1)\<close> show ?thesis
   606   with \<open>[?x = u1] (mod m1)\<close> show ?thesis
   715     by blast
   607     by blast
   716 qed
   608 qed
   724     where "[b1 = 1] (mod m1)" and "[b1 = 0] (mod m2)"
   616     where "[b1 = 1] (mod m1)" and "[b1 = 0] (mod m2)"
   725       and "[b2 = 0] (mod m1)" and "[b2 = 1] (mod m2)"
   617       and "[b2 = 0] (mod m1)" and "[b2 = 1] (mod m2)"
   726     by blast
   618     by blast
   727   let ?x = "u1 * b1 + u2 * b2"
   619   let ?x = "u1 * b1 + u2 * b2"
   728   have "[?x = u1 * 1 + u2 * 0] (mod m1)"
   620   have "[?x = u1 * 1 + u2 * 0] (mod m1)"
   729     apply (rule cong_add_int)
   621     using \<open>[b1 = 1] (mod m1)\<close> \<open>[b2 = 0] (mod m1)\<close> cong_add cong_scalar_left by blast
   730      apply (rule cong_scalar2_int)
       
   731      apply (rule \<open>[b1 = 1] (mod m1)\<close>)
       
   732     apply (rule cong_scalar2_int)
       
   733     apply (rule \<open>[b2 = 0] (mod m1)\<close>)
       
   734     done
       
   735   then have "[?x = u1] (mod m1)" by simp
   622   then have "[?x = u1] (mod m1)" by simp
   736   have "[?x = u1 * 0 + u2 * 1] (mod m2)"
   623   have "[?x = u1 * 0 + u2 * 1] (mod m2)"
   737     apply (rule cong_add_int)
   624     using \<open>[b1 = 0] (mod m2)\<close> \<open>[b2 = 1] (mod m2)\<close> cong_add cong_scalar_left by blast
   738      apply (rule cong_scalar2_int)
       
   739      apply (rule \<open>[b1 = 0] (mod m2)\<close>)
       
   740     apply (rule cong_scalar2_int)
       
   741     apply (rule \<open>[b2 = 1] (mod m2)\<close>)
       
   742     done
       
   743   then have "[?x = u2] (mod m2)" by simp
   625   then have "[?x = u2] (mod m2)" by simp
   744   with \<open>[?x = u1] (mod m1)\<close> show ?thesis
   626   with \<open>[?x = u1] (mod m1)\<close> show ?thesis
   745     by blast
   627     by blast
   746 qed
   628 qed
   747 
   629 
   748 lemma cong_modulus_mult_nat: "[x = y] (mod m * n) \<Longrightarrow> [x = y] (mod m)"
   630 lemma cong_modulus_mult_nat: "[x = y] (mod m * n) \<Longrightarrow> [x = y] (mod m)"
   749   for x y :: nat
   631   for x y :: nat
   750   apply (cases "y \<le> x")
   632   apply (cases "y \<le> x")
   751    apply (simp add: cong_altdef_nat)
   633    apply (simp add: cong_altdef_nat)
   752    apply (erule dvd_mult_left)
   634    apply (erule dvd_mult_left)
   753   apply (rule cong_sym_nat)
   635   apply (rule cong_sym)
   754   apply (subst (asm) cong_sym_eq_nat)
   636   apply (subst (asm) cong_sym_eq)
   755   apply (simp add: cong_altdef_nat)
   637   apply (simp add: cong_altdef_nat)
   756   apply (erule dvd_mult_left)
   638   apply (erule dvd_mult_left)
   757   done
   639   done
   758 
   640 
   759 lemma cong_modulus_mult_int: "[x = y] (mod m * n) \<Longrightarrow> [x = y] (mod m)"
   641 lemma cong_modulus_mult_int: "[x = y] (mod m * n) \<Longrightarrow> [x = y] (mod m)"
   762   apply (erule dvd_mult_left)
   644   apply (erule dvd_mult_left)
   763   done
   645   done
   764 
   646 
   765 lemma cong_less_modulus_unique_nat: "[x = y] (mod m) \<Longrightarrow> x < m \<Longrightarrow> y < m \<Longrightarrow> x = y"
   647 lemma cong_less_modulus_unique_nat: "[x = y] (mod m) \<Longrightarrow> x < m \<Longrightarrow> y < m \<Longrightarrow> x = y"
   766   for x y :: nat
   648   for x y :: nat
   767   by (simp add: cong_nat_def)
   649   by (simp add: cong_def)
   768 
   650 
   769 lemma binary_chinese_remainder_unique_nat:
   651 lemma binary_chinese_remainder_unique_nat:
   770   fixes m1 m2 :: nat
   652   fixes m1 m2 :: nat
   771   assumes a: "coprime m1 m2"
   653   assumes a: "coprime m1 m2"
   772     and nz: "m1 \<noteq> 0" "m2 \<noteq> 0"
   654     and nz: "m1 \<noteq> 0" "m2 \<noteq> 0"
   777     by blast
   659     by blast
   778   let ?x = "y mod (m1 * m2)"
   660   let ?x = "y mod (m1 * m2)"
   779   from nz have less: "?x < m1 * m2"
   661   from nz have less: "?x < m1 * m2"
   780     by auto
   662     by auto
   781   have 1: "[?x = u1] (mod m1)"
   663   have 1: "[?x = u1] (mod m1)"
   782     apply (rule cong_trans_nat)
   664     apply (rule cong_trans)
   783      prefer 2
   665      prefer 2
   784      apply (rule \<open>[y = u1] (mod m1)\<close>)
   666      apply (rule \<open>[y = u1] (mod m1)\<close>)
   785     apply (rule cong_modulus_mult_nat)
   667     apply (rule cong_modulus_mult_nat [of _ _ _ m2])
   786     apply (rule cong_mod_nat)
   668     apply simp
   787     using nz apply auto
       
   788     done
   669     done
   789   have 2: "[?x = u2] (mod m2)"
   670   have 2: "[?x = u2] (mod m2)"
   790     apply (rule cong_trans_nat)
   671     apply (rule cong_trans)
   791      prefer 2
   672      prefer 2
   792      apply (rule \<open>[y = u2] (mod m2)\<close>)
   673      apply (rule \<open>[y = u2] (mod m2)\<close>)
   793     apply (subst mult.commute)
   674     apply (subst mult.commute)
   794     apply (rule cong_modulus_mult_nat)
   675     apply (rule cong_modulus_mult_nat [of _ _ _ m1])
   795     apply (rule cong_mod_nat)
   676     apply simp
   796     using nz apply auto
       
   797     done
   677     done
   798   have "\<forall>z. z < m1 * m2 \<and> [z = u1] (mod m1) \<and> [z = u2] (mod m2) \<longrightarrow> z = ?x"
   678   have "\<forall>z. z < m1 * m2 \<and> [z = u1] (mod m1) \<and> [z = u2] (mod m2) \<longrightarrow> z = ?x"
   799   proof clarify
   679   proof clarify
   800     fix z
   680     fix z
   801     assume "z < m1 * m2"
   681     assume "z < m1 * m2"
   802     assume "[z = u1] (mod m1)" and  "[z = u2] (mod m2)"
   682     assume "[z = u1] (mod m1)" and  "[z = u2] (mod m2)"
   803     have "[?x = z] (mod m1)"
   683     have "[?x = z] (mod m1)"
   804       apply (rule cong_trans_nat)
   684       apply (rule cong_trans)
   805        apply (rule \<open>[?x = u1] (mod m1)\<close>)
   685        apply (rule \<open>[?x = u1] (mod m1)\<close>)
   806       apply (rule cong_sym_nat)
   686       apply (rule cong_sym)
   807       apply (rule \<open>[z = u1] (mod m1)\<close>)
   687       apply (rule \<open>[z = u1] (mod m1)\<close>)
   808       done
   688       done
   809     moreover have "[?x = z] (mod m2)"
   689     moreover have "[?x = z] (mod m2)"
   810       apply (rule cong_trans_nat)
   690       apply (rule cong_trans)
   811        apply (rule \<open>[?x = u2] (mod m2)\<close>)
   691        apply (rule \<open>[?x = u2] (mod m2)\<close>)
   812       apply (rule cong_sym_nat)
   692       apply (rule cong_sym)
   813       apply (rule \<open>[z = u2] (mod m2)\<close>)
   693       apply (rule \<open>[z = u2] (mod m2)\<close>)
   814       done
   694       done
   815     ultimately have "[?x = z] (mod m1 * m2)"
   695     ultimately have "[?x = z] (mod m1 * m2)"
   816       by (auto intro: coprime_cong_mult_nat a)
   696       using a by (auto intro: coprime_cong_mult_nat simp add: mod_mult_cong_left mod_mult_cong_right)
   817     with \<open>z < m1 * m2\<close> \<open>?x < m1 * m2\<close> show "z = ?x"
   697     with \<open>z < m1 * m2\<close> \<open>?x < m1 * m2\<close> show "z = ?x"
   818       apply (intro cong_less_modulus_unique_nat)
   698       apply (intro cong_less_modulus_unique_nat)
   819         apply (auto, erule cong_sym_nat)
   699         apply (auto, erule cong_sym)
   820       done
   700       done
   821   qed
   701   qed
   822   with less 1 2 show ?thesis by auto
   702   with less 1 2 show ?thesis by auto
   823  qed
   703  qed
   824 
   704 
   836   then have "\<exists>x. [(\<Prod>j \<in> A - {i}. m j) * x = 1] (mod m i)"
   716   then have "\<exists>x. [(\<Prod>j \<in> A - {i}. m j) * x = 1] (mod m i)"
   837     by (elim cong_solve_coprime_nat)
   717     by (elim cong_solve_coprime_nat)
   838   then obtain x where "[(\<Prod>j \<in> A - {i}. m j) * x = 1] (mod m i)"
   718   then obtain x where "[(\<Prod>j \<in> A - {i}. m j) * x = 1] (mod m i)"
   839     by auto
   719     by auto
   840   moreover have "[(\<Prod>j \<in> A - {i}. m j) * x = 0] (mod (\<Prod>j \<in> A - {i}. m j))"
   720   moreover have "[(\<Prod>j \<in> A - {i}. m j) * x = 0] (mod (\<Prod>j \<in> A - {i}. m j))"
   841     by (subst mult.commute, rule cong_mult_self_nat)
   721     by (simp add: cong_0_iff)
   842   ultimately show "\<exists>a. [a = 1] (mod m i) \<and> [a = 0] (mod prod m (A - {i}))"
   722   ultimately show "\<exists>a. [a = 1] (mod m i) \<and> [a = 0] (mod prod m (A - {i}))"
   843     by blast
   723     by blast
   844 qed
   724 qed
   845 
   725 
   846 lemma chinese_remainder_nat:
   726 lemma chinese_remainder_nat:
   865         by (subst sum.union_disjoint [symmetric]) (auto intro: sum.cong)
   745         by (subst sum.union_disjoint [symmetric]) (auto intro: sum.cong)
   866       then have "[?x = u i * b i + (\<Sum>j \<in> A - {i}. u j * b j)] (mod m i)"
   746       then have "[?x = u i * b i + (\<Sum>j \<in> A - {i}. u j * b j)] (mod m i)"
   867         by auto
   747         by auto
   868       also have "[u i * b i + (\<Sum>j \<in> A - {i}. u j * b j) =
   748       also have "[u i * b i + (\<Sum>j \<in> A - {i}. u j * b j) =
   869                   u i * 1 + (\<Sum>j \<in> A - {i}. u j * 0)] (mod m i)"
   749                   u i * 1 + (\<Sum>j \<in> A - {i}. u j * 0)] (mod m i)"
   870         apply (rule cong_add_nat)
   750         apply (rule cong_add)
   871          apply (rule cong_scalar2_nat)
   751          apply (rule cong_scalar_left)
   872         using b a apply blast
   752         using b a apply blast
   873         apply (rule cong_sum_nat)
   753         apply (rule cong_sum)
   874         apply (rule cong_scalar2_nat)
   754         apply (rule cong_scalar_left)
   875         using b apply auto
   755         using b apply auto
   876         apply (rule cong_dvd_modulus_nat)
   756         apply (rule cong_dvd_modulus_nat)
   877          apply (drule (1) bspec)
   757          apply (drule (1) bspec)
   878          apply (erule conjE)
   758          apply (erule conjE)
   879          apply assumption
   759          apply assumption
   884         by simp
   764         by simp
   885     qed
   765     qed
   886   qed
   766   qed
   887 qed
   767 qed
   888 
   768 
   889 lemma coprime_cong_prod_nat [rule_format]: "finite A \<Longrightarrow>
   769 lemma coprime_cong_prod_nat:
   890     (\<forall>i\<in>A. (\<forall>j\<in>A. i \<noteq> j \<longrightarrow> coprime (m i) (m j))) \<longrightarrow>
   770   "[x = y] (mod (\<Prod>i\<in>A. m i))"
   891       (\<forall>i\<in>A. [(x::nat) = y] (mod m i)) \<longrightarrow>
   771   if "\<forall>i\<in>A. (\<forall>j\<in>A. i \<noteq> j \<longrightarrow> coprime (m i) (m j))"
   892          [x = y] (mod (\<Prod>i\<in>A. m i))"
   772     and "\<forall>i\<in>A. [x = y] (mod m i)" for x y :: nat
   893   apply (induct set: finite)
   773   using that apply (induct A rule: infinite_finite_induct)
   894   apply auto
   774   apply auto
   895   apply (metis One_nat_def coprime_cong_mult_nat gcd.commute prod_coprime)
   775   apply (metis One_nat_def coprime_cong_mult_nat gcd.commute prod_coprime)
   896   done
   776   done
   897 
   777 
   898 lemma chinese_remainder_unique_nat:
   778 lemma chinese_remainder_unique_nat:
   912     by auto
   792     by auto
   913   then have less: "?x < (\<Prod>i\<in>A. m i)"
   793   then have less: "?x < (\<Prod>i\<in>A. m i)"
   914     by auto
   794     by auto
   915   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)"
   916     apply auto
   796     apply auto
   917     apply (rule cong_trans_nat)
   797     apply (rule cong_trans)
   918      prefer 2
   798      prefer 2
   919     using one apply auto
   799     using one apply auto
   920     apply (rule cong_dvd_modulus_nat)
   800     apply (rule cong_dvd_modulus_nat [of _ _ "prod m A"])
   921      apply (rule cong_mod_nat)
   801      apply simp
   922     using prodnz apply auto
   802     using fin apply auto
   923     apply rule
       
   924      apply (rule fin)
       
   925     apply assumption
       
   926     done
   803     done
   927   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"
   804   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"
   928   proof clarify
   805   proof clarify
   929     fix z
   806     fix z
   930     assume zless: "z < (\<Prod>i\<in>A. m i)"
   807     assume zless: "z < (\<Prod>i\<in>A. m i)"
   931     assume zcong: "(\<forall>i\<in>A. [z = u i] (mod m i))"
   808     assume zcong: "(\<forall>i\<in>A. [z = u i] (mod m i))"
   932     have "\<forall>i\<in>A. [?x = z] (mod m i)"
   809     have "\<forall>i\<in>A. [?x = z] (mod m i)"
   933       apply clarify
   810       apply clarify
   934       apply (rule cong_trans_nat)
   811       apply (rule cong_trans)
   935       using cong apply (erule bspec)
   812       using cong apply (erule bspec)
   936       apply (rule cong_sym_nat)
   813       apply (rule cong_sym)
   937       using zcong apply auto
   814       using zcong apply auto
   938       done
   815       done
   939     with fin cop have "[?x = z] (mod (\<Prod>i\<in>A. m i))"
   816     with fin cop have "[?x = z] (mod (\<Prod>i\<in>A. m i))"
   940       apply (intro coprime_cong_prod_nat)
   817       apply (intro coprime_cong_prod_nat)
   941         apply auto
   818         apply auto
   942       done
   819       done
   943     with zless less show "z = ?x"
   820     with zless less show "z = ?x"
   944       apply (intro cong_less_modulus_unique_nat)
   821       apply (intro cong_less_modulus_unique_nat)
   945         apply auto
   822         apply auto
   946       apply (erule cong_sym_nat)
   823       apply (erule cong_sym)
   947       done
   824       done
   948   qed
   825   qed
   949   from less cong unique show ?thesis
   826   from less cong unique show ?thesis
   950     by blast
   827     by blast
   951 qed
   828 qed