21 extended to the natural numbers by Chaieb. Jeremy Avigad combined |
21 extended to the natural numbers by Chaieb. Jeremy Avigad combined |
22 these, revised and tidied them, made the development uniform for the |
22 these, revised and tidied them, made the development uniform for the |
23 natural numbers and the integers, and added a number of new theorems. |
23 natural numbers and the integers, and added a number of new theorems. |
24 *) |
24 *) |
25 |
25 |
26 section {* Congruence *} |
26 section \<open>Congruence\<close> |
27 |
27 |
28 theory Cong |
28 theory Cong |
29 imports Primes |
29 imports Primes |
30 begin |
30 begin |
31 |
31 |
32 subsection {* Turn off @{text One_nat_def} *} |
32 subsection \<open>Turn off @{text One_nat_def}\<close> |
33 |
33 |
34 lemma power_eq_one_eq_nat [simp]: "((x::nat)^m = 1) = (m = 0 | x = 1)" |
34 lemma power_eq_one_eq_nat [simp]: "((x::nat)^m = 1) = (m = 0 | x = 1)" |
35 by (induct m) auto |
35 by (induct m) auto |
36 |
36 |
37 declare mod_pos_pos_trivial [simp] |
37 declare mod_pos_pos_trivial [simp] |
38 |
38 |
39 |
39 |
40 subsection {* Main definitions *} |
40 subsection \<open>Main definitions\<close> |
41 |
41 |
42 class cong = |
42 class cong = |
43 fixes cong :: "'a \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> bool" ("(1[_ = _] '(()mod _'))") |
43 fixes cong :: "'a \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> bool" ("(1[_ = _] '(()mod _'))") |
44 begin |
44 begin |
45 |
45 |
95 |
95 |
96 declare transfer_morphism_int_nat[transfer add return: |
96 declare transfer_morphism_int_nat[transfer add return: |
97 transfer_int_nat_cong] |
97 transfer_int_nat_cong] |
98 |
98 |
99 |
99 |
100 subsection {* Congruence *} |
100 subsection \<open>Congruence\<close> |
101 |
101 |
102 (* was zcong_0, etc. *) |
102 (* was zcong_0, etc. *) |
103 lemma cong_0_nat [simp, presburger]: "([(a::nat) = b] (mod 0)) = (a = b)" |
103 lemma cong_0_nat [simp, presburger]: "([(a::nat) = b] (mod 0)) = (a = b)" |
104 unfolding cong_nat_def by auto |
104 unfolding cong_nat_def by auto |
105 |
105 |
631 by blast |
631 by blast |
632 let ?x = "u1 * b1 + u2 * b2" |
632 let ?x = "u1 * b1 + u2 * b2" |
633 have "[?x = u1 * 1 + u2 * 0] (mod m1)" |
633 have "[?x = u1 * 1 + u2 * 0] (mod m1)" |
634 apply (rule cong_add_nat) |
634 apply (rule cong_add_nat) |
635 apply (rule cong_scalar2_nat) |
635 apply (rule cong_scalar2_nat) |
636 apply (rule `[b1 = 1] (mod m1)`) |
636 apply (rule \<open>[b1 = 1] (mod m1)\<close>) |
637 apply (rule cong_scalar2_nat) |
637 apply (rule cong_scalar2_nat) |
638 apply (rule `[b2 = 0] (mod m1)`) |
638 apply (rule \<open>[b2 = 0] (mod m1)\<close>) |
639 done |
639 done |
640 then have "[?x = u1] (mod m1)" by simp |
640 then have "[?x = u1] (mod m1)" by simp |
641 have "[?x = u1 * 0 + u2 * 1] (mod m2)" |
641 have "[?x = u1 * 0 + u2 * 1] (mod m2)" |
642 apply (rule cong_add_nat) |
642 apply (rule cong_add_nat) |
643 apply (rule cong_scalar2_nat) |
643 apply (rule cong_scalar2_nat) |
644 apply (rule `[b1 = 0] (mod m2)`) |
644 apply (rule \<open>[b1 = 0] (mod m2)\<close>) |
645 apply (rule cong_scalar2_nat) |
645 apply (rule cong_scalar2_nat) |
646 apply (rule `[b2 = 1] (mod m2)`) |
646 apply (rule \<open>[b2 = 1] (mod m2)\<close>) |
647 done |
647 done |
648 then have "[?x = u2] (mod m2)" by simp |
648 then have "[?x = u2] (mod m2)" by simp |
649 with `[?x = u1] (mod m1)` show ?thesis by blast |
649 with \<open>[?x = u1] (mod m1)\<close> show ?thesis by blast |
650 qed |
650 qed |
651 |
651 |
652 lemma binary_chinese_remainder_int: |
652 lemma binary_chinese_remainder_int: |
653 assumes a: "coprime (m1::int) m2" |
653 assumes a: "coprime (m1::int) m2" |
654 shows "EX x. [x = u1] (mod m1) \<and> [x = u2] (mod m2)" |
654 shows "EX x. [x = u1] (mod m1) \<and> [x = u2] (mod m2)" |
659 by blast |
659 by blast |
660 let ?x = "u1 * b1 + u2 * b2" |
660 let ?x = "u1 * b1 + u2 * b2" |
661 have "[?x = u1 * 1 + u2 * 0] (mod m1)" |
661 have "[?x = u1 * 1 + u2 * 0] (mod m1)" |
662 apply (rule cong_add_int) |
662 apply (rule cong_add_int) |
663 apply (rule cong_scalar2_int) |
663 apply (rule cong_scalar2_int) |
664 apply (rule `[b1 = 1] (mod m1)`) |
664 apply (rule \<open>[b1 = 1] (mod m1)\<close>) |
665 apply (rule cong_scalar2_int) |
665 apply (rule cong_scalar2_int) |
666 apply (rule `[b2 = 0] (mod m1)`) |
666 apply (rule \<open>[b2 = 0] (mod m1)\<close>) |
667 done |
667 done |
668 then have "[?x = u1] (mod m1)" by simp |
668 then have "[?x = u1] (mod m1)" by simp |
669 have "[?x = u1 * 0 + u2 * 1] (mod m2)" |
669 have "[?x = u1 * 0 + u2 * 1] (mod m2)" |
670 apply (rule cong_add_int) |
670 apply (rule cong_add_int) |
671 apply (rule cong_scalar2_int) |
671 apply (rule cong_scalar2_int) |
672 apply (rule `[b1 = 0] (mod m2)`) |
672 apply (rule \<open>[b1 = 0] (mod m2)\<close>) |
673 apply (rule cong_scalar2_int) |
673 apply (rule cong_scalar2_int) |
674 apply (rule `[b2 = 1] (mod m2)`) |
674 apply (rule \<open>[b2 = 1] (mod m2)\<close>) |
675 done |
675 done |
676 then have "[?x = u2] (mod m2)" by simp |
676 then have "[?x = u2] (mod m2)" by simp |
677 with `[?x = u1] (mod m1)` show ?thesis by blast |
677 with \<open>[?x = u1] (mod m1)\<close> show ?thesis by blast |
678 qed |
678 qed |
679 |
679 |
680 lemma cong_modulus_mult_nat: "[(x::nat) = y] (mod m * n) \<Longrightarrow> |
680 lemma cong_modulus_mult_nat: "[(x::nat) = y] (mod m * n) \<Longrightarrow> |
681 [x = y] (mod m)" |
681 [x = y] (mod m)" |
682 apply (cases "y \<le> x") |
682 apply (cases "y \<le> x") |
710 from nz have less: "?x < m1 * m2" |
710 from nz have less: "?x < m1 * m2" |
711 by auto |
711 by auto |
712 have one: "[?x = u1] (mod m1)" |
712 have one: "[?x = u1] (mod m1)" |
713 apply (rule cong_trans_nat) |
713 apply (rule cong_trans_nat) |
714 prefer 2 |
714 prefer 2 |
715 apply (rule `[y = u1] (mod m1)`) |
715 apply (rule \<open>[y = u1] (mod m1)\<close>) |
716 apply (rule cong_modulus_mult_nat) |
716 apply (rule cong_modulus_mult_nat) |
717 apply (rule cong_mod_nat) |
717 apply (rule cong_mod_nat) |
718 using nz apply auto |
718 using nz apply auto |
719 done |
719 done |
720 have two: "[?x = u2] (mod m2)" |
720 have two: "[?x = u2] (mod m2)" |
721 apply (rule cong_trans_nat) |
721 apply (rule cong_trans_nat) |
722 prefer 2 |
722 prefer 2 |
723 apply (rule `[y = u2] (mod m2)`) |
723 apply (rule \<open>[y = u2] (mod m2)\<close>) |
724 apply (subst mult.commute) |
724 apply (subst mult.commute) |
725 apply (rule cong_modulus_mult_nat) |
725 apply (rule cong_modulus_mult_nat) |
726 apply (rule cong_mod_nat) |
726 apply (rule cong_mod_nat) |
727 using nz apply auto |
727 using nz apply auto |
728 done |
728 done |
731 fix z |
731 fix z |
732 assume "z < m1 * m2" |
732 assume "z < m1 * m2" |
733 assume "[z = u1] (mod m1)" and "[z = u2] (mod m2)" |
733 assume "[z = u1] (mod m1)" and "[z = u2] (mod m2)" |
734 have "[?x = z] (mod m1)" |
734 have "[?x = z] (mod m1)" |
735 apply (rule cong_trans_nat) |
735 apply (rule cong_trans_nat) |
736 apply (rule `[?x = u1] (mod m1)`) |
736 apply (rule \<open>[?x = u1] (mod m1)\<close>) |
737 apply (rule cong_sym_nat) |
737 apply (rule cong_sym_nat) |
738 apply (rule `[z = u1] (mod m1)`) |
738 apply (rule \<open>[z = u1] (mod m1)\<close>) |
739 done |
739 done |
740 moreover have "[?x = z] (mod m2)" |
740 moreover have "[?x = z] (mod m2)" |
741 apply (rule cong_trans_nat) |
741 apply (rule cong_trans_nat) |
742 apply (rule `[?x = u2] (mod m2)`) |
742 apply (rule \<open>[?x = u2] (mod m2)\<close>) |
743 apply (rule cong_sym_nat) |
743 apply (rule cong_sym_nat) |
744 apply (rule `[z = u2] (mod m2)`) |
744 apply (rule \<open>[z = u2] (mod m2)\<close>) |
745 done |
745 done |
746 ultimately have "[?x = z] (mod m1 * m2)" |
746 ultimately have "[?x = z] (mod m1 * m2)" |
747 by (auto intro: coprime_cong_mult_nat a) |
747 by (auto intro: coprime_cong_mult_nat a) |
748 with `z < m1 * m2` `?x < m1 * m2` show "z = ?x" |
748 with \<open>z < m1 * m2\<close> \<open>?x < m1 * m2\<close> show "z = ?x" |
749 apply (intro cong_less_modulus_unique_nat) |
749 apply (intro cong_less_modulus_unique_nat) |
750 apply (auto, erule cong_sym_nat) |
750 apply (auto, erule cong_sym_nat) |
751 done |
751 done |
752 qed |
752 qed |
753 with less one two show ?thesis by auto |
753 with less one two show ?thesis by auto |