src/HOL/GCD.thy
changeset 71398 e0237f2eb49d
parent 69906 55534affe445
child 73109 783406dd051e
equal deleted inserted replaced
71397:028edb1e5b99 71398:e0237f2eb49d
   164 class semiring_gcd = normalization_semidom + gcd +
   164 class semiring_gcd = normalization_semidom + gcd +
   165   assumes gcd_dvd1 [iff]: "gcd a b dvd a"
   165   assumes gcd_dvd1 [iff]: "gcd a b dvd a"
   166     and gcd_dvd2 [iff]: "gcd a b dvd b"
   166     and gcd_dvd2 [iff]: "gcd a b dvd b"
   167     and gcd_greatest: "c dvd a \<Longrightarrow> c dvd b \<Longrightarrow> c dvd gcd a b"
   167     and gcd_greatest: "c dvd a \<Longrightarrow> c dvd b \<Longrightarrow> c dvd gcd a b"
   168     and normalize_gcd [simp]: "normalize (gcd a b) = gcd a b"
   168     and normalize_gcd [simp]: "normalize (gcd a b) = gcd a b"
   169     and lcm_gcd: "lcm a b = normalize (a * b) div gcd a b"
   169     and lcm_gcd: "lcm a b = normalize (a * b div gcd a b)"
   170 begin
   170 begin
   171 
   171 
   172 lemma gcd_greatest_iff [simp]: "a dvd gcd b c \<longleftrightarrow> a dvd b \<and> a dvd c"
   172 lemma gcd_greatest_iff [simp]: "a dvd gcd b c \<longleftrightarrow> a dvd b \<and> a dvd c"
   173   by (blast intro!: gcd_greatest intro: dvd_trans)
   173   by (blast intro!: gcd_greatest intro: dvd_trans)
   174 
   174 
   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"
   339   proof (cases "gcd a b = 0")
   366   proof (cases "gcd a b = 0")
   340     case True
   367     case True
   341     with assms show ?thesis by simp
   368     with assms show ?thesis by simp
   342   next
   369   next
   343     case False
   370     case False
   344     then have "a \<noteq> 0 \<or> b \<noteq> 0"
   371     have "a * b dvd normalize (c * gcd a b)"
   345       by simp
   372       using assms by (subst gcd_mult_left [symmetric]) (auto intro!: gcd_greatest simp: mult_ac)
   346     with \<open>c \<noteq> 0\<close> assms have "a * b dvd a * c" "a * b dvd c * b"
   373     with False have "(a * b div gcd a b) dvd c"
   347       by (simp_all add: mult_dvd_mono)
   374       by (subst div_dvd_iff_mult) auto
   348     then have "normalize (a * b) dvd gcd (a * c) (b * c)"
   375     thus ?thesis by (simp add: lcm_gcd)
   349       by (auto intro: gcd_greatest simp add: ac_simps)
       
   350     then have "normalize (a * b) dvd gcd (a * c) (b * c) * unit_factor c"
       
   351       using * by (simp add: dvd_mult_unit_iff)
       
   352     then have "normalize (a * b) dvd gcd a b * c"
       
   353       by (simp add: mult_gcd_right [of a b c])
       
   354     then have "normalize (a * b) div gcd a b dvd c"
       
   355       using False by (simp add: div_dvd_iff_mult ac_simps)
       
   356     then show ?thesis
       
   357       by (simp add: lcm_gcd)
       
   358   qed
   376   qed
   359 qed
   377 qed
   360 
   378 
   361 lemma lcm_least_iff [simp]: "lcm a b dvd c \<longleftrightarrow> a dvd c \<and> b dvd c"
   379 lemma lcm_least_iff [simp]: "lcm a b dvd c \<longleftrightarrow> a dvd c \<and> b dvd c"
   362   by (blast intro!: lcm_least intro: dvd_trans)
   380   by (blast intro!: lcm_least intro: dvd_trans)
   374   (is "?P \<longleftrightarrow> ?Q")
   392   (is "?P \<longleftrightarrow> ?Q")
   375 proof
   393 proof
   376   assume ?P
   394   assume ?P
   377   then have "0 dvd lcm a b"
   395   then have "0 dvd lcm a b"
   378     by simp
   396     by simp
   379   then have "0 dvd normalize (a * b) div gcd a b"
   397   also have "lcm a b dvd (a * b)"
   380     by (simp add: lcm_gcd)
   398     by simp
   381   then have "0 * gcd a b dvd normalize (a * b)"
   399   finally show ?Q
   382     using dvd_div_iff_mult [of "gcd a b" _ 0] by (cases "gcd a b = 0") simp_all
   400     by auto
   383   then have "normalize (a * b) = 0"
       
   384     by simp
       
   385   then show ?Q
       
   386     by simp
       
   387 next
   401 next
   388   assume ?Q
   402   assume ?Q
   389   then show ?P
   403   then show ?P
   390     by auto
   404     by auto
   391 qed
   405 qed
   392 
   406 
       
   407 lemma zero_eq_lcm_iff: "0 = lcm a b \<longleftrightarrow> a = 0 \<or> b = 0"
       
   408   using lcm_eq_0_iff[of a b] by auto
       
   409 
   393 lemma lcm_eq_1_iff [simp]: "lcm a b = 1 \<longleftrightarrow> is_unit a \<and> is_unit b"
   410 lemma lcm_eq_1_iff [simp]: "lcm a b = 1 \<longleftrightarrow> is_unit a \<and> is_unit b"
   394   by (auto intro: associated_eqI)
   411   by (auto intro: associated_eqI)
   395 
   412 
   396 lemma unit_factor_lcm: "unit_factor (lcm a b) = (if a = 0 \<or> b = 0 then 0 else 1)"
   413 lemma unit_factor_lcm: "unit_factor (lcm a b) = (if a = 0 \<or> b = 0 then 0 else 1)"
   397   by (simp add: unit_factor_gcd dvd_unit_factor_div lcm_gcd)
   414   using lcm_eq_0_iff[of a b] by (cases "lcm a b = 0") (auto simp: lcm_gcd)
   398 
   415 
   399 sublocale lcm: abel_semigroup lcm
   416 sublocale lcm: abel_semigroup lcm
   400 proof
   417 proof
   401   fix a b c
   418   fix a b c
   402   show "lcm a b = lcm b a"
   419   show "lcm a b = lcm b a"
   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"
   603     by (rule gcd_greatest)
   552     by (rule gcd_greatest)
   604   from this and ** show "l dvd gcd a b"
   553   from this and ** show "l dvd gcd a b"
   605     by (rule dvd_trans)
   554     by (rule dvd_trans)
   606 qed
   555 qed
   607 
   556 
   608 lemma gcd_add1 [simp]: "gcd (m + n) n = gcd m n"
       
   609   by (rule gcdI [symmetric]) (simp_all add: dvd_add_left_iff)
       
   610 
       
   611 lemma gcd_add2 [simp]: "gcd m (m + n) = gcd m n"
       
   612   using gcd_add1 [of n m] by (simp add: ac_simps)
       
   613 
       
   614 lemma gcd_add_mult: "gcd m (k * m + n) = gcd m n"
       
   615   by (rule gcdI [symmetric]) (simp_all add: dvd_add_right_iff)
       
   616 
       
   617 lemma lcm_gcd_prod: "lcm a b * gcd a b = normalize (a * b)"
       
   618   by (simp add: lcm_gcd)
       
   619 
       
   620 declare unit_factor_lcm [simp]
   557 declare unit_factor_lcm [simp]
   621 
   558 
   622 lemma lcmI:
   559 lemma lcmI:
   623   assumes "a dvd c" and "b dvd c" and "\<And>d. a dvd d \<Longrightarrow> b dvd d \<Longrightarrow> c dvd d"
   560   assumes "a dvd c" and "b dvd c" and "\<And>d. a dvd d \<Longrightarrow> b dvd d \<Longrightarrow> c dvd d"
   624     and "normalize c = c"
   561     and "normalize c = c"
   634   "a dvd d \<and> b dvd d \<and> normalize d = d \<and> (\<forall>e. a dvd e \<and> b dvd e \<longrightarrow> d dvd e) \<longleftrightarrow> d = lcm a b"
   571   "a dvd d \<and> b dvd d \<and> normalize d = d \<and> (\<forall>e. a dvd e \<and> b dvd e \<longrightarrow> d dvd e) \<longleftrightarrow> d = lcm a b"
   635   by rule (auto intro: lcmI simp: lcm_least lcm_eq_0_iff)
   572   by rule (auto intro: lcmI simp: lcm_least lcm_eq_0_iff)
   636 
   573 
   637 lemma lcm_proj1_if_dvd:
   574 lemma lcm_proj1_if_dvd:
   638   assumes "b dvd a" shows "lcm a b = normalize a"
   575   assumes "b dvd a" shows "lcm a b = normalize a"
   639 proof (cases "a = 0")
   576 proof -
   640   case False
   577   have "normalize (lcm a b) = normalize a"
   641   then show ?thesis
   578     by (rule associatedI) (use assms in auto)
   642     using assms gcd_proj2_if_dvd lcm_mult_gcd local.lcm_gcd by auto
   579   thus ?thesis by simp
   643 qed auto
   580 qed
   644 
   581 
   645 lemma lcm_proj2_if_dvd: "a dvd b \<Longrightarrow> lcm a b = normalize b"
   582 lemma lcm_proj2_if_dvd: "a dvd b \<Longrightarrow> lcm a b = normalize b"
   646   using lcm_proj1_if_dvd [of a b] by (simp add: ac_simps)
   583   using lcm_proj1_if_dvd [of a b] by (simp add: ac_simps)
   647 
   584 
   648 lemma lcm_proj1_iff: "lcm m n = normalize m \<longleftrightarrow> n dvd m"
   585 lemma lcm_proj1_iff: "lcm m n = normalize m \<longleftrightarrow> n dvd m"
   665 qed
   602 qed
   666 
   603 
   667 lemma lcm_proj2_iff: "lcm m n = normalize n \<longleftrightarrow> m dvd n"
   604 lemma lcm_proj2_iff: "lcm m n = normalize n \<longleftrightarrow> m dvd n"
   668   using lcm_proj1_iff [of n m] by (simp add: ac_simps)
   605   using lcm_proj1_iff [of n m] by (simp add: ac_simps)
   669 
   606 
   670 lemma lcm_mult_distrib': "normalize c * lcm a b = lcm (c * a) (c * b)"
       
   671   by (rule lcmI) (auto simp: normalize_mult lcm_least mult_dvd_mono lcm_mult_left [symmetric])
       
   672 
       
   673 lemma lcm_mult_distrib: "k * lcm a b = lcm (k * a) (k * b) * unit_factor k"
       
   674 proof-
       
   675   have "normalize k * lcm a b = lcm (k * a) (k * b)"
       
   676     by (simp add: lcm_mult_distrib')
       
   677   then have "normalize k * lcm a b * unit_factor k = lcm (k * a) (k * b) * unit_factor k"
       
   678     by simp
       
   679   then have "normalize k * unit_factor k * lcm a b  = lcm (k * a) (k * b) * unit_factor k"
       
   680     by (simp only: ac_simps)
       
   681   then show ?thesis
       
   682     by simp
       
   683 qed
       
   684 
       
   685 lemma gcd_mono: "a dvd c \<Longrightarrow> b dvd d \<Longrightarrow> gcd a b dvd gcd c d"
   607 lemma gcd_mono: "a dvd c \<Longrightarrow> b dvd d \<Longrightarrow> gcd a b dvd gcd c d"
   686   by (simp add: gcd_dvdI1 gcd_dvdI2)
   608   by (simp add: gcd_dvdI1 gcd_dvdI2)
   687 
   609 
   688 lemma lcm_mono: "a dvd c \<Longrightarrow> b dvd d \<Longrightarrow> lcm a b dvd lcm c d"
   610 lemma lcm_mono: "a dvd c \<Longrightarrow> b dvd d \<Longrightarrow> lcm a b dvd lcm c d"
   689   by (simp add: dvd_lcmI1 dvd_lcmI2)
   611   by (simp add: dvd_lcmI1 dvd_lcmI2)
   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
   829   by (blast intro: Lcm_least dvd_Lcm)
   784   by (blast intro: Lcm_least dvd_Lcm)
   830 
   785 
   831 lemma Lcm_Un: "Lcm (A \<union> B) = lcm (Lcm A) (Lcm B)"
   786 lemma Lcm_Un: "Lcm (A \<union> B) = lcm (Lcm A) (Lcm B)"
   832 proof -
   787 proof -
   833   have "\<And>d. \<lbrakk>Lcm A dvd d; Lcm B dvd d\<rbrakk> \<Longrightarrow> Lcm (A \<union> B) dvd d"
   788   have "\<And>d. \<lbrakk>Lcm A dvd d; Lcm B dvd d\<rbrakk> \<Longrightarrow> Lcm (A \<union> B) dvd d"
   834     by (meson UnE local.Lcm_least local.dvd_Lcm local.dvd_trans)
   789     by (meson UnE Lcm_least dvd_Lcm dvd_trans)
   835   then show ?thesis
   790   then show ?thesis
   836     by (meson Lcm_subset local.lcm_unique local.normalize_Lcm sup.cobounded1 sup.cobounded2)
   791     by (meson Lcm_subset lcm_unique normalize_Lcm sup.cobounded1 sup.cobounded2)
   837 qed
   792 qed
   838 
   793 
   839 lemma Gcd_0_iff [simp]: "Gcd A = 0 \<longleftrightarrow> A \<subseteq> {0}"
   794 lemma Gcd_0_iff [simp]: "Gcd A = 0 \<longleftrightarrow> A \<subseteq> {0}"
   840   (is "?P \<longleftrightarrow> ?Q")
   795   (is "?P \<longleftrightarrow> ?Q")
   841 proof
   796 proof
   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"
  1019 lemma Lcm_dvd_iff: "Lcm A dvd x \<longleftrightarrow> (\<forall>y\<in>A. y dvd x)"
   968 lemma Lcm_dvd_iff: "Lcm A dvd x \<longleftrightarrow> (\<forall>y\<in>A. y dvd x)"
  1020   by (blast dest: Lcm_dvdD intro: Lcm_least)
   969   by (blast dest: Lcm_dvdD intro: Lcm_least)
  1021 
   970 
  1022 lemma Lcm_mult:
   971 lemma Lcm_mult:
  1023   assumes "A \<noteq> {}"
   972   assumes "A \<noteq> {}"
  1024   shows "Lcm ((*) c ` A) = normalize c * Lcm A"
   973   shows "Lcm ((*) c ` A) = normalize (c * Lcm A)"
  1025 proof (cases "c = 0")
   974 proof (cases "c = 0")
  1026   case True
   975   case True
  1027   with assms have "(*) c ` A = {0}"
   976   with assms have "(*) c ` A = {0}"
  1028     by auto
   977     by auto
  1029   with True show ?thesis by auto
   978   with True show ?thesis by auto
  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"
  1173 lemma lcm_list_dvd_iff:
  1116 lemma lcm_list_dvd_iff:
  1174   "lcm_list xs dvd b  \<longleftrightarrow> (\<forall>a\<in>set xs. a dvd b)"
  1117   "lcm_list xs dvd b  \<longleftrightarrow> (\<forall>a\<in>set xs. a dvd b)"
  1175   by (simp add: Lcm_fin_dvd_iff)
  1118   by (simp add: Lcm_fin_dvd_iff)
  1176 
  1119 
  1177 lemma Gcd_fin_mult:
  1120 lemma Gcd_fin_mult:
  1178   "Gcd\<^sub>f\<^sub>i\<^sub>n (image (times b) A) = normalize b * Gcd\<^sub>f\<^sub>i\<^sub>n A" if "finite A"
  1121   "Gcd\<^sub>f\<^sub>i\<^sub>n (image (times b) A) = normalize (b * Gcd\<^sub>f\<^sub>i\<^sub>n A)" if "finite A"
  1179 using that proof induct
  1122   using that by induction (auto simp: gcd_mult_left)
  1180   case empty
       
  1181   then show ?case
       
  1182     by simp
       
  1183 next
       
  1184   case (insert a A)
       
  1185   have "gcd (b * a) (b * Gcd\<^sub>f\<^sub>i\<^sub>n A) = gcd (b * a) (normalize (b * Gcd\<^sub>f\<^sub>i\<^sub>n A))"
       
  1186     by simp
       
  1187   also have "\<dots> = gcd (b * a) (normalize b * Gcd\<^sub>f\<^sub>i\<^sub>n A)"
       
  1188     by (simp add: normalize_mult)
       
  1189   finally show ?case
       
  1190     using insert by (simp add: gcd_mult_distrib')
       
  1191 qed
       
  1192 
  1123 
  1193 lemma Lcm_fin_mult:
  1124 lemma Lcm_fin_mult:
  1194   "Lcm\<^sub>f\<^sub>i\<^sub>n (image (times b) A) = normalize b * Lcm\<^sub>f\<^sub>i\<^sub>n A" if "A \<noteq> {}"
  1125   "Lcm\<^sub>f\<^sub>i\<^sub>n (image (times b) A) = normalize (b * Lcm\<^sub>f\<^sub>i\<^sub>n A)" if "A \<noteq> {}"
  1195 proof (cases "b = 0")
  1126 proof (cases "b = 0")
  1196   case True
  1127   case True
  1197   moreover from that have "times 0 ` A = {0}"
  1128   moreover from that have "times 0 ` A = {0}"
  1198     by auto
  1129     by auto
  1199   ultimately show ?thesis
  1130   ultimately show ?thesis
  1208       by (simp add: finite_image_iff)
  1139       by (simp add: finite_image_iff)
  1209     with False show ?thesis
  1140     with False show ?thesis
  1210       by simp
  1141       by simp
  1211   next
  1142   next
  1212     case True
  1143     case True
  1213     then show ?thesis using that proof (induct A rule: finite_ne_induct)
  1144     then show ?thesis using that
  1214       case (singleton a)
  1145       by (induct A rule: finite_ne_induct) (auto simp: lcm_mult_left)
  1215       then show ?case
       
  1216         by (simp add: normalize_mult)
       
  1217     next
       
  1218       case (insert a A)
       
  1219       have "lcm (b * a) (b * Lcm\<^sub>f\<^sub>i\<^sub>n A) = lcm (b * a) (normalize (b * Lcm\<^sub>f\<^sub>i\<^sub>n A))"
       
  1220         by simp
       
  1221       also have "\<dots> = lcm (b * a) (normalize b * Lcm\<^sub>f\<^sub>i\<^sub>n A)"
       
  1222         by (simp add: normalize_mult)
       
  1223       finally show ?case
       
  1224         using insert by (simp add: lcm_mult_distrib')
       
  1225     qed
       
  1226   qed
  1146   qed
  1227 qed
  1147 qed
  1228 
  1148 
  1229 lemma unit_factor_Gcd_fin:
  1149 lemma unit_factor_Gcd_fin:
  1230   "unit_factor (Gcd\<^sub>f\<^sub>i\<^sub>n A) = of_bool (Gcd\<^sub>f\<^sub>i\<^sub>n A \<noteq> 0)"
  1150   "unit_factor (Gcd\<^sub>f\<^sub>i\<^sub>n A) = of_bool (Gcd\<^sub>f\<^sub>i\<^sub>n A \<noteq> 0)"
  1411       by simp
  1331       by simp
  1412   next
  1332   next
  1413     case False
  1333     case False
  1414     then have unit: "is_unit (unit_factor b)"
  1334     then have unit: "is_unit (unit_factor b)"
  1415       by simp
  1335       by simp
  1416     from \<open>coprime a c\<close> mult_gcd_left [of b a c]
  1336     from \<open>coprime a c\<close>
  1417     have "gcd (b * a) (b * c) * unit_factor b = b"
  1337     have "gcd (b * a) (b * c) * unit_factor b = b"
  1418       by (simp add: ac_simps)
  1338       by (subst gcd_mult_left) (simp add: ac_simps)
  1419     moreover from \<open>a dvd b * c\<close>
  1339     moreover from \<open>a dvd b * c\<close>
  1420     have "a dvd gcd (b * a) (b * c) * unit_factor b"
  1340     have "a dvd gcd (b * a) (b * c) * unit_factor b"
  1421       by (simp add: dvd_mult_unit_iff unit)
  1341       by (simp add: dvd_mult_unit_iff unit)
  1422     ultimately show ?thesis
  1342     ultimately show ?thesis
  1423       by simp
  1343       by simp
  1477 proof -
  1397 proof -
  1478   from c have "a \<noteq> 0 \<or> b \<noteq> 0"
  1398   from c have "a \<noteq> 0 \<or> b \<noteq> 0"
  1479     by simp
  1399     by simp
  1480   with div_gcd_coprime have "coprime (a div gcd a b) (b div gcd a b)" .
  1400   with div_gcd_coprime have "coprime (a div gcd a b) (b div gcd a b)" .
  1481   also from assms have "a div gcd a b = a'"
  1401   also from assms have "a div gcd a b = a'"
  1482     using dvd_div_eq_mult local.gcd_dvd1 by blast
  1402     using dvd_div_eq_mult gcd_dvd1 by blast
  1483   also from assms have "b div gcd a b = b'"
  1403   also from assms have "b div gcd a b = b'"
  1484     using dvd_div_eq_mult local.gcd_dvd1 by blast
  1404     using dvd_div_eq_mult gcd_dvd1 by blast
  1485   finally show ?thesis .
  1405   finally show ?thesis .
  1486 qed
  1406 qed
  1487 
  1407 
  1488 lemma gcd_coprime_exists:
  1408 lemma gcd_coprime_exists:
  1489   assumes "gcd a b \<noteq> 0"
  1409   assumes "gcd a b \<noteq> 0"
  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>
  1944 qed (simp_all add: lcm_nat_def)
  1926 qed (simp_all add: lcm_nat_def)
  1945 
  1927 
  1946 instance int :: ring_gcd
  1928 instance int :: ring_gcd
  1947 proof
  1929 proof
  1948   fix k l r :: int
  1930   fix k l r :: int
  1949   show "gcd k l dvd k" "gcd k l dvd l"
  1931   show [simp]: "gcd k l dvd k" "gcd k l dvd l"
  1950     using gcd_dvd1 [of "nat \<bar>k\<bar>" "nat \<bar>l\<bar>"]
  1932     using gcd_dvd1 [of "nat \<bar>k\<bar>" "nat \<bar>l\<bar>"]
  1951       gcd_dvd2 [of "nat \<bar>k\<bar>" "nat \<bar>l\<bar>"]
  1933       gcd_dvd2 [of "nat \<bar>k\<bar>" "nat \<bar>l\<bar>"]
  1952     by simp_all
  1934     by simp_all
  1953   show "lcm k l = normalize (k * l) div gcd k l"
  1935   show "lcm k l = normalize (k * l div gcd k l)"
  1954     using lcm_gcd [of "nat \<bar>k\<bar>" "nat \<bar>l\<bar>"]
  1936     using lcm_gcd [of "nat \<bar>k\<bar>" "nat \<bar>l\<bar>"]
  1955     by (simp add: nat_eq_iff of_nat_div abs_mult)
  1937     by (simp add: nat_eq_iff of_nat_div abs_mult abs_div)
  1956   assume "r dvd k" "r dvd l"
  1938   assume "r dvd k" "r dvd l"
  1957   then show "r dvd gcd k l"
  1939   then show "r dvd gcd k l"
  1958     using gcd_greatest [of "nat \<bar>r\<bar>" "nat \<bar>k\<bar>" "nat \<bar>l\<bar>"]
  1940     using gcd_greatest [of "nat \<bar>r\<bar>" "nat \<bar>k\<bar>" "nat \<bar>l\<bar>"]
  1959     by simp
  1941     by simp
  1960 qed simp
  1942 qed simp
  2008 text \<open>\<^medskip> Multiplication laws.\<close>
  1990 text \<open>\<^medskip> Multiplication laws.\<close>
  2009 
  1991 
  2010 lemma gcd_mult_distrib_nat: "k * gcd m n = gcd (k * m) (k * n)"
  1992 lemma gcd_mult_distrib_nat: "k * gcd m n = gcd (k * m) (k * n)"
  2011   for k m n :: nat
  1993   for k m n :: nat
  2012   \<comment> \<open>@{cite \<open>page 27\<close> davenport92}\<close>
  1994   \<comment> \<open>@{cite \<open>page 27\<close> davenport92}\<close>
  2013 proof (induct m n rule: gcd_nat_induct)
  1995   by (simp add: gcd_mult_left)
  2014   case (step m n)
       
  2015   then show ?case
       
  2016     by (metis gcd_mult_distrib' gcd_red_nat)
       
  2017 qed auto
       
  2018 
  1996 
  2019 lemma gcd_mult_distrib_int: "\<bar>k\<bar> * gcd m n = gcd (k * m) (k * n)"
  1997 lemma gcd_mult_distrib_int: "\<bar>k\<bar> * gcd m n = gcd (k * m) (k * n)"
  2020   for k m n :: int
  1998   for k m n :: int
  2021   using gcd_mult_distrib' [of k m n] by simp
  1999   by (simp add: gcd_mult_left abs_mult)
  2022 
  2000 
  2023 text \<open>\medskip Addition laws.\<close>
  2001 text \<open>\medskip Addition laws.\<close>
  2024 
  2002 
  2025 (* TODO: add the other variations? *)
  2003 (* TODO: add the other variations? *)
  2026 
  2004 
  2398 
  2376 
  2399 subsection \<open>LCM properties on \<^typ>\<open>nat\<close> and \<^typ>\<open>int\<close>\<close>
  2377 subsection \<open>LCM properties on \<^typ>\<open>nat\<close> and \<^typ>\<open>int\<close>\<close>
  2400 
  2378 
  2401 lemma lcm_altdef_int [code]: "lcm a b = \<bar>a\<bar> * \<bar>b\<bar> div gcd a b"
  2379 lemma lcm_altdef_int [code]: "lcm a b = \<bar>a\<bar> * \<bar>b\<bar> div gcd a b"
  2402   for a b :: int
  2380   for a b :: int
  2403   by (simp add: abs_mult lcm_gcd)
  2381   by (simp add: abs_mult lcm_gcd abs_div)
  2404   
  2382   
  2405 lemma prod_gcd_lcm_nat: "m * n = gcd m n * lcm m n"
  2383 lemma prod_gcd_lcm_nat: "m * n = gcd m n * lcm m n"
  2406   for m n :: nat
  2384   for m n :: nat
  2407   by simp
  2385   by (simp add: lcm_gcd)
  2408 
  2386 
  2409 lemma prod_gcd_lcm_int: "\<bar>m\<bar> * \<bar>n\<bar> = gcd m n * lcm m n"
  2387 lemma prod_gcd_lcm_int: "\<bar>m\<bar> * \<bar>n\<bar> = gcd m n * lcm m n"
  2410   for m n :: int
  2388   for m n :: int
  2411   by simp
  2389   by (simp add: lcm_gcd abs_div abs_mult)
  2412 
  2390 
  2413 lemma lcm_pos_nat: "m > 0 \<Longrightarrow> n > 0 \<Longrightarrow> lcm m n > 0"
  2391 lemma lcm_pos_nat: "m > 0 \<Longrightarrow> n > 0 \<Longrightarrow> lcm m n > 0"
  2414   for m n :: nat
  2392   for m n :: nat
  2415   using lcm_eq_0_iff [of m n] by auto
  2393   using lcm_eq_0_iff [of m n] by auto
  2416 
  2394 
  2550 end
  2528 end
  2551 
  2529 
  2552 lemma Gcd_nat_eq_one: "1 \<in> N \<Longrightarrow> Gcd N = 1"
  2530 lemma Gcd_nat_eq_one: "1 \<in> N \<Longrightarrow> Gcd N = 1"
  2553   for N :: "nat set"
  2531   for N :: "nat set"
  2554   by (rule Gcd_eq_1_I) auto
  2532   by (rule Gcd_eq_1_I) auto
       
  2533 
       
  2534 instance nat :: semiring_gcd_mult_normalize
       
  2535   by intro_classes (auto simp: unit_factor_nat_def)
  2555 
  2536 
  2556 
  2537 
  2557 text \<open>Alternative characterizations of Gcd:\<close>
  2538 text \<open>Alternative characterizations of Gcd:\<close>
  2558 
  2539 
  2559 lemma Gcd_eq_Max:
  2540 lemma Gcd_eq_Max:
  2693   proof -
  2674   proof -
  2694     have "(LCM k\<in>K. nat \<bar>k\<bar>) dvd nat \<bar>k\<bar>"
  2675     have "(LCM k\<in>K. nat \<bar>k\<bar>) dvd nat \<bar>k\<bar>"
  2695       by (rule Lcm_least) (use that in auto)
  2676       by (rule Lcm_least) (use that in auto)
  2696     then show ?thesis by simp
  2677     then show ?thesis by simp
  2697   qed
  2678   qed
  2698 qed simp_all
  2679 qed (simp_all add: sgn_mult)
       
  2680 
       
  2681 instance int :: semiring_gcd_mult_normalize
       
  2682   by intro_classes (auto simp: sgn_mult)
  2699 
  2683 
  2700 
  2684 
  2701 subsection \<open>GCD and LCM on \<^typ>\<open>integer\<close>\<close>
  2685 subsection \<open>GCD and LCM on \<^typ>\<open>integer\<close>\<close>
  2702 
  2686 
  2703 instantiation integer :: gcd
  2687 instantiation integer :: gcd