changeset 66888 | 930abfdf8727 |
parent 66837 | 6ba663ff2b1c |
child 66954 | 0230af0f3c59 |
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 |