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)" |
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) |
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 |