270 by (fact gcd.left_idem) |
270 by (fact gcd.left_idem) |
271 |
271 |
272 lemma gcd_right_idem: "gcd (gcd a b) b = gcd a b" |
272 lemma gcd_right_idem: "gcd (gcd a b) b = gcd a b" |
273 by (fact gcd.right_idem) |
273 by (fact gcd.right_idem) |
274 |
274 |
275 lemma gcd_mult_left: "gcd (c * a) (c * b) = normalize c * gcd a b" |
275 lemma gcdI: |
|
276 assumes "c dvd a" and "c dvd b" |
|
277 and greatest: "\<And>d. d dvd a \<Longrightarrow> d dvd b \<Longrightarrow> d dvd c" |
|
278 and "normalize c = c" |
|
279 shows "c = gcd a b" |
|
280 by (rule associated_eqI) (auto simp: assms intro: gcd_greatest) |
|
281 |
|
282 lemma gcd_unique: |
|
283 "d dvd a \<and> d dvd b \<and> normalize d = d \<and> (\<forall>e. e dvd a \<and> e dvd b \<longrightarrow> e dvd d) \<longleftrightarrow> d = gcd a b" |
|
284 by rule (auto intro: gcdI simp: gcd_greatest) |
|
285 |
|
286 lemma gcd_dvd_prod: "gcd a b dvd k * b" |
|
287 using mult_dvd_mono [of 1] by auto |
|
288 |
|
289 lemma gcd_proj2_if_dvd: "b dvd a \<Longrightarrow> gcd a b = normalize b" |
|
290 by (rule gcdI [symmetric]) simp_all |
|
291 |
|
292 lemma gcd_proj1_if_dvd: "a dvd b \<Longrightarrow> gcd a b = normalize a" |
|
293 by (rule gcdI [symmetric]) simp_all |
|
294 |
|
295 lemma gcd_proj1_iff: "gcd m n = normalize m \<longleftrightarrow> m dvd n" |
|
296 proof |
|
297 assume *: "gcd m n = normalize m" |
|
298 show "m dvd n" |
|
299 proof (cases "m = 0") |
|
300 case True |
|
301 with * show ?thesis by simp |
|
302 next |
|
303 case [simp]: False |
|
304 from * have **: "m = gcd m n * unit_factor m" |
|
305 by (simp add: unit_eq_div2) |
|
306 show ?thesis |
|
307 by (subst **) (simp add: mult_unit_dvd_iff) |
|
308 qed |
|
309 next |
|
310 assume "m dvd n" |
|
311 then show "gcd m n = normalize m" |
|
312 by (rule gcd_proj1_if_dvd) |
|
313 qed |
|
314 |
|
315 lemma gcd_proj2_iff: "gcd m n = normalize n \<longleftrightarrow> n dvd m" |
|
316 using gcd_proj1_iff [of n m] by (simp add: ac_simps) |
|
317 |
|
318 lemma gcd_mult_left: "gcd (c * a) (c * b) = normalize (c * gcd a b)" |
276 proof (cases "c = 0") |
319 proof (cases "c = 0") |
277 case True |
320 case True |
278 then show ?thesis by simp |
321 then show ?thesis by simp |
279 next |
322 next |
280 case False |
323 case False |
286 by (auto intro: associated_eqI) |
329 by (auto intro: associated_eqI) |
287 then show ?thesis |
330 then show ?thesis |
288 by (simp add: normalize_mult) |
331 by (simp add: normalize_mult) |
289 qed |
332 qed |
290 |
333 |
291 lemma gcd_mult_right: "gcd (a * c) (b * c) = gcd b a * normalize c" |
334 lemma gcd_mult_right: "gcd (a * c) (b * c) = normalize (gcd b a * c)" |
292 using gcd_mult_left [of c a b] by (simp add: ac_simps) |
335 using gcd_mult_left [of c a b] by (simp add: ac_simps) |
293 |
336 |
294 lemma mult_gcd_left: "c * gcd a b = unit_factor c * gcd (c * a) (c * b)" |
|
295 by (simp add: gcd_mult_left mult.assoc [symmetric]) |
|
296 |
|
297 lemma mult_gcd_right: "gcd a b * c = gcd (a * c) (b * c) * unit_factor c" |
|
298 using mult_gcd_left [of c a b] by (simp add: ac_simps) |
|
299 |
|
300 lemma dvd_lcm1 [iff]: "a dvd lcm a b" |
337 lemma dvd_lcm1 [iff]: "a dvd lcm a b" |
301 proof - |
338 by (metis div_mult_swap dvd_mult2 dvd_normalize_iff dvd_refl gcd_dvd2 lcm_gcd) |
302 have "normalize (a * b) div gcd a b = normalize a * (normalize b div gcd a b)" |
|
303 by (simp add: lcm_gcd normalize_mult div_mult_swap) |
|
304 then show ?thesis |
|
305 by (simp add: lcm_gcd) |
|
306 qed |
|
307 |
339 |
308 lemma dvd_lcm2 [iff]: "b dvd lcm a b" |
340 lemma dvd_lcm2 [iff]: "b dvd lcm a b" |
309 proof - |
341 by (metis dvd_div_mult dvd_mult dvd_normalize_iff dvd_refl gcd_dvd1 lcm_gcd) |
310 have "normalize (a * b) div gcd a b = normalize b * (normalize a div gcd a b)" |
|
311 by (simp add: lcm_gcd normalize_mult div_mult_swap ac_simps) |
|
312 then show ?thesis |
|
313 by (simp add: lcm_gcd) |
|
314 qed |
|
315 |
342 |
316 lemma dvd_lcmI1: "a dvd b \<Longrightarrow> a dvd lcm b c" |
343 lemma dvd_lcmI1: "a dvd b \<Longrightarrow> a dvd lcm b c" |
317 by (rule dvd_trans) (assumption, blast) |
344 by (rule dvd_trans) (assumption, blast) |
318 |
345 |
319 lemma dvd_lcmI2: "a dvd c \<Longrightarrow> a dvd lcm b c" |
346 lemma dvd_lcmI2: "a dvd c \<Longrightarrow> a dvd lcm b c" |
435 by (fact lcm.left_idem) |
452 by (fact lcm.left_idem) |
436 |
453 |
437 lemma lcm_right_idem: "lcm (lcm a b) b = lcm a b" |
454 lemma lcm_right_idem: "lcm (lcm a b) b = lcm a b" |
438 by (fact lcm.right_idem) |
455 by (fact lcm.right_idem) |
439 |
456 |
440 lemma gcd_mult_lcm [simp]: "gcd a b * lcm a b = normalize a * normalize b" |
|
441 by (simp add: lcm_gcd normalize_mult) |
|
442 |
|
443 lemma lcm_mult_gcd [simp]: "lcm a b * gcd a b = normalize a * normalize b" |
|
444 using gcd_mult_lcm [of a b] by (simp add: ac_simps) |
|
445 |
|
446 lemma gcd_lcm: |
457 lemma gcd_lcm: |
447 assumes "a \<noteq> 0" and "b \<noteq> 0" |
458 assumes "a \<noteq> 0" and "b \<noteq> 0" |
448 shows "gcd a b = normalize (a * b) div lcm a b" |
459 shows "gcd a b = normalize (a * b div lcm a b)" |
449 proof - |
460 proof - |
450 from assms have "lcm a b \<noteq> 0" |
461 from assms have [simp]: "a * b div gcd a b \<noteq> 0" |
451 by (simp add: lcm_eq_0_iff) |
462 by (subst dvd_div_eq_0_iff) auto |
452 have "gcd a b * lcm a b = normalize a * normalize b" |
463 let ?u = "unit_factor (a * b div gcd a b)" |
453 by simp |
464 have "gcd a b * normalize (a * b div gcd a b) = |
454 then have "gcd a b * lcm a b div lcm a b = normalize (a * b) div lcm a b" |
465 gcd a b * ((a * b div gcd a b) * (1 div ?u))" |
455 by (simp_all add: normalize_mult) |
466 by simp |
456 with \<open>lcm a b \<noteq> 0\<close> show ?thesis |
467 also have "\<dots> = a * b div ?u" |
457 using nonzero_mult_div_cancel_right [of "lcm a b" "gcd a b"] by simp |
468 by (subst mult.assoc [symmetric]) auto |
|
469 also have "\<dots> dvd a * b" |
|
470 by (subst div_unit_dvd_iff) auto |
|
471 finally have "gcd a b dvd ((a * b) div lcm a b)" |
|
472 by (intro dvd_mult_imp_div) (auto simp: lcm_gcd) |
|
473 moreover have "a * b div lcm a b dvd a" and "a * b div lcm a b dvd b" |
|
474 using assms by (subst div_dvd_iff_mult; simp add: lcm_eq_0_iff mult.commute[of b "lcm a b"])+ |
|
475 ultimately have "normalize (gcd a b) = normalize (a * b div lcm a b)" |
|
476 apply - |
|
477 apply (rule associated_eqI) |
|
478 using assms |
|
479 apply (auto simp: div_dvd_iff_mult zero_eq_lcm_iff) |
|
480 done |
|
481 thus ?thesis by simp |
458 qed |
482 qed |
459 |
483 |
460 lemma lcm_1_left: "lcm 1 a = normalize a" |
484 lemma lcm_1_left: "lcm 1 a = normalize a" |
461 by (fact lcm.top_left_normalize) |
485 by (fact lcm.top_left_normalize) |
462 |
486 |
463 lemma lcm_1_right: "lcm a 1 = normalize a" |
487 lemma lcm_1_right: "lcm a 1 = normalize a" |
464 by (fact lcm.top_right_normalize) |
488 by (fact lcm.top_right_normalize) |
465 |
489 |
466 lemma lcm_mult_left: "lcm (c * a) (c * b) = normalize c * lcm a b" |
490 lemma lcm_mult_left: "lcm (c * a) (c * b) = normalize (c * lcm a b)" |
467 by (cases "c = 0") |
491 proof (cases "c = 0") |
468 (simp_all add: gcd_mult_right lcm_gcd div_mult_swap normalize_mult ac_simps, |
492 case True |
469 simp add: dvd_div_mult2_eq mult.left_commute [of "normalize c", symmetric]) |
493 then show ?thesis by simp |
470 |
494 next |
471 lemma lcm_mult_right: "lcm (a * c) (b * c) = lcm b a * normalize c" |
495 case False |
|
496 then have *: "lcm (c * a) (c * b) dvd c * lcm a b" |
|
497 by (auto intro: lcm_least) |
|
498 moreover have "lcm a b dvd lcm (c * a) (c * b) div c" |
|
499 by (intro lcm_least) (auto intro!: dvd_mult_imp_div simp: mult_ac) |
|
500 hence "c * lcm a b dvd lcm (c * a) (c * b)" |
|
501 using False by (subst (asm) dvd_div_iff_mult) (auto simp: mult_ac intro: dvd_lcmI1) |
|
502 ultimately have "normalize (lcm (c * a) (c * b)) = normalize (c * lcm a b)" |
|
503 by (auto intro: associated_eqI) |
|
504 then show ?thesis |
|
505 by (simp add: normalize_mult) |
|
506 qed |
|
507 |
|
508 lemma lcm_mult_right: "lcm (a * c) (b * c) = normalize (lcm b a * c)" |
472 using lcm_mult_left [of c a b] by (simp add: ac_simps) |
509 using lcm_mult_left [of c a b] by (simp add: ac_simps) |
473 |
|
474 lemma mult_lcm_left: "c * lcm a b = unit_factor c * lcm (c * a) (c * b)" |
|
475 by (simp add: lcm_mult_left mult.assoc [symmetric]) |
|
476 |
|
477 lemma mult_lcm_right: "lcm a b * c = lcm (a * c) (b * c) * unit_factor c" |
|
478 using mult_lcm_left [of c a b] by (simp add: ac_simps) |
|
479 |
|
480 lemma gcdI: |
|
481 assumes "c dvd a" and "c dvd b" |
|
482 and greatest: "\<And>d. d dvd a \<Longrightarrow> d dvd b \<Longrightarrow> d dvd c" |
|
483 and "normalize c = c" |
|
484 shows "c = gcd a b" |
|
485 by (rule associated_eqI) (auto simp: assms intro: gcd_greatest) |
|
486 |
|
487 lemma gcd_unique: |
|
488 "d dvd a \<and> d dvd b \<and> normalize d = d \<and> (\<forall>e. e dvd a \<and> e dvd b \<longrightarrow> e dvd d) \<longleftrightarrow> d = gcd a b" |
|
489 by rule (auto intro: gcdI simp: gcd_greatest) |
|
490 |
|
491 lemma gcd_dvd_prod: "gcd a b dvd k * b" |
|
492 using mult_dvd_mono [of 1] by auto |
|
493 |
|
494 lemma gcd_proj2_if_dvd: "b dvd a \<Longrightarrow> gcd a b = normalize b" |
|
495 by (rule gcdI [symmetric]) simp_all |
|
496 |
|
497 lemma gcd_proj1_if_dvd: "a dvd b \<Longrightarrow> gcd a b = normalize a" |
|
498 by (rule gcdI [symmetric]) simp_all |
|
499 |
|
500 lemma gcd_proj1_iff: "gcd m n = normalize m \<longleftrightarrow> m dvd n" |
|
501 proof |
|
502 assume *: "gcd m n = normalize m" |
|
503 show "m dvd n" |
|
504 proof (cases "m = 0") |
|
505 case True |
|
506 with * show ?thesis by simp |
|
507 next |
|
508 case [simp]: False |
|
509 from * have **: "m = gcd m n * unit_factor m" |
|
510 by (simp add: unit_eq_div2) |
|
511 show ?thesis |
|
512 by (subst **) (simp add: mult_unit_dvd_iff) |
|
513 qed |
|
514 next |
|
515 assume "m dvd n" |
|
516 then show "gcd m n = normalize m" |
|
517 by (rule gcd_proj1_if_dvd) |
|
518 qed |
|
519 |
|
520 lemma gcd_proj2_iff: "gcd m n = normalize n \<longleftrightarrow> n dvd m" |
|
521 using gcd_proj1_iff [of n m] by (simp add: ac_simps) |
|
522 |
|
523 lemma gcd_mult_distrib': "normalize c * gcd a b = gcd (c * a) (c * b)" |
|
524 by (rule gcdI) (auto simp: normalize_mult gcd_greatest mult_dvd_mono gcd_mult_left[symmetric]) |
|
525 |
|
526 lemma gcd_mult_distrib: "k * gcd a b = gcd (k * a) (k * b) * unit_factor k" |
|
527 proof- |
|
528 have "normalize k * gcd a b = gcd (k * a) (k * b)" |
|
529 by (simp add: gcd_mult_distrib') |
|
530 then have "normalize k * gcd a b * unit_factor k = gcd (k * a) (k * b) * unit_factor k" |
|
531 by simp |
|
532 then have "normalize k * unit_factor k * gcd a b = gcd (k * a) (k * b) * unit_factor k" |
|
533 by (simp only: ac_simps) |
|
534 then show ?thesis |
|
535 by simp |
|
536 qed |
|
537 |
510 |
538 lemma lcm_mult_unit1: "is_unit a \<Longrightarrow> lcm (b * a) c = lcm b c" |
511 lemma lcm_mult_unit1: "is_unit a \<Longrightarrow> lcm (b * a) c = lcm b c" |
539 by (rule associated_eqI) (simp_all add: mult_unit_dvd_iff dvd_lcmI1) |
512 by (rule associated_eqI) (simp_all add: mult_unit_dvd_iff dvd_lcmI1) |
540 |
513 |
541 lemma lcm_mult_unit2: "is_unit a \<Longrightarrow> lcm b (c * a) = lcm b c" |
514 lemma lcm_mult_unit2: "is_unit a \<Longrightarrow> lcm b (c * a) = lcm b c" |
551 lemma normalize_lcm_left: "lcm (normalize a) b = lcm a b" |
524 lemma normalize_lcm_left: "lcm (normalize a) b = lcm a b" |
552 by (fact lcm.normalize_left_idem) |
525 by (fact lcm.normalize_left_idem) |
553 |
526 |
554 lemma normalize_lcm_right: "lcm a (normalize b) = lcm a b" |
527 lemma normalize_lcm_right: "lcm a (normalize b) = lcm a b" |
555 by (fact lcm.normalize_right_idem) |
528 by (fact lcm.normalize_right_idem) |
556 |
|
557 lemma gcd_mult_unit1: |
|
558 assumes "is_unit a" shows "gcd (b * a) c = gcd b c" |
|
559 proof - |
|
560 have "gcd (b * a) c dvd b" |
|
561 using assms local.dvd_mult_unit_iff by blast |
|
562 then show ?thesis |
|
563 by (rule gcdI) simp_all |
|
564 qed |
|
565 |
|
566 lemma gcd_mult_unit2: "is_unit a \<Longrightarrow> gcd b (c * a) = gcd b c" |
|
567 using gcd.commute gcd_mult_unit1 by auto |
|
568 |
|
569 lemma gcd_div_unit1: "is_unit a \<Longrightarrow> gcd (b div a) c = gcd b c" |
|
570 by (erule is_unitE [of _ b]) (simp add: gcd_mult_unit1) |
|
571 |
|
572 lemma gcd_div_unit2: "is_unit a \<Longrightarrow> gcd b (c div a) = gcd b c" |
|
573 by (erule is_unitE [of _ c]) (simp add: gcd_mult_unit2) |
|
574 |
|
575 lemma normalize_gcd_left: "gcd (normalize a) b = gcd a b" |
|
576 by (fact gcd.normalize_left_idem) |
|
577 |
|
578 lemma normalize_gcd_right: "gcd a (normalize b) = gcd a b" |
|
579 by (fact gcd.normalize_right_idem) |
|
580 |
529 |
581 lemma comp_fun_idem_gcd: "comp_fun_idem gcd" |
530 lemma comp_fun_idem_gcd: "comp_fun_idem gcd" |
582 by standard (simp_all add: fun_eq_iff ac_simps) |
531 by standard (simp_all add: fun_eq_iff ac_simps) |
583 |
532 |
584 lemma comp_fun_idem_lcm: "comp_fun_idem lcm" |
533 lemma comp_fun_idem_lcm: "comp_fun_idem lcm" |
699 define x y where "x = gcd a p" and "y = p div x" |
621 define x y where "x = gcd a p" and "y = p div x" |
700 have "p = x * y" by (simp add: x_def y_def) |
622 have "p = x * y" by (simp add: x_def y_def) |
701 moreover have "x dvd a" by (simp add: x_def) |
623 moreover have "x dvd a" by (simp add: x_def) |
702 moreover from assms have "p dvd gcd (b * a) (b * p)" |
624 moreover from assms have "p dvd gcd (b * a) (b * p)" |
703 by (intro gcd_greatest) (simp_all add: mult.commute) |
625 by (intro gcd_greatest) (simp_all add: mult.commute) |
704 hence "p dvd b * gcd a p" by (simp add: gcd_mult_distrib) |
626 hence "p dvd b * gcd a p" by (subst (asm) gcd_mult_left) auto |
705 with False have "y dvd b" |
627 with False have "y dvd b" |
706 by (simp add: x_def y_def div_dvd_iff_mult assms) |
628 by (simp add: x_def y_def div_dvd_iff_mult assms) |
707 ultimately show ?thesis by (rule that) |
629 ultimately show ?thesis by (rule that) |
708 qed |
630 qed |
|
631 |
|
632 lemma gcd_mult_unit1: |
|
633 assumes "is_unit a" shows "gcd (b * a) c = gcd b c" |
|
634 proof - |
|
635 have "gcd (b * a) c dvd b" |
|
636 using assms dvd_mult_unit_iff by blast |
|
637 then show ?thesis |
|
638 by (rule gcdI) simp_all |
|
639 qed |
|
640 |
|
641 lemma gcd_mult_unit2: "is_unit a \<Longrightarrow> gcd b (c * a) = gcd b c" |
|
642 using gcd.commute gcd_mult_unit1 by auto |
|
643 |
|
644 lemma gcd_div_unit1: "is_unit a \<Longrightarrow> gcd (b div a) c = gcd b c" |
|
645 by (erule is_unitE [of _ b]) (simp add: gcd_mult_unit1) |
|
646 |
|
647 lemma gcd_div_unit2: "is_unit a \<Longrightarrow> gcd b (c div a) = gcd b c" |
|
648 by (erule is_unitE [of _ c]) (simp add: gcd_mult_unit2) |
|
649 |
|
650 lemma normalize_gcd_left: "gcd (normalize a) b = gcd a b" |
|
651 by (fact gcd.normalize_left_idem) |
|
652 |
|
653 lemma normalize_gcd_right: "gcd a (normalize b) = gcd a b" |
|
654 by (fact gcd.normalize_right_idem) |
|
655 |
|
656 lemma gcd_add1 [simp]: "gcd (m + n) n = gcd m n" |
|
657 by (rule gcdI [symmetric]) (simp_all add: dvd_add_left_iff) |
|
658 |
|
659 lemma gcd_add2 [simp]: "gcd m (m + n) = gcd m n" |
|
660 using gcd_add1 [of n m] by (simp add: ac_simps) |
|
661 |
|
662 lemma gcd_add_mult: "gcd m (k * m + n) = gcd m n" |
|
663 by (rule gcdI [symmetric]) (simp_all add: dvd_add_right_iff) |
709 |
664 |
710 end |
665 end |
711 |
666 |
712 class ring_gcd = comm_ring_1 + semiring_gcd |
667 class ring_gcd = comm_ring_1 + semiring_gcd |
713 begin |
668 begin |
980 using Gcd_dvd dvd_trans by blast |
935 using Gcd_dvd dvd_trans by blast |
981 |
936 |
982 lemma dvd_Gcd_iff: "x dvd Gcd A \<longleftrightarrow> (\<forall>y\<in>A. x dvd y)" |
937 lemma dvd_Gcd_iff: "x dvd Gcd A \<longleftrightarrow> (\<forall>y\<in>A. x dvd y)" |
983 by (blast dest: dvd_GcdD intro: Gcd_greatest) |
938 by (blast dest: dvd_GcdD intro: Gcd_greatest) |
984 |
939 |
985 lemma Gcd_mult: "Gcd ((*) c ` A) = normalize c * Gcd A" |
940 lemma Gcd_mult: "Gcd ((*) c ` A) = normalize (c * Gcd A)" |
986 proof (cases "c = 0") |
941 proof (cases "c = 0") |
987 case True |
942 case True |
988 then show ?thesis by auto |
943 then show ?thesis by auto |
989 next |
944 next |
990 case [simp]: False |
945 case [simp]: False |
991 have "Gcd ((*) c ` A) div c dvd Gcd A" |
946 have "Gcd ((*) c ` A) div c dvd Gcd A" |
992 by (intro Gcd_greatest, subst div_dvd_iff_mult) |
947 by (intro Gcd_greatest, subst div_dvd_iff_mult) |
993 (auto intro!: Gcd_greatest Gcd_dvd simp: mult.commute[of _ c]) |
948 (auto intro!: Gcd_greatest Gcd_dvd simp: mult.commute[of _ c]) |
994 then have "Gcd ((*) c ` A) dvd c * Gcd A" |
949 then have "Gcd ((*) c ` A) dvd c * Gcd A" |
995 by (subst (asm) div_dvd_iff_mult) (auto intro: Gcd_greatest simp: mult_ac) |
950 by (subst (asm) div_dvd_iff_mult) (auto intro: Gcd_greatest simp: mult_ac) |
996 also have "c * Gcd A = (normalize c * Gcd A) * unit_factor c" |
951 moreover have "c * Gcd A dvd Gcd ((*) c ` A)" |
997 by (subst unit_factor_mult_normalize [symmetric]) (simp only: mult_ac) |
|
998 also have "Gcd ((*) c ` A) dvd \<dots> \<longleftrightarrow> Gcd ((*) c ` A) dvd normalize c * Gcd A" |
|
999 by (simp add: dvd_mult_unit_iff) |
|
1000 finally have "Gcd ((*) c ` A) dvd normalize c * Gcd A" . |
|
1001 moreover have "normalize c * Gcd A dvd Gcd ((*) c ` A)" |
|
1002 by (intro Gcd_greatest) (auto intro: mult_dvd_mono Gcd_dvd) |
952 by (intro Gcd_greatest) (auto intro: mult_dvd_mono Gcd_dvd) |
1003 ultimately have "normalize (Gcd ((*) c ` A)) = normalize (normalize c * Gcd A)" |
953 ultimately have "normalize (Gcd ((*) c ` A)) = normalize (c * Gcd A)" |
1004 by (rule associatedI) |
954 by (rule associatedI) |
1005 then show ?thesis |
955 then show ?thesis by simp |
1006 by (simp add: normalize_mult) |
|
1007 qed |
956 qed |
1008 |
957 |
1009 lemma Lcm_eqI: |
958 lemma Lcm_eqI: |
1010 assumes "normalize a = a" |
959 assumes "normalize a = a" |
1011 and "\<And>b. b \<in> A \<Longrightarrow> b dvd a" |
960 and "\<And>b. b \<in> A \<Longrightarrow> b dvd a" |
1039 moreover have "Lcm A dvd Lcm ((*) c ` A) div c" |
988 moreover have "Lcm A dvd Lcm ((*) c ` A) div c" |
1040 by (intro Lcm_least dvd_mult_imp_div) |
989 by (intro Lcm_least dvd_mult_imp_div) |
1041 (auto intro!: Lcm_least dvd_Lcm simp: mult.commute[of _ c]) |
990 (auto intro!: Lcm_least dvd_Lcm simp: mult.commute[of _ c]) |
1042 ultimately have "c * Lcm A dvd Lcm ((*) c ` A)" |
991 ultimately have "c * Lcm A dvd Lcm ((*) c ` A)" |
1043 by auto |
992 by auto |
1044 also have "c * Lcm A = (normalize c * Lcm A) * unit_factor c" |
993 moreover have "Lcm ((*) c ` A) dvd c * Lcm A" |
1045 by (subst unit_factor_mult_normalize [symmetric]) (simp only: mult_ac) |
|
1046 also have "\<dots> dvd Lcm ((*) c ` A) \<longleftrightarrow> normalize c * Lcm A dvd Lcm ((*) c ` A)" |
|
1047 by (simp add: mult_unit_dvd_iff) |
|
1048 finally have "normalize c * Lcm A dvd Lcm ((*) c ` A)" . |
|
1049 moreover have "Lcm ((*) c ` A) dvd normalize c * Lcm A" |
|
1050 by (intro Lcm_least) (auto intro: mult_dvd_mono dvd_Lcm) |
994 by (intro Lcm_least) (auto intro: mult_dvd_mono dvd_Lcm) |
1051 ultimately have "normalize (normalize c * Lcm A) = normalize (Lcm ((*) c ` A))" |
995 ultimately have "normalize (c * Lcm A) = normalize (Lcm ((*) c ` A))" |
1052 by (rule associatedI) |
996 by (rule associatedI) |
1053 then show ?thesis |
997 then show ?thesis by simp |
1054 by (simp add: normalize_mult) |
|
1055 qed |
998 qed |
1056 |
999 |
1057 lemma Lcm_no_units: "Lcm A = Lcm (A - {a. is_unit a})" |
1000 lemma Lcm_no_units: "Lcm A = Lcm (A - {a. is_unit a})" |
1058 proof - |
1001 proof - |
1059 have "(A - {a. is_unit a}) \<union> {a\<in>A. is_unit a} = A" |
1002 have "(A - {a. is_unit a}) \<union> {a\<in>A. is_unit a} = A" |
1572 moreover from \<open>c dvd d\<close> \<open>d dvd c\<close> have "normalize c = normalize d" |
1492 moreover from \<open>c dvd d\<close> \<open>d dvd c\<close> have "normalize c = normalize d" |
1573 by (rule associatedI) |
1493 by (rule associatedI) |
1574 ultimately show ?rhs .. |
1494 ultimately show ?rhs .. |
1575 qed |
1495 qed |
1576 |
1496 |
|
1497 lemma gcd_mult_left_left_cancel: |
|
1498 "gcd (c * a) b = gcd a b" if "coprime b c" |
|
1499 proof - |
|
1500 have "coprime (gcd b (a * c)) c" |
|
1501 by (rule coprimeI) (auto intro: that coprime_common_divisor) |
|
1502 then have "gcd b (a * c) dvd a" |
|
1503 using coprime_dvd_mult_left_iff [of "gcd b (a * c)" c a] |
|
1504 by simp |
|
1505 then show ?thesis |
|
1506 by (auto intro: associated_eqI simp add: ac_simps) |
|
1507 qed |
|
1508 |
|
1509 lemma gcd_mult_left_right_cancel: |
|
1510 "gcd (a * c) b = gcd a b" if "coprime b c" |
|
1511 using that gcd_mult_left_left_cancel [of b c a] |
|
1512 by (simp add: ac_simps) |
|
1513 |
|
1514 lemma gcd_mult_right_left_cancel: |
|
1515 "gcd a (c * b) = gcd a b" if "coprime a c" |
|
1516 using that gcd_mult_left_left_cancel [of a c b] |
|
1517 by (simp add: ac_simps) |
|
1518 |
|
1519 lemma gcd_mult_right_right_cancel: |
|
1520 "gcd a (b * c) = gcd a b" if "coprime a c" |
|
1521 using that gcd_mult_right_left_cancel [of a c b] |
|
1522 by (simp add: ac_simps) |
|
1523 |
|
1524 lemma gcd_exp_weak: |
|
1525 "gcd (a ^ n) (b ^ n) = normalize (gcd a b ^ n)" |
|
1526 proof (cases "a = 0 \<and> b = 0 \<or> n = 0") |
|
1527 case True |
|
1528 then show ?thesis |
|
1529 by (cases n) simp_all |
|
1530 next |
|
1531 case False |
|
1532 then have "coprime (a div gcd a b) (b div gcd a b)" and "n > 0" |
|
1533 by (auto intro: div_gcd_coprime) |
|
1534 then have "coprime ((a div gcd a b) ^ n) ((b div gcd a b) ^ n)" |
|
1535 by simp |
|
1536 then have "1 = gcd ((a div gcd a b) ^ n) ((b div gcd a b) ^ n)" |
|
1537 by simp |
|
1538 then have "normalize (gcd a b ^ n) = normalize (gcd a b ^ n * \<dots>)" |
|
1539 by simp |
|
1540 also have "\<dots> = gcd (gcd a b ^ n * (a div gcd a b) ^ n) (gcd a b ^ n * (b div gcd a b) ^ n)" |
|
1541 by (rule gcd_mult_left [symmetric]) |
|
1542 also have "(gcd a b) ^ n * (a div gcd a b) ^ n = a ^ n" |
|
1543 by (simp add: ac_simps div_power dvd_power_same) |
|
1544 also have "(gcd a b) ^ n * (b div gcd a b) ^ n = b ^ n" |
|
1545 by (simp add: ac_simps div_power dvd_power_same) |
|
1546 finally show ?thesis by simp |
|
1547 qed |
|
1548 |
|
1549 lemma division_decomp: |
|
1550 assumes "a dvd b * c" |
|
1551 shows "\<exists>b' c'. a = b' * c' \<and> b' dvd b \<and> c' dvd c" |
|
1552 proof (cases "gcd a b = 0") |
|
1553 case True |
|
1554 then have "a = 0 \<and> b = 0" |
|
1555 by simp |
|
1556 then have "a = 0 * c \<and> 0 dvd b \<and> c dvd c" |
|
1557 by simp |
|
1558 then show ?thesis by blast |
|
1559 next |
|
1560 case False |
|
1561 let ?d = "gcd a b" |
|
1562 from gcd_coprime_exists [OF False] |
|
1563 obtain a' b' where ab': "a = a' * ?d" "b = b' * ?d" "coprime a' b'" |
|
1564 by blast |
|
1565 from ab'(1) have "a' dvd a" .. |
|
1566 with assms have "a' dvd b * c" |
|
1567 using dvd_trans [of a' a "b * c"] by simp |
|
1568 from assms ab'(1,2) have "a' * ?d dvd (b' * ?d) * c" |
|
1569 by simp |
|
1570 then have "?d * a' dvd ?d * (b' * c)" |
|
1571 by (simp add: mult_ac) |
|
1572 with \<open>?d \<noteq> 0\<close> have "a' dvd b' * c" |
|
1573 by simp |
|
1574 then have "a' dvd c" |
|
1575 using \<open>coprime a' b'\<close> by (simp add: coprime_dvd_mult_right_iff) |
|
1576 with ab'(1) have "a = ?d * a' \<and> ?d dvd b \<and> a' dvd c" |
|
1577 by (simp add: ac_simps) |
|
1578 then show ?thesis by blast |
|
1579 qed |
|
1580 |
|
1581 lemma lcm_coprime: "coprime a b \<Longrightarrow> lcm a b = normalize (a * b)" |
|
1582 by (subst lcm_gcd) simp |
|
1583 |
|
1584 end |
|
1585 |
|
1586 context ring_gcd |
|
1587 begin |
|
1588 |
|
1589 lemma coprime_minus_left_iff [simp]: |
|
1590 "coprime (- a) b \<longleftrightarrow> coprime a b" |
|
1591 by (rule; rule coprimeI) (auto intro: coprime_common_divisor) |
|
1592 |
|
1593 lemma coprime_minus_right_iff [simp]: |
|
1594 "coprime a (- b) \<longleftrightarrow> coprime a b" |
|
1595 using coprime_minus_left_iff [of b a] by (simp add: ac_simps) |
|
1596 |
|
1597 lemma coprime_diff_one_left [simp]: "coprime (a - 1) a" |
|
1598 using coprime_add_one_right [of "a - 1"] by simp |
|
1599 |
|
1600 lemma coprime_doff_one_right [simp]: "coprime a (a - 1)" |
|
1601 using coprime_diff_one_left [of a] by (simp add: ac_simps) |
|
1602 |
|
1603 end |
|
1604 |
|
1605 context semiring_Gcd |
|
1606 begin |
|
1607 |
|
1608 lemma Lcm_coprime: |
|
1609 assumes "finite A" |
|
1610 and "A \<noteq> {}" |
|
1611 and "\<And>a b. a \<in> A \<Longrightarrow> b \<in> A \<Longrightarrow> a \<noteq> b \<Longrightarrow> coprime a b" |
|
1612 shows "Lcm A = normalize (\<Prod>A)" |
|
1613 using assms |
|
1614 proof (induct rule: finite_ne_induct) |
|
1615 case singleton |
|
1616 then show ?case by simp |
|
1617 next |
|
1618 case (insert a A) |
|
1619 have "Lcm (insert a A) = lcm a (Lcm A)" |
|
1620 by simp |
|
1621 also from insert have "Lcm A = normalize (\<Prod>A)" |
|
1622 by blast |
|
1623 also have "lcm a \<dots> = lcm a (\<Prod>A)" |
|
1624 by (cases "\<Prod>A = 0") (simp_all add: lcm_div_unit2) |
|
1625 also from insert have "coprime a (\<Prod>A)" |
|
1626 by (subst coprime_commute, intro prod_coprime_left) auto |
|
1627 with insert have "lcm a (\<Prod>A) = normalize (\<Prod>(insert a A))" |
|
1628 by (simp add: lcm_coprime) |
|
1629 finally show ?case . |
|
1630 qed |
|
1631 |
|
1632 lemma Lcm_coprime': |
|
1633 "card A \<noteq> 0 \<Longrightarrow> |
|
1634 (\<And>a b. a \<in> A \<Longrightarrow> b \<in> A \<Longrightarrow> a \<noteq> b \<Longrightarrow> coprime a b) \<Longrightarrow> |
|
1635 Lcm A = normalize (\<Prod>A)" |
|
1636 by (rule Lcm_coprime) (simp_all add: card_eq_0_iff) |
|
1637 |
|
1638 end |
|
1639 |
|
1640 |
|
1641 subsection \<open>GCD and LCM for multiplicative normalisation functions\<close> |
|
1642 |
|
1643 class semiring_gcd_mult_normalize = semiring_gcd + normalization_semidom_multiplicative |
|
1644 begin |
|
1645 |
|
1646 lemma mult_gcd_left: "c * gcd a b = unit_factor c * gcd (c * a) (c * b)" |
|
1647 by (simp add: gcd_mult_left normalize_mult mult.assoc [symmetric]) |
|
1648 |
|
1649 lemma mult_gcd_right: "gcd a b * c = gcd (a * c) (b * c) * unit_factor c" |
|
1650 using mult_gcd_left [of c a b] by (simp add: ac_simps) |
|
1651 |
|
1652 lemma gcd_mult_distrib': "normalize c * gcd a b = gcd (c * a) (c * b)" |
|
1653 by (subst gcd_mult_left) (simp_all add: normalize_mult) |
|
1654 |
|
1655 lemma gcd_mult_distrib: "k * gcd a b = gcd (k * a) (k * b) * unit_factor k" |
|
1656 proof- |
|
1657 have "normalize k * gcd a b = gcd (k * a) (k * b)" |
|
1658 by (simp add: gcd_mult_distrib') |
|
1659 then have "normalize k * gcd a b * unit_factor k = gcd (k * a) (k * b) * unit_factor k" |
|
1660 by simp |
|
1661 then have "normalize k * unit_factor k * gcd a b = gcd (k * a) (k * b) * unit_factor k" |
|
1662 by (simp only: ac_simps) |
|
1663 then show ?thesis |
|
1664 by simp |
|
1665 qed |
|
1666 |
|
1667 lemma gcd_mult_lcm [simp]: "gcd a b * lcm a b = normalize a * normalize b" |
|
1668 by (simp add: lcm_gcd normalize_mult dvd_normalize_div) |
|
1669 |
|
1670 lemma lcm_mult_gcd [simp]: "lcm a b * gcd a b = normalize a * normalize b" |
|
1671 using gcd_mult_lcm [of a b] by (simp add: ac_simps) |
|
1672 |
|
1673 lemma mult_lcm_left: "c * lcm a b = unit_factor c * lcm (c * a) (c * b)" |
|
1674 by (simp add: lcm_mult_left mult.assoc [symmetric] normalize_mult) |
|
1675 |
|
1676 lemma mult_lcm_right: "lcm a b * c = lcm (a * c) (b * c) * unit_factor c" |
|
1677 using mult_lcm_left [of c a b] by (simp add: ac_simps) |
|
1678 |
|
1679 lemma lcm_gcd_prod: "lcm a b * gcd a b = normalize (a * b)" |
|
1680 by (simp add: lcm_gcd dvd_normalize_div normalize_mult) |
|
1681 |
|
1682 lemma lcm_mult_distrib': "normalize c * lcm a b = lcm (c * a) (c * b)" |
|
1683 by (subst lcm_mult_left) (simp add: normalize_mult) |
|
1684 |
|
1685 lemma lcm_mult_distrib: "k * lcm a b = lcm (k * a) (k * b) * unit_factor k" |
|
1686 proof- |
|
1687 have "normalize k * lcm a b = lcm (k * a) (k * b)" |
|
1688 by (simp add: lcm_mult_distrib') |
|
1689 then have "normalize k * lcm a b * unit_factor k = lcm (k * a) (k * b) * unit_factor k" |
|
1690 by simp |
|
1691 then have "normalize k * unit_factor k * lcm a b = lcm (k * a) (k * b) * unit_factor k" |
|
1692 by (simp only: ac_simps) |
|
1693 then show ?thesis |
|
1694 by simp |
|
1695 qed |
|
1696 |
1577 lemma coprime_crossproduct': |
1697 lemma coprime_crossproduct': |
1578 fixes a b c d |
1698 fixes a b c d |
1579 assumes "b \<noteq> 0" |
1699 assumes "b \<noteq> 0" |
1580 assumes unit_factors: "unit_factor b = unit_factor d" |
1700 assumes unit_factors: "unit_factor b = unit_factor d" |
1581 assumes coprime: "coprime a b" "coprime c d" |
1701 assumes coprime: "coprime a b" "coprime c d" |
1590 by (rule normalize_unit_factor_eqI) |
1710 by (rule normalize_unit_factor_eqI) |
1591 from eq have "a * d = c * d" by (simp only: \<open>b = d\<close> mult_ac) |
1711 from eq have "a * d = c * d" by (simp only: \<open>b = d\<close> mult_ac) |
1592 with \<open>b \<noteq> 0\<close> \<open>b = d\<close> show "a = c" by simp |
1712 with \<open>b \<noteq> 0\<close> \<open>b = d\<close> show "a = c" by simp |
1593 qed (simp_all add: mult_ac) |
1713 qed (simp_all add: mult_ac) |
1594 |
1714 |
1595 lemma gcd_mult_left_left_cancel: |
|
1596 "gcd (c * a) b = gcd a b" if "coprime b c" |
|
1597 proof - |
|
1598 have "coprime (gcd b (a * c)) c" |
|
1599 by (rule coprimeI) (auto intro: that coprime_common_divisor) |
|
1600 then have "gcd b (a * c) dvd a" |
|
1601 using coprime_dvd_mult_left_iff [of "gcd b (a * c)" c a] |
|
1602 by simp |
|
1603 then show ?thesis |
|
1604 by (auto intro: associated_eqI simp add: ac_simps) |
|
1605 qed |
|
1606 |
|
1607 lemma gcd_mult_left_right_cancel: |
|
1608 "gcd (a * c) b = gcd a b" if "coprime b c" |
|
1609 using that gcd_mult_left_left_cancel [of b c a] |
|
1610 by (simp add: ac_simps) |
|
1611 |
|
1612 lemma gcd_mult_right_left_cancel: |
|
1613 "gcd a (c * b) = gcd a b" if "coprime a c" |
|
1614 using that gcd_mult_left_left_cancel [of a c b] |
|
1615 by (simp add: ac_simps) |
|
1616 |
|
1617 lemma gcd_mult_right_right_cancel: |
|
1618 "gcd a (b * c) = gcd a b" if "coprime a c" |
|
1619 using that gcd_mult_right_left_cancel [of a c b] |
|
1620 by (simp add: ac_simps) |
|
1621 |
|
1622 lemma gcd_exp [simp]: |
1715 lemma gcd_exp [simp]: |
1623 "gcd (a ^ n) (b ^ n) = gcd a b ^ n" |
1716 "gcd (a ^ n) (b ^ n) = gcd a b ^ n" |
1624 proof (cases "a = 0 \<and> b = 0 \<or> n = 0") |
1717 using gcd_exp_weak[of a n b] by (simp add: normalize_power) |
1625 case True |
|
1626 then show ?thesis |
|
1627 by (cases n) simp_all |
|
1628 next |
|
1629 case False |
|
1630 then have "coprime (a div gcd a b) (b div gcd a b)" and "n > 0" |
|
1631 by (auto intro: div_gcd_coprime) |
|
1632 then have "coprime ((a div gcd a b) ^ n) ((b div gcd a b) ^ n)" |
|
1633 by simp |
|
1634 then have "1 = gcd ((a div gcd a b) ^ n) ((b div gcd a b) ^ n)" |
|
1635 by simp |
|
1636 then have "gcd a b ^ n = gcd a b ^ n * \<dots>" |
|
1637 by simp |
|
1638 also note gcd_mult_distrib |
|
1639 also have "unit_factor (gcd a b ^ n) = 1" |
|
1640 using False by (auto simp: unit_factor_power unit_factor_gcd) |
|
1641 also have "(gcd a b) ^ n * (a div gcd a b) ^ n = a ^ n" |
|
1642 by (simp add: ac_simps div_power dvd_power_same) |
|
1643 also have "(gcd a b) ^ n * (b div gcd a b) ^ n = b ^ n" |
|
1644 by (simp add: ac_simps div_power dvd_power_same) |
|
1645 finally show ?thesis by simp |
|
1646 qed |
|
1647 |
|
1648 lemma division_decomp: |
|
1649 assumes "a dvd b * c" |
|
1650 shows "\<exists>b' c'. a = b' * c' \<and> b' dvd b \<and> c' dvd c" |
|
1651 proof (cases "gcd a b = 0") |
|
1652 case True |
|
1653 then have "a = 0 \<and> b = 0" |
|
1654 by simp |
|
1655 then have "a = 0 * c \<and> 0 dvd b \<and> c dvd c" |
|
1656 by simp |
|
1657 then show ?thesis by blast |
|
1658 next |
|
1659 case False |
|
1660 let ?d = "gcd a b" |
|
1661 from gcd_coprime_exists [OF False] |
|
1662 obtain a' b' where ab': "a = a' * ?d" "b = b' * ?d" "coprime a' b'" |
|
1663 by blast |
|
1664 from ab'(1) have "a' dvd a" .. |
|
1665 with assms have "a' dvd b * c" |
|
1666 using dvd_trans [of a' a "b * c"] by simp |
|
1667 from assms ab'(1,2) have "a' * ?d dvd (b' * ?d) * c" |
|
1668 by simp |
|
1669 then have "?d * a' dvd ?d * (b' * c)" |
|
1670 by (simp add: mult_ac) |
|
1671 with \<open>?d \<noteq> 0\<close> have "a' dvd b' * c" |
|
1672 by simp |
|
1673 then have "a' dvd c" |
|
1674 using \<open>coprime a' b'\<close> by (simp add: coprime_dvd_mult_right_iff) |
|
1675 with ab'(1) have "a = ?d * a' \<and> ?d dvd b \<and> a' dvd c" |
|
1676 by (simp add: ac_simps) |
|
1677 then show ?thesis by blast |
|
1678 qed |
|
1679 |
|
1680 lemma lcm_coprime: "coprime a b \<Longrightarrow> lcm a b = normalize (a * b)" |
|
1681 by (subst lcm_gcd) simp |
|
1682 |
|
1683 end |
|
1684 |
|
1685 context ring_gcd |
|
1686 begin |
|
1687 |
|
1688 lemma coprime_minus_left_iff [simp]: |
|
1689 "coprime (- a) b \<longleftrightarrow> coprime a b" |
|
1690 by (rule; rule coprimeI) (auto intro: coprime_common_divisor) |
|
1691 |
|
1692 lemma coprime_minus_right_iff [simp]: |
|
1693 "coprime a (- b) \<longleftrightarrow> coprime a b" |
|
1694 using coprime_minus_left_iff [of b a] by (simp add: ac_simps) |
|
1695 |
|
1696 lemma coprime_diff_one_left [simp]: "coprime (a - 1) a" |
|
1697 using coprime_add_one_right [of "a - 1"] by simp |
|
1698 |
|
1699 lemma coprime_doff_one_right [simp]: "coprime a (a - 1)" |
|
1700 using coprime_diff_one_left [of a] by (simp add: ac_simps) |
|
1701 |
|
1702 end |
|
1703 |
|
1704 context semiring_Gcd |
|
1705 begin |
|
1706 |
|
1707 lemma Lcm_coprime: |
|
1708 assumes "finite A" |
|
1709 and "A \<noteq> {}" |
|
1710 and "\<And>a b. a \<in> A \<Longrightarrow> b \<in> A \<Longrightarrow> a \<noteq> b \<Longrightarrow> coprime a b" |
|
1711 shows "Lcm A = normalize (\<Prod>A)" |
|
1712 using assms |
|
1713 proof (induct rule: finite_ne_induct) |
|
1714 case singleton |
|
1715 then show ?case by simp |
|
1716 next |
|
1717 case (insert a A) |
|
1718 have "Lcm (insert a A) = lcm a (Lcm A)" |
|
1719 by simp |
|
1720 also from insert have "Lcm A = normalize (\<Prod>A)" |
|
1721 by blast |
|
1722 also have "lcm a \<dots> = lcm a (\<Prod>A)" |
|
1723 by (cases "\<Prod>A = 0") (simp_all add: lcm_div_unit2) |
|
1724 also from insert have "coprime a (\<Prod>A)" |
|
1725 by (subst coprime_commute, intro prod_coprime_left) auto |
|
1726 with insert have "lcm a (\<Prod>A) = normalize (\<Prod>(insert a A))" |
|
1727 by (simp add: lcm_coprime) |
|
1728 finally show ?case . |
|
1729 qed |
|
1730 |
|
1731 lemma Lcm_coprime': |
|
1732 "card A \<noteq> 0 \<Longrightarrow> |
|
1733 (\<And>a b. a \<in> A \<Longrightarrow> b \<in> A \<Longrightarrow> a \<noteq> b \<Longrightarrow> coprime a b) \<Longrightarrow> |
|
1734 Lcm A = normalize (\<Prod>A)" |
|
1735 by (rule Lcm_coprime) (simp_all add: card_eq_0_iff) |
|
1736 |
1718 |
1737 end |
1719 end |
1738 |
1720 |
1739 |
1721 |
1740 subsection \<open>GCD and LCM on \<^typ>\<open>nat\<close> and \<^typ>\<open>int\<close>\<close> |
1722 subsection \<open>GCD and LCM on \<^typ>\<open>nat\<close> and \<^typ>\<open>int\<close>\<close> |