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