227 done |
227 done |
228 |
228 |
229 lemma cong_mult_rcancel_int: |
229 lemma cong_mult_rcancel_int: |
230 "[a * k = b * k] (mod m) \<longleftrightarrow> [a = b] (mod m)" |
230 "[a * k = b * k] (mod m) \<longleftrightarrow> [a = b] (mod m)" |
231 if "coprime k m" for a k m :: int |
231 if "coprime k m" for a k m :: int |
232 by (metis that cong_altdef_int left_diff_distrib coprime_dvd_mult_iff gcd.commute) |
232 using that by (simp add: cong_altdef_int) |
|
233 (metis coprime_commute coprime_dvd_mult_right_iff mult.commute right_diff_distrib') |
233 |
234 |
234 lemma cong_mult_rcancel_nat: |
235 lemma cong_mult_rcancel_nat: |
235 "[a * k = b * k] (mod m) \<longleftrightarrow> [a = b] (mod m)" |
236 "[a * k = b * k] (mod m) \<longleftrightarrow> [a = b] (mod m)" |
236 if "coprime k m" for a k m :: nat |
237 if "coprime k m" for a k m :: nat |
237 proof - |
238 proof - |
240 also have "\<dots> \<longleftrightarrow> m dvd nat \<bar>(int a - int b) * int k\<bar>" |
241 also have "\<dots> \<longleftrightarrow> m dvd nat \<bar>(int a - int b) * int k\<bar>" |
241 by (simp add: algebra_simps) |
242 by (simp add: algebra_simps) |
242 also have "\<dots> \<longleftrightarrow> m dvd nat \<bar>int a - int b\<bar> * k" |
243 also have "\<dots> \<longleftrightarrow> m dvd nat \<bar>int a - int b\<bar> * k" |
243 by (simp add: abs_mult nat_times_as_int) |
244 by (simp add: abs_mult nat_times_as_int) |
244 also have "\<dots> \<longleftrightarrow> m dvd nat \<bar>int a - int b\<bar>" |
245 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 by (rule coprime_dvd_mult_left_iff) (use \<open>coprime k m\<close> in \<open>simp add: ac_simps\<close>) |
246 also have "\<dots> \<longleftrightarrow> [a = b] (mod m)" |
247 also have "\<dots> \<longleftrightarrow> [a = b] (mod m)" |
247 by (simp add: cong_altdef_nat') |
248 by (simp add: cong_altdef_nat') |
248 finally show ?thesis . |
249 finally show ?thesis . |
249 qed |
250 qed |
250 |
251 |
318 for a b :: int |
319 for a b :: int |
319 by (auto simp add: cong_def) (metis gcd_red_int) |
320 by (auto simp add: cong_def) (metis gcd_red_int) |
320 |
321 |
321 lemma cong_imp_coprime_nat: "[a = b] (mod m) \<Longrightarrow> coprime a m \<Longrightarrow> coprime b m" |
322 lemma cong_imp_coprime_nat: "[a = b] (mod m) \<Longrightarrow> coprime a m \<Longrightarrow> coprime b m" |
322 for a b :: nat |
323 for a b :: nat |
323 by (auto simp add: cong_gcd_eq_nat) |
324 by (auto simp add: cong_gcd_eq_nat coprime_iff_gcd_eq_1) |
324 |
325 |
325 lemma cong_imp_coprime_int: "[a = b] (mod m) \<Longrightarrow> coprime a m \<Longrightarrow> coprime b m" |
326 lemma cong_imp_coprime_int: "[a = b] (mod m) \<Longrightarrow> coprime a m \<Longrightarrow> coprime b m" |
326 for a b :: int |
327 for a b :: int |
327 by (auto simp add: cong_gcd_eq_int) |
328 by (auto simp add: cong_gcd_eq_int coprime_iff_gcd_eq_1) |
328 |
329 |
329 lemma cong_cong_mod_nat: "[a = b] (mod m) \<longleftrightarrow> [a mod m = b mod m] (mod m)" |
330 lemma cong_cong_mod_nat: "[a = b] (mod m) \<longleftrightarrow> [a mod m = b mod m] (mod m)" |
330 for a b :: nat |
331 for a b :: nat |
331 by simp |
332 by simp |
332 |
333 |
488 finally show ?thesis |
489 finally show ?thesis |
489 by auto |
490 by auto |
490 qed |
491 qed |
491 |
492 |
492 lemma cong_solve_coprime_nat: |
493 lemma cong_solve_coprime_nat: |
493 fixes a :: nat |
494 "\<exists>x. [a * x = Suc 0] (mod n)" if "coprime a n" |
494 assumes "coprime a n" |
495 using that cong_solve_nat [of a n] by (cases "a = 0") simp_all |
495 shows "\<exists>x. [a * x = 1] (mod n)" |
496 |
496 proof (cases "a = 0") |
497 lemma cong_solve_coprime_int: |
497 case True |
498 "\<exists>x. [a * x = 1] (mod n)" if "coprime a n" for a n x :: int |
498 with assms show ?thesis |
499 using that cong_solve_int [of a n] by (cases "a = 0") |
499 by (simp add: cong_0_1_nat') |
500 (auto simp add: zabs_def split: if_splits) |
500 next |
|
501 case False |
|
502 with assms show ?thesis |
|
503 by (metis cong_solve_nat) |
|
504 qed |
|
505 |
|
506 lemma cong_solve_coprime_int: "coprime (a::int) n \<Longrightarrow> \<exists>x. [a * x = 1] (mod n)" |
|
507 apply (cases "a = 0") |
|
508 apply auto |
|
509 apply (cases "n \<ge> 0") |
|
510 apply auto |
|
511 apply (metis cong_solve_int) |
|
512 done |
|
513 |
501 |
514 lemma coprime_iff_invertible_nat: |
502 lemma coprime_iff_invertible_nat: |
515 "m > 0 \<Longrightarrow> coprime a m = (\<exists>x. [a * x = Suc 0] (mod m))" |
503 "m > 0 \<Longrightarrow> coprime a m \<longleftrightarrow> (\<exists>x. [a * x = Suc 0] (mod m))" |
516 by (metis One_nat_def cong_gcd_eq_nat cong_solve_coprime_nat coprime_lmult gcd.commute gcd_Suc_0) |
504 by (auto intro: cong_solve_coprime_nat) |
517 |
505 (use cong_imp_coprime_nat cong_sym coprime_Suc_0_left coprime_mult_left_iff in blast) |
518 lemma coprime_iff_invertible_int: "m > 0 \<Longrightarrow> coprime a m \<longleftrightarrow> (\<exists>x. [a * x = 1] (mod m))" |
506 |
|
507 lemma coprime_iff_invertible_int: |
|
508 "m > 0 \<Longrightarrow> coprime a m \<longleftrightarrow> (\<exists>x. [a * x = 1] (mod m))" |
519 for m :: int |
509 for m :: int |
520 apply (auto intro: cong_solve_coprime_int) |
510 by (auto intro: cong_solve_coprime_int) |
521 using cong_gcd_eq_int coprime_mul_eq' apply fastforce |
511 (meson cong_imp_coprime_int cong_sym coprime_1_left coprime_mult_left_iff) |
522 done |
|
523 |
512 |
524 lemma coprime_iff_invertible'_nat: |
513 lemma coprime_iff_invertible'_nat: |
525 "m > 0 \<Longrightarrow> coprime a m \<longleftrightarrow> (\<exists>x. 0 \<le> x \<and> x < m \<and> [a * x = Suc 0] (mod m))" |
514 "m > 0 \<Longrightarrow> coprime a m \<longleftrightarrow> (\<exists>x. 0 \<le> x \<and> x < m \<and> [a * x = Suc 0] (mod m))" |
526 apply (subst coprime_iff_invertible_nat) |
515 apply (subst coprime_iff_invertible_nat) |
527 apply auto |
516 apply auto |
552 "[x = y] (mod (\<Prod>i\<in>A. m i))" if |
541 "[x = y] (mod (\<Prod>i\<in>A. m i))" if |
553 "(\<forall>i\<in>A. [(x::nat) = y] (mod m i))" |
542 "(\<forall>i\<in>A. [(x::nat) = y] (mod m i))" |
554 and "(\<forall>i\<in>A. (\<forall>j\<in>A. i \<noteq> j \<longrightarrow> coprime (m i) (m j)))" |
543 and "(\<forall>i\<in>A. (\<forall>j\<in>A. i \<noteq> j \<longrightarrow> coprime (m i) (m j)))" |
555 using that apply (induct A rule: infinite_finite_induct) |
544 using that apply (induct A rule: infinite_finite_induct) |
556 apply auto |
545 apply auto |
557 apply (metis One_nat_def coprime_cong_mult_nat gcd.commute prod_coprime) |
546 apply (metis coprime_cong_mult_nat prod_coprime_right) |
558 done |
547 done |
559 |
548 |
560 lemma cong_cong_prod_coprime_int [rule_format]: |
549 lemma cong_cong_prod_coprime_int: |
561 "[x = y] (mod (\<Prod>i\<in>A. m i))" if |
550 "[x = y] (mod (\<Prod>i\<in>A. m i))" if |
562 "(\<forall>i\<in>A. [(x::int) = y] (mod m i))" |
551 "(\<forall>i\<in>A. [(x::int) = y] (mod m i))" |
563 "(\<forall>i\<in>A. (\<forall>j\<in>A. i \<noteq> j \<longrightarrow> coprime (m i) (m j)))" |
552 "(\<forall>i\<in>A. (\<forall>j\<in>A. i \<noteq> j \<longrightarrow> coprime (m i) (m j)))" |
564 using that apply (induct A rule: infinite_finite_induct) |
553 using that apply (induct A rule: infinite_finite_induct) |
565 apply auto |
554 apply auto |
566 apply (metis coprime_cong_mult_int gcd.commute prod_coprime) |
555 apply (metis coprime_cong_mult_int prod_coprime_right) |
567 done |
556 done |
568 |
557 |
569 lemma binary_chinese_remainder_aux_nat: |
558 lemma binary_chinese_remainder_aux_nat: |
570 fixes m1 m2 :: nat |
559 fixes m1 m2 :: nat |
571 assumes a: "coprime m1 m2" |
560 assumes a: "coprime m1 m2" |
572 shows "\<exists>b1 b2. [b1 = 1] (mod m1) \<and> [b1 = 0] (mod m2) \<and> [b2 = 0] (mod m1) \<and> [b2 = 1] (mod m2)" |
561 shows "\<exists>b1 b2. [b1 = 1] (mod m1) \<and> [b1 = 0] (mod m2) \<and> [b2 = 0] (mod m1) \<and> [b2 = 1] (mod m2)" |
573 proof - |
562 proof - |
574 from cong_solve_coprime_nat [OF a] obtain x1 where 1: "[m1 * x1 = 1] (mod m2)" |
563 from cong_solve_coprime_nat [OF a] obtain x1 where 1: "[m1 * x1 = 1] (mod m2)" |
575 by auto |
564 by auto |
576 from a have b: "coprime m2 m1" |
565 from a have b: "coprime m2 m1" |
577 by (subst gcd.commute) |
566 by (simp add: ac_simps) |
578 from cong_solve_coprime_nat [OF b] obtain x2 where 2: "[m2 * x2 = 1] (mod m1)" |
567 from cong_solve_coprime_nat [OF b] obtain x2 where 2: "[m2 * x2 = 1] (mod m1)" |
579 by auto |
568 by auto |
580 have "[m1 * x1 = 0] (mod m1)" |
569 have "[m1 * x1 = 0] (mod m1)" |
581 by (simp add: cong_mult_self_left) |
570 by (simp add: cong_mult_self_left) |
582 moreover have "[m2 * x2 = 0] (mod m2)" |
571 moreover have "[m2 * x2 = 0] (mod m2)" |
591 shows "\<exists>b1 b2. [b1 = 1] (mod m1) \<and> [b1 = 0] (mod m2) \<and> [b2 = 0] (mod m1) \<and> [b2 = 1] (mod m2)" |
580 shows "\<exists>b1 b2. [b1 = 1] (mod m1) \<and> [b1 = 0] (mod m2) \<and> [b2 = 0] (mod m1) \<and> [b2 = 1] (mod m2)" |
592 proof - |
581 proof - |
593 from cong_solve_coprime_int [OF a] obtain x1 where 1: "[m1 * x1 = 1] (mod m2)" |
582 from cong_solve_coprime_int [OF a] obtain x1 where 1: "[m1 * x1 = 1] (mod m2)" |
594 by auto |
583 by auto |
595 from a have b: "coprime m2 m1" |
584 from a have b: "coprime m2 m1" |
596 by (subst gcd.commute) |
585 by (simp add: ac_simps) |
597 from cong_solve_coprime_int [OF b] obtain x2 where 2: "[m2 * x2 = 1] (mod m1)" |
586 from cong_solve_coprime_int [OF b] obtain x2 where 2: "[m2 * x2 = 1] (mod m1)" |
598 by auto |
587 by auto |
599 have "[m1 * x1 = 0] (mod m1)" |
588 have "[m1 * x1 = 0] (mod m1)" |
600 by (simp add: cong_mult_self_left) |
589 by (simp add: cong_mult_self_left) |
601 moreover have "[m2 * x2 = 0] (mod m2)" |
590 moreover have "[m2 * x2 = 0] (mod m2)" |
728 shows "\<exists>b. (\<forall>i \<in> A. [b i = 1] (mod m i) \<and> [b i = 0] (mod (\<Prod>j \<in> A - {i}. m j)))" |
717 shows "\<exists>b. (\<forall>i \<in> A. [b i = 1] (mod m i) \<and> [b i = 0] (mod (\<Prod>j \<in> A - {i}. m j)))" |
729 proof (rule finite_set_choice, rule fin, rule ballI) |
718 proof (rule finite_set_choice, rule fin, rule ballI) |
730 fix i |
719 fix i |
731 assume "i \<in> A" |
720 assume "i \<in> A" |
732 with cop have "coprime (\<Prod>j \<in> A - {i}. m j) (m i)" |
721 with cop have "coprime (\<Prod>j \<in> A - {i}. m j) (m i)" |
733 by (intro prod_coprime) auto |
722 by (intro prod_coprime_left) auto |
734 then have "\<exists>x. [(\<Prod>j \<in> A - {i}. m j) * x = 1] (mod m i)" |
723 then have "\<exists>x. [(\<Prod>j \<in> A - {i}. m j) * x = Suc 0] (mod m i)" |
735 by (elim cong_solve_coprime_nat) |
724 by (elim cong_solve_coprime_nat) |
736 then obtain x where "[(\<Prod>j \<in> A - {i}. m j) * x = 1] (mod m i)" |
725 then obtain x where "[(\<Prod>j \<in> A - {i}. m j) * x = 1] (mod m i)" |
737 by auto |
726 by auto |
738 moreover have "[(\<Prod>j \<in> A - {i}. m j) * x = 0] (mod (\<Prod>j \<in> A - {i}. m j))" |
727 moreover have "[(\<Prod>j \<in> A - {i}. m j) * x = 0] (mod (\<Prod>j \<in> A - {i}. m j))" |
739 by (simp add: cong_0_iff) |
728 by (simp add: cong_0_iff) |
787 lemma coprime_cong_prod_nat: |
776 lemma coprime_cong_prod_nat: |
788 "[x = y] (mod (\<Prod>i\<in>A. m i))" |
777 "[x = y] (mod (\<Prod>i\<in>A. m i))" |
789 if "\<forall>i\<in>A. (\<forall>j\<in>A. i \<noteq> j \<longrightarrow> coprime (m i) (m j))" |
778 if "\<forall>i\<in>A. (\<forall>j\<in>A. i \<noteq> j \<longrightarrow> coprime (m i) (m j))" |
790 and "\<forall>i\<in>A. [x = y] (mod m i)" for x y :: nat |
779 and "\<forall>i\<in>A. [x = y] (mod m i)" for x y :: nat |
791 using that apply (induct A rule: infinite_finite_induct) |
780 using that apply (induct A rule: infinite_finite_induct) |
792 apply auto |
781 apply auto |
793 apply (metis One_nat_def coprime_cong_mult_nat gcd.commute prod_coprime) |
782 apply (metis coprime_cong_mult_nat prod_coprime_right) |
794 done |
783 done |
795 |
784 |
796 lemma chinese_remainder_unique_nat: |
785 lemma chinese_remainder_unique_nat: |
797 fixes A :: "'a set" |
786 fixes A :: "'a set" |
798 and m :: "'a \<Rightarrow> nat" |
787 and m :: "'a \<Rightarrow> nat" |