164 done |
164 done |
165 |
165 |
166 lemma zprime_imp_zrelprime: |
166 lemma zprime_imp_zrelprime: |
167 "zprime p ==> \<not> p dvd n ==> zgcd (n, p) = 1" |
167 "zprime p ==> \<not> p dvd n ==> zgcd (n, p) = 1" |
168 apply (auto simp add: zprime_def) |
168 apply (auto simp add: zprime_def) |
169 apply (drule_tac x = "zgcd(n, p)" in allE) |
169 apply (metis zgcd_commute zgcd_geq_zero zgcd_zdvd1 zgcd_zdvd2) |
170 apply (auto simp add: zgcd_zdvd2 [of n p] zgcd_geq_zero) |
|
171 apply (insert zgcd_zdvd1 [of n p], auto) |
|
172 done |
170 done |
173 |
171 |
174 lemma zless_zprime_imp_zrelprime: |
172 lemma zless_zprime_imp_zrelprime: |
175 "zprime p ==> 0 < n ==> n < p ==> zgcd (n, p) = 1" |
173 "zprime p ==> 0 < n ==> n < p ==> zgcd (n, p) = 1" |
176 apply (erule zprime_imp_zrelprime) |
174 apply (erule zprime_imp_zrelprime) |
177 apply (erule zdvd_not_zless, assumption) |
175 apply (erule zdvd_not_zless, assumption) |
178 done |
176 done |
179 |
177 |
180 lemma zprime_zdvd_zmult: |
178 lemma zprime_zdvd_zmult: |
181 "0 \<le> (m::int) ==> zprime p ==> p dvd m * n ==> p dvd m \<or> p dvd n" |
179 "0 \<le> (m::int) ==> zprime p ==> p dvd m * n ==> p dvd m \<or> p dvd n" |
182 apply safe |
180 by (metis igcd_dvd1 igcd_dvd2 igcd_pos zprime_def zrelprime_dvd_mult) |
183 apply (rule zrelprime_zdvd_zmult) |
|
184 apply (rule zprime_imp_zrelprime, auto) |
|
185 done |
|
186 |
181 |
187 lemma zgcd_zadd_zmult [simp]: "zgcd (m + n * k, n) = zgcd (m, n)" |
182 lemma zgcd_zadd_zmult [simp]: "zgcd (m + n * k, n) = zgcd (m, n)" |
188 apply (rule zgcd_eq [THEN trans]) |
183 apply (rule zgcd_eq [THEN trans]) |
189 apply (simp add: zmod_zadd1_eq) |
184 apply (simp add: zmod_zadd1_eq) |
190 apply (rule zgcd_eq [symmetric]) |
185 apply (rule zgcd_eq [symmetric]) |
199 "zgcd (k, n) = 1 ==> zgcd (k * m, n) dvd zgcd (m, n)" |
194 "zgcd (k, n) = 1 ==> zgcd (k * m, n) dvd zgcd (m, n)" |
200 apply (simp add: zgcd_greatest_iff) |
195 apply (simp add: zgcd_greatest_iff) |
201 apply (rule_tac n = k in zrelprime_zdvd_zmult) |
196 apply (rule_tac n = k in zrelprime_zdvd_zmult) |
202 prefer 2 |
197 prefer 2 |
203 apply (simp add: zmult_commute) |
198 apply (simp add: zmult_commute) |
204 apply (subgoal_tac "zgcd (k, zgcd (k * m, n)) = zgcd (k * m, zgcd (k, n))") |
199 apply (metis zgcd_1 zgcd_commute zgcd_left_commute) |
205 apply simp |
|
206 apply (simp (no_asm) add: zgcd_ac) |
|
207 done |
200 done |
208 |
201 |
209 lemma zgcd_zmult_cancel: "zgcd (k, n) = 1 ==> zgcd (k * m, n) = zgcd (m, n)" |
202 lemma zgcd_zmult_cancel: "zgcd (k, n) = 1 ==> zgcd (k * m, n) = zgcd (m, n)" |
210 by (simp add: zgcd_def nat_abs_mult_distrib gcd_mult_cancel) |
203 by (simp add: zgcd_def nat_abs_mult_distrib gcd_mult_cancel) |
211 |
204 |
212 lemma zgcd_zgcd_zmult: |
205 lemma zgcd_zgcd_zmult: |
213 "zgcd (k, m) = 1 ==> zgcd (n, m) = 1 ==> zgcd (k * n, m) = 1" |
206 "zgcd (k, m) = 1 ==> zgcd (n, m) = 1 ==> zgcd (k * n, m) = 1" |
214 by (simp add: zgcd_zmult_cancel) |
207 by (simp add: zgcd_zmult_cancel) |
215 |
208 |
216 lemma zdvd_iff_zgcd: "0 < m ==> (m dvd n) = (zgcd (n, m) = m)" |
209 lemma zdvd_iff_zgcd: "0 < m ==> (m dvd n) = (zgcd (n, m) = m)" |
217 apply safe |
210 by (metis abs_of_pos zdvd_mult_div_cancel zgcd_0 zgcd_commute zgcd_geq_zero zgcd_zdvd2 zgcd_zmult_eq_self) |
218 apply (rule_tac [2] n = "zgcd (n, m)" in zdvd_trans) |
211 |
219 apply (rule_tac [3] zgcd_zdvd1, simp_all) |
|
220 apply (unfold dvd_def, auto) |
|
221 done |
|
222 |
212 |
223 |
213 |
224 subsection {* Congruences *} |
214 subsection {* Congruences *} |
225 |
215 |
226 lemma zcong_1 [simp]: "[a = b] (mod 1)" |
216 lemma zcong_1 [simp]: "[a = b] (mod 1)" |
255 apply (simp add: zadd_ac zadd_zmult_distrib2) |
245 apply (simp add: zadd_ac zadd_zmult_distrib2) |
256 done |
246 done |
257 |
247 |
258 lemma zcong_zmult: |
248 lemma zcong_zmult: |
259 "[a = b] (mod m) ==> [c = d] (mod m) ==> [a * c = b * d] (mod m)" |
249 "[a = b] (mod m) ==> [c = d] (mod m) ==> [a * c = b * d] (mod m)" |
|
250 |
260 apply (rule_tac b = "b * c" in zcong_trans) |
251 apply (rule_tac b = "b * c" in zcong_trans) |
261 apply (unfold zcong_def) |
252 apply (unfold zcong_def) |
262 apply (rule_tac s = "c * (a - b)" in subst) |
253 apply (metis zdiff_zmult_distrib2 zdvd_zmult zmult_commute) |
263 apply (rule_tac [3] s = "b * (c - d)" in subst) |
254 apply (metis zdiff_zmult_distrib2 zdvd_zmult) |
264 prefer 4 |
|
265 apply (blast intro: zdvd_zmult) |
|
266 prefer 2 |
|
267 apply (blast intro: zdvd_zmult) |
|
268 apply (simp_all add: zdiff_zmult_distrib2 zmult_commute) |
|
269 done |
255 done |
270 |
256 |
271 lemma zcong_scalar: "[a = b] (mod m) ==> [a * k = b * k] (mod m)" |
257 lemma zcong_scalar: "[a = b] (mod m) ==> [a * k = b * k] (mod m)" |
272 by (rule zcong_zmult, simp_all) |
258 by (rule zcong_zmult, simp_all) |
273 |
259 |
317 ==> [a = b] (mod m * n)" |
303 ==> [a = b] (mod m * n)" |
318 apply (unfold zcong_def dvd_def, auto) |
304 apply (unfold zcong_def dvd_def, auto) |
319 apply (subgoal_tac "m dvd n * ka") |
305 apply (subgoal_tac "m dvd n * ka") |
320 apply (subgoal_tac "m dvd ka") |
306 apply (subgoal_tac "m dvd ka") |
321 apply (case_tac [2] "0 \<le> ka") |
307 apply (case_tac [2] "0 \<le> ka") |
322 prefer 3 |
308 apply (metis zdvd_mult_div_cancel zdvd_refl zdvd_zminus2_iff zdvd_zmultD2 zgcd_zminus zmult_commute zmult_zminus zrelprime_zdvd_zmult) |
323 apply (subst zdvd_zminus_iff [symmetric]) |
309 apply (metis IntDiv.zdvd_abs1 abs_of_nonneg zadd_0 zgcd_0_left zgcd_commute zgcd_zadd_zmult zgcd_zdvd_zgcd_zmult zgcd_zmult_distrib2_abs zmult_1_right zmult_commute) |
324 apply (rule_tac n = n in zrelprime_zdvd_zmult) |
310 apply (metis abs_eq_0 int_0_neq_1 mult_le_0_iff zdvd_mono zdvd_mult_cancel zdvd_mult_cancel1 zdvd_refl zdvd_triv_left zdvd_zmult2 zero_le_mult_iff zgcd_greatest_iff zle_anti_sym zle_linear zle_refl zmult_commute zrelprime_zdvd_zmult) |
325 apply (simp add: zgcd_commute) |
311 apply (metis zdvd_triv_left) |
326 apply (simp add: zmult_commute zdvd_zminus_iff) |
|
327 prefer 2 |
|
328 apply (rule_tac n = n in zrelprime_zdvd_zmult) |
|
329 apply (simp add: zgcd_commute) |
|
330 apply (simp add: zmult_commute) |
|
331 apply (auto simp add: dvd_def) |
|
332 done |
312 done |
333 |
313 |
334 lemma zcong_zless_imp_eq: |
314 lemma zcong_zless_imp_eq: |
335 "0 \<le> a ==> |
315 "0 \<le> a ==> |
336 a < m ==> 0 \<le> b ==> b < m ==> [a = b] (mod m) ==> a = b" |
316 a < m ==> 0 \<le> b ==> b < m ==> [a = b] (mod m) ==> a = b" |
337 apply (unfold zcong_def dvd_def, auto) |
317 apply (unfold zcong_def dvd_def, auto) |
338 apply (drule_tac f = "\<lambda>z. z mod m" in arg_cong) |
318 apply (drule_tac f = "\<lambda>z. z mod m" in arg_cong) |
339 apply (cut_tac x = a and y = b in linorder_less_linear, auto) |
319 apply (metis diff_add_cancel mod_pos_pos_trivial zadd_0 zadd_commute zmod_eq_0_iff zmod_zadd_right_eq) |
340 apply (subgoal_tac [2] "(a - b) mod m = a - b") |
|
341 apply (rule_tac [3] mod_pos_pos_trivial, auto) |
|
342 apply (subgoal_tac "(m + (a - b)) mod m = m + (a - b)") |
|
343 apply (rule_tac [2] mod_pos_pos_trivial, auto) |
|
344 done |
320 done |
345 |
321 |
346 lemma zcong_square_zless: |
322 lemma zcong_square_zless: |
347 "zprime p ==> 0 < a ==> a < p ==> |
323 "zprime p ==> 0 < a ==> a < p ==> |
348 [a * a = 1] (mod p) ==> a = 1 \<or> a = p - 1" |
324 [a * a = 1] (mod p) ==> a = 1 \<or> a = p - 1" |
358 done |
334 done |
359 |
335 |
360 lemma zcong_zless_0: |
336 lemma zcong_zless_0: |
361 "0 \<le> a ==> a < m ==> [a = 0] (mod m) ==> a = 0" |
337 "0 \<le> a ==> a < m ==> [a = 0] (mod m) ==> a = 0" |
362 apply (unfold zcong_def dvd_def, auto) |
338 apply (unfold zcong_def dvd_def, auto) |
363 apply (subgoal_tac "0 < m") |
339 apply (metis div_pos_pos_trivial linorder_not_less zdiv_zmult_self2 zle_refl zle_trans) |
364 apply (simp add: zero_le_mult_iff) |
|
365 apply (subgoal_tac "m * k < m * 1") |
|
366 apply (drule mult_less_cancel_left [THEN iffD1]) |
|
367 apply (auto simp add: linorder_neq_iff) |
|
368 done |
340 done |
369 |
341 |
370 lemma zcong_zless_unique: |
342 lemma zcong_zless_unique: |
371 "0 < m ==> (\<exists>!b. 0 \<le> b \<and> b < m \<and> [a = b] (mod m))" |
343 "0 < m ==> (\<exists>!b. 0 \<le> b \<and> b < m \<and> [a = b] (mod m))" |
372 apply auto |
344 apply auto |
373 apply (subgoal_tac [2] "[b = y] (mod m)") |
345 prefer 2 apply (metis zcong_sym zcong_trans zcong_zless_imp_eq) |
374 apply (case_tac [2] "b = 0") |
|
375 apply (case_tac [3] "y = 0") |
|
376 apply (auto intro: zcong_trans zcong_zless_0 zcong_zless_imp_eq order_less_le |
|
377 simp add: zcong_sym) |
|
378 apply (unfold zcong_def dvd_def) |
346 apply (unfold zcong_def dvd_def) |
379 apply (rule_tac x = "a mod m" in exI, auto) |
347 apply (rule_tac x = "a mod m" in exI, auto) |
380 apply (rule_tac x = "-(a div m)" in exI) |
348 apply (metis zmult_div_cancel) |
381 apply (simp add: diff_eq_eq eq_diff_eq add_commute) |
|
382 done |
349 done |
383 |
350 |
384 lemma zcong_iff_lin: "([a = b] (mod m)) = (\<exists>k. b = a + m * k)" |
351 lemma zcong_iff_lin: "([a = b] (mod m)) = (\<exists>k. b = a + m * k)" |
385 apply (unfold zcong_def dvd_def, auto) |
352 apply (unfold zcong_def dvd_def, auto) |
386 apply (rule_tac [!] x = "-k" in exI, auto) |
353 apply (rule_tac [!] x = "-k" in exI, auto) |
404 apply (simp add: zadd_commute) |
371 apply (simp add: zadd_commute) |
405 done |
372 done |
406 |
373 |
407 lemma zcong_zmod_eq: "0 < m ==> [a = b] (mod m) = (a mod m = b mod m)" |
374 lemma zcong_zmod_eq: "0 < m ==> [a = b] (mod m) = (a mod m = b mod m)" |
408 apply auto |
375 apply auto |
409 apply (rule_tac m = m in zcong_zless_imp_eq) |
376 apply (metis pos_mod_conj zcong_zless_imp_eq zcong_zmod) |
410 prefer 5 |
377 apply (metis zcong_refl zcong_zmod) |
411 apply (subst zcong_zmod [symmetric], simp_all) |
|
412 apply (unfold zcong_def dvd_def) |
|
413 apply (rule_tac x = "a div m - b div m" in exI) |
|
414 apply (rule_tac m1 = m in zcong_zmod_aux [THEN trans], auto) |
|
415 done |
378 done |
416 |
379 |
417 lemma zcong_zminus [iff]: "[a = b] (mod -m) = [a = b] (mod m)" |
380 lemma zcong_zminus [iff]: "[a = b] (mod -m) = [a = b] (mod m)" |
418 by (auto simp add: zcong_def) |
381 by (auto simp add: zcong_def) |
419 |
382 |
455 (\<exists>sn tn. xzgcda (m, n, r', r, s', s, t', t) = (k, sn, tn))" |
418 (\<exists>sn tn. xzgcda (m, n, r', r, s', s, t', t) = (k, sn, tn))" |
456 apply (rule_tac u = m and v = n and w = r' and x = r and y = s' and |
419 apply (rule_tac u = m and v = n and w = r' and x = r and y = s' and |
457 z = s and aa = t' and ab = t in xzgcda.induct) |
420 z = s and aa = t' and ab = t in xzgcda.induct) |
458 apply (subst zgcd_eq) |
421 apply (subst zgcd_eq) |
459 apply (subst xzgcda.simps, auto) |
422 apply (subst xzgcda.simps, auto) |
460 apply (case_tac "r' mod r = 0") |
423 apply (metis abs_of_pos pos_mod_conj simps zgcd_0 zgcd_eq zle_refl zless_le) |
461 prefer 2 |
|
462 apply (frule_tac a = "r'" in pos_mod_sign, auto) |
|
463 apply (rule exI) |
|
464 apply (rule exI) |
|
465 apply (subst xzgcda.simps, auto) |
|
466 done |
424 done |
467 |
425 |
468 lemma xzgcd_correct_aux2: |
426 lemma xzgcd_correct_aux2: |
469 "(\<exists>sn tn. xzgcda (m, n, r', r, s', s, t', t) = (k, sn, tn)) --> 0 < r --> |
427 "(\<exists>sn tn. xzgcda (m, n, r', r, s', s, t', t) = (k, sn, tn)) --> 0 < r --> |
470 zgcd (r', r) = k" |
428 zgcd (r', r) = k" |
474 apply (subst xzgcda.simps) |
432 apply (subst xzgcda.simps) |
475 apply (auto simp add: linorder_not_le) |
433 apply (auto simp add: linorder_not_le) |
476 apply (case_tac "r' mod r = 0") |
434 apply (case_tac "r' mod r = 0") |
477 prefer 2 |
435 prefer 2 |
478 apply (frule_tac a = "r'" in pos_mod_sign, auto) |
436 apply (frule_tac a = "r'" in pos_mod_sign, auto) |
479 apply (erule_tac P = "xzgcda ?u = ?v" in rev_mp) |
437 apply (metis Pair_eq simps zle_refl) |
480 apply (subst xzgcda.simps, auto) |
|
481 done |
438 done |
482 |
439 |
483 lemma xzgcd_correct: |
440 lemma xzgcd_correct: |
484 "0 < n ==> (zgcd (m, n) = k) = (\<exists>s t. xzgcd m n = (k, s, t))" |
441 "0 < n ==> (zgcd (m, n) = k) = (\<exists>s t. xzgcd m n = (k, s, t))" |
485 apply (unfold xzgcd_def) |
442 apply (unfold xzgcd_def) |
559 prefer 2 |
516 prefer 2 |
560 apply (simp add: zcong_sym) |
517 apply (simp add: zcong_sym) |
561 apply (cut_tac a = a and n = n in zcong_lineq_ex, auto) |
518 apply (cut_tac a = a and n = n in zcong_lineq_ex, auto) |
562 apply (rule_tac x = "x * b mod n" in exI, safe) |
519 apply (rule_tac x = "x * b mod n" in exI, safe) |
563 apply (simp_all (no_asm_simp)) |
520 apply (simp_all (no_asm_simp)) |
564 apply (subst zcong_zmod) |
521 apply (metis zcong_scalar zcong_zmod zmod_zmult1_eq zmult_1 zmult_assoc) |
565 apply (subst zmod_zmult1_eq [symmetric]) |
|
566 apply (subst zcong_zmod [symmetric]) |
|
567 apply (subgoal_tac "[a * x * b = 1 * b] (mod n)") |
|
568 apply (rule_tac [2] zcong_zmult) |
|
569 apply (simp_all add: zmult_assoc) |
|
570 done |
522 done |
571 |
523 |
572 end |
524 end |