src/HOL/GCD.thy
changeset 57512 cc97b347b301
parent 56218 1c3f1f2431f9
child 57514 bdc2c6b40bf2
equal deleted inserted replaced
57511:de51a86fc903 57512:cc97b347b301
   408   apply (rule dvd_antisym)
   408   apply (rule dvd_antisym)
   409   apply (rule gcd_greatest_nat)
   409   apply (rule gcd_greatest_nat)
   410   apply (rule_tac n = k in coprime_dvd_mult_nat)
   410   apply (rule_tac n = k in coprime_dvd_mult_nat)
   411   apply (simp add: gcd_assoc_nat)
   411   apply (simp add: gcd_assoc_nat)
   412   apply (simp add: gcd_commute_nat)
   412   apply (simp add: gcd_commute_nat)
   413   apply (simp_all add: mult_commute)
   413   apply (simp_all add: mult.commute)
   414 done
   414 done
   415 
   415 
   416 lemma gcd_mult_cancel_int:
   416 lemma gcd_mult_cancel_int:
   417   "coprime (k::int) n \<Longrightarrow> gcd (k * m) n = gcd m n"
   417   "coprime (k::int) n \<Longrightarrow> gcd (k * m) n = gcd m n"
   418 apply (subst (1 2) gcd_abs_int)
   418 apply (subst (1 2) gcd_abs_int)
   430   assume ?lhs
   430   assume ?lhs
   431   from `?lhs` have "a dvd b * d" by (auto intro: dvdI dest: sym)
   431   from `?lhs` have "a dvd b * d" by (auto intro: dvdI dest: sym)
   432   with `coprime a d` have "a dvd b" by (simp add: coprime_dvd_mult_iff_nat)
   432   with `coprime a d` have "a dvd b" by (simp add: coprime_dvd_mult_iff_nat)
   433   from `?lhs` have "b dvd a * c" by (auto intro: dvdI dest: sym)
   433   from `?lhs` have "b dvd a * c" by (auto intro: dvdI dest: sym)
   434   with `coprime b c` have "b dvd a" by (simp add: coprime_dvd_mult_iff_nat)
   434   with `coprime b c` have "b dvd a" by (simp add: coprime_dvd_mult_iff_nat)
   435   from `?lhs` have "c dvd d * b" by (auto intro: dvdI dest: sym simp add: mult_commute)
   435   from `?lhs` have "c dvd d * b" by (auto intro: dvdI dest: sym simp add: mult.commute)
   436   with `coprime b c` have "c dvd d" by (simp add: coprime_dvd_mult_iff_nat gcd_commute_nat)
   436   with `coprime b c` have "c dvd d" by (simp add: coprime_dvd_mult_iff_nat gcd_commute_nat)
   437   from `?lhs` have "d dvd c * a" by (auto intro: dvdI dest: sym simp add: mult_commute)
   437   from `?lhs` have "d dvd c * a" by (auto intro: dvdI dest: sym simp add: mult.commute)
   438   with `coprime a d` have "d dvd c" by (simp add: coprime_dvd_mult_iff_nat gcd_commute_nat)
   438   with `coprime a d` have "d dvd c" by (simp add: coprime_dvd_mult_iff_nat gcd_commute_nat)
   439   from `a dvd b` `b dvd a` have "a = b" by (rule Nat.dvd.antisym)
   439   from `a dvd b` `b dvd a` have "a = b" by (rule Nat.dvd.antisym)
   440   moreover from `c dvd d` `d dvd c` have "c = d" by (rule Nat.dvd.antisym)
   440   moreover from `c dvd d` `d dvd c` have "c = d" by (rule Nat.dvd.antisym)
   441   ultimately show ?rhs ..
   441   ultimately show ?rhs ..
   442 qed
   442 qed
   454   apply (simp_all add: gcd_non_0_nat)
   454   apply (simp_all add: gcd_non_0_nat)
   455 done
   455 done
   456 
   456 
   457 lemma gcd_add2_nat [simp]: "gcd (m::nat) (m + n) = gcd m n"
   457 lemma gcd_add2_nat [simp]: "gcd (m::nat) (m + n) = gcd m n"
   458   apply (subst (1 2) gcd_commute_nat)
   458   apply (subst (1 2) gcd_commute_nat)
   459   apply (subst add_commute)
   459   apply (subst add.commute)
   460   apply simp
   460   apply simp
   461 done
   461 done
   462 
   462 
   463 (* to do: add the other variations? *)
   463 (* to do: add the other variations? *)
   464 
   464 
   494   apply (insert gcd_non_0_int [of "-y" "-x"])
   494   apply (insert gcd_non_0_int [of "-y" "-x"])
   495   apply auto
   495   apply auto
   496 done
   496 done
   497 
   497 
   498 lemma gcd_add1_int [simp]: "gcd ((m::int) + n) n = gcd m n"
   498 lemma gcd_add1_int [simp]: "gcd ((m::int) + n) n = gcd m n"
   499 by (metis gcd_red_int mod_add_self1 add_commute)
   499 by (metis gcd_red_int mod_add_self1 add.commute)
   500 
   500 
   501 lemma gcd_add2_int [simp]: "gcd m ((m::int) + n) = gcd m n"
   501 lemma gcd_add2_int [simp]: "gcd m ((m::int) + n) = gcd m n"
   502 by (metis gcd_add1_int gcd_commute_int add_commute)
   502 by (metis gcd_add1_int gcd_commute_int add.commute)
   503 
   503 
   504 lemma gcd_add_mult_nat: "gcd (m::nat) (k * m + n) = gcd m n"
   504 lemma gcd_add_mult_nat: "gcd (m::nat) (k * m + n) = gcd m n"
   505 by (metis mod_mult_self3 gcd_commute_nat gcd_red_nat)
   505 by (metis mod_mult_self3 gcd_commute_nat gcd_red_nat)
   506 
   506 
   507 lemma gcd_add_mult_int: "gcd (m::int) (k * m + n) = gcd m n"
   507 lemma gcd_add_mult_int: "gcd (m::int) (k * m + n) = gcd m n"
   508 by (metis gcd_commute_int gcd_red_int mod_mult_self1 add_commute)
   508 by (metis gcd_commute_int gcd_red_int mod_mult_self1 add.commute)
   509 
   509 
   510 
   510 
   511 (* to do: differences, and all variations of addition rules
   511 (* to do: differences, and all variations of addition rules
   512     as simplification rules for nat and int *)
   512     as simplification rules for nat and int *)
   513 
   513 
   776   next assume "~(a = 0 & b = 0)"
   776   next assume "~(a = 0 & b = 0)"
   777   hence "coprime ((a div gcd a b)^n) ((b div gcd a b)^n)"
   777   hence "coprime ((a div gcd a b)^n) ((b div gcd a b)^n)"
   778     by (auto simp:div_gcd_coprime_nat)
   778     by (auto simp:div_gcd_coprime_nat)
   779   hence "gcd ((a div gcd a b)^n * (gcd a b)^n)
   779   hence "gcd ((a div gcd a b)^n * (gcd a b)^n)
   780       ((b div gcd a b)^n * (gcd a b)^n) = (gcd a b)^n"
   780       ((b div gcd a b)^n * (gcd a b)^n) = (gcd a b)^n"
   781     apply (subst (1 2) mult_commute)
   781     apply (subst (1 2) mult.commute)
   782     apply (subst gcd_mult_distrib_nat [symmetric])
   782     apply (subst gcd_mult_distrib_nat [symmetric])
   783     apply simp
   783     apply simp
   784     done
   784     done
   785   also have "(a div gcd a b)^n * (gcd a b)^n = a^n"
   785   also have "(a div gcd a b)^n * (gcd a b)^n = a^n"
   786     apply (subst div_power)
   786     apply (subst div_power)
   818       by blast
   818       by blast
   819     have thb: "?g dvd b" by auto
   819     have thb: "?g dvd b" by auto
   820     from ab'(1) have "a' dvd a"  unfolding dvd_def by blast
   820     from ab'(1) have "a' dvd a"  unfolding dvd_def by blast
   821     with dc have th0: "a' dvd b*c" using dvd_trans[of a' a "b*c"] by simp
   821     with dc have th0: "a' dvd b*c" using dvd_trans[of a' a "b*c"] by simp
   822     from dc ab'(1,2) have "a'*?g dvd (b'*?g) *c" by auto
   822     from dc ab'(1,2) have "a'*?g dvd (b'*?g) *c" by auto
   823     hence "?g*a' dvd ?g * (b' * c)" by (simp add: mult_assoc)
   823     hence "?g*a' dvd ?g * (b' * c)" by (simp add: mult.assoc)
   824     with z have th_1: "a' dvd b' * c" by auto
   824     with z have th_1: "a' dvd b' * c" by auto
   825     from coprime_dvd_mult_nat[OF ab'(3)] th_1
   825     from coprime_dvd_mult_nat[OF ab'(3)] th_1
   826     have thc: "a' dvd c" by (subst (asm) mult_commute, blast)
   826     have thc: "a' dvd c" by (subst (asm) mult.commute, blast)
   827     from ab' have "a = ?g*a'" by algebra
   827     from ab' have "a = ?g*a'" by algebra
   828     with thb thc have ?thesis by blast }
   828     with thb thc have ?thesis by blast }
   829   ultimately show ?thesis by blast
   829   ultimately show ?thesis by blast
   830 qed
   830 qed
   831 
   831 
   842     have thb: "?g dvd b" by auto
   842     have thb: "?g dvd b" by auto
   843     from ab'(1) have "a' dvd a"  unfolding dvd_def by blast
   843     from ab'(1) have "a' dvd a"  unfolding dvd_def by blast
   844     with dc have th0: "a' dvd b*c"
   844     with dc have th0: "a' dvd b*c"
   845       using dvd_trans[of a' a "b*c"] by simp
   845       using dvd_trans[of a' a "b*c"] by simp
   846     from dc ab'(1,2) have "a'*?g dvd (b'*?g) *c" by auto
   846     from dc ab'(1,2) have "a'*?g dvd (b'*?g) *c" by auto
   847     hence "?g*a' dvd ?g * (b' * c)" by (simp add: mult_assoc)
   847     hence "?g*a' dvd ?g * (b' * c)" by (simp add: mult.assoc)
   848     with z have th_1: "a' dvd b' * c" by auto
   848     with z have th_1: "a' dvd b' * c" by auto
   849     from coprime_dvd_mult_int[OF ab'(3)] th_1
   849     from coprime_dvd_mult_int[OF ab'(3)] th_1
   850     have thc: "a' dvd c" by (subst (asm) mult_commute, blast)
   850     have thc: "a' dvd c" by (subst (asm) mult.commute, blast)
   851     from ab' have "a = ?g*a'" by algebra
   851     from ab' have "a = ?g*a'" by algebra
   852     with thb thc have ?thesis by blast }
   852     with thb thc have ?thesis by blast }
   853   ultimately show ?thesis by blast
   853   ultimately show ?thesis by blast
   854 qed
   854 qed
   855 
   855 
   867     obtain a' b' where ab': "a = a' * ?g" "b = b' * ?g" "coprime a' b'"
   867     obtain a' b' where ab': "a = a' * ?g" "b = b' * ?g" "coprime a' b'"
   868       by blast
   868       by blast
   869     from ab have "(a' * ?g) ^ n dvd (b' * ?g)^n"
   869     from ab have "(a' * ?g) ^ n dvd (b' * ?g)^n"
   870       by (simp add: ab'(1,2)[symmetric])
   870       by (simp add: ab'(1,2)[symmetric])
   871     hence "?g^n*a'^n dvd ?g^n *b'^n"
   871     hence "?g^n*a'^n dvd ?g^n *b'^n"
   872       by (simp only: power_mult_distrib mult_commute)
   872       by (simp only: power_mult_distrib mult.commute)
   873     with zn z n have th0:"a'^n dvd b'^n" by auto
   873     with zn z n have th0:"a'^n dvd b'^n" by auto
   874     have "a' dvd a'^n" by (simp add: m)
   874     have "a' dvd a'^n" by (simp add: m)
   875     with th0 have "a' dvd b'^n" using dvd_trans[of a' "a'^n" "b'^n"] by simp
   875     with th0 have "a' dvd b'^n" using dvd_trans[of a' "a'^n" "b'^n"] by simp
   876     hence th1: "a' dvd b'^m * b'" by (simp add: m mult_commute)
   876     hence th1: "a' dvd b'^m * b'" by (simp add: m mult.commute)
   877     from coprime_dvd_mult_nat[OF coprime_exp_nat [OF ab'(3), of m]] th1
   877     from coprime_dvd_mult_nat[OF coprime_exp_nat [OF ab'(3), of m]] th1
   878     have "a' dvd b'" by (subst (asm) mult_commute, blast)
   878     have "a' dvd b'" by (subst (asm) mult.commute, blast)
   879     hence "a'*?g dvd b'*?g" by simp
   879     hence "a'*?g dvd b'*?g" by simp
   880     with ab'(1,2)  have ?thesis by simp }
   880     with ab'(1,2)  have ?thesis by simp }
   881   ultimately show ?thesis by blast
   881   ultimately show ?thesis by blast
   882 qed
   882 qed
   883 
   883 
   895     obtain a' b' where ab': "a = a' * ?g" "b = b' * ?g" "coprime a' b'"
   895     obtain a' b' where ab': "a = a' * ?g" "b = b' * ?g" "coprime a' b'"
   896       by blast
   896       by blast
   897     from ab have "(a' * ?g) ^ n dvd (b' * ?g)^n"
   897     from ab have "(a' * ?g) ^ n dvd (b' * ?g)^n"
   898       by (simp add: ab'(1,2)[symmetric])
   898       by (simp add: ab'(1,2)[symmetric])
   899     hence "?g^n*a'^n dvd ?g^n *b'^n"
   899     hence "?g^n*a'^n dvd ?g^n *b'^n"
   900       by (simp only: power_mult_distrib mult_commute)
   900       by (simp only: power_mult_distrib mult.commute)
   901     with zn z n have th0:"a'^n dvd b'^n" by auto
   901     with zn z n have th0:"a'^n dvd b'^n" by auto
   902     have "a' dvd a'^n" by (simp add: m)
   902     have "a' dvd a'^n" by (simp add: m)
   903     with th0 have "a' dvd b'^n"
   903     with th0 have "a' dvd b'^n"
   904       using dvd_trans[of a' "a'^n" "b'^n"] by simp
   904       using dvd_trans[of a' "a'^n" "b'^n"] by simp
   905     hence th1: "a' dvd b'^m * b'" by (simp add: m mult_commute)
   905     hence th1: "a' dvd b'^m * b'" by (simp add: m mult.commute)
   906     from coprime_dvd_mult_int[OF coprime_exp_int [OF ab'(3), of m]] th1
   906     from coprime_dvd_mult_int[OF coprime_exp_int [OF ab'(3), of m]] th1
   907     have "a' dvd b'" by (subst (asm) mult_commute, blast)
   907     have "a' dvd b'" by (subst (asm) mult.commute, blast)
   908     hence "a'*?g dvd b'*?g" by simp
   908     hence "a'*?g dvd b'*?g" by simp
   909     with ab'(1,2)  have ?thesis by simp }
   909     with ab'(1,2)  have ?thesis by simp }
   910   ultimately show ?thesis by blast
   910   ultimately show ?thesis by blast
   911 qed
   911 qed
   912 
   912 
   920   assumes mr: "(m::nat) dvd r" and nr: "n dvd r" and mn:"coprime m n"
   920   assumes mr: "(m::nat) dvd r" and nr: "n dvd r" and mn:"coprime m n"
   921   shows "m * n dvd r"
   921   shows "m * n dvd r"
   922 proof-
   922 proof-
   923   from mr nr obtain m' n' where m': "r = m*m'" and n': "r = n*n'"
   923   from mr nr obtain m' n' where m': "r = m*m'" and n': "r = n*n'"
   924     unfolding dvd_def by blast
   924     unfolding dvd_def by blast
   925   from mr n' have "m dvd n'*n" by (simp add: mult_commute)
   925   from mr n' have "m dvd n'*n" by (simp add: mult.commute)
   926   hence "m dvd n'" using coprime_dvd_mult_iff_nat[OF mn] by simp
   926   hence "m dvd n'" using coprime_dvd_mult_iff_nat[OF mn] by simp
   927   then obtain k where k: "n' = m*k" unfolding dvd_def by blast
   927   then obtain k where k: "n' = m*k" unfolding dvd_def by blast
   928   from n' k show ?thesis unfolding dvd_def by auto
   928   from n' k show ?thesis unfolding dvd_def by auto
   929 qed
   929 qed
   930 
   930 
   932   assumes mr: "(m::int) dvd r" and nr: "n dvd r" and mn:"coprime m n"
   932   assumes mr: "(m::int) dvd r" and nr: "n dvd r" and mn:"coprime m n"
   933   shows "m * n dvd r"
   933   shows "m * n dvd r"
   934 proof-
   934 proof-
   935   from mr nr obtain m' n' where m': "r = m*m'" and n': "r = n*n'"
   935   from mr nr obtain m' n' where m': "r = m*m'" and n': "r = n*n'"
   936     unfolding dvd_def by blast
   936     unfolding dvd_def by blast
   937   from mr n' have "m dvd n'*n" by (simp add: mult_commute)
   937   from mr n' have "m dvd n'*n" by (simp add: mult.commute)
   938   hence "m dvd n'" using coprime_dvd_mult_iff_int[OF mn] by simp
   938   hence "m dvd n'" using coprime_dvd_mult_iff_int[OF mn] by simp
   939   then obtain k where k: "n' = m*k" unfolding dvd_def by blast
   939   then obtain k where k: "n' = m*k" unfolding dvd_def by blast
   940   from n' k show ?thesis unfolding dvd_def by auto
   940   from n' k show ?thesis unfolding dvd_def by auto
   941 qed
   941 qed
   942 
   942 
  1216           with xp mult_mono[of "1" "x" "d*b" "b*(b - 1)"]
  1216           with xp mult_mono[of "1" "x" "d*b" "b*(b - 1)"]
  1217           have dble: "d*b \<le> x*b*(b - 1)" using bp by simp
  1217           have dble: "d*b \<le> x*b*(b - 1)" using bp by simp
  1218           from H (3) have "d + (b - 1) * (b*x) = d + (b - 1) * (a*y + d)"
  1218           from H (3) have "d + (b - 1) * (b*x) = d + (b - 1) * (a*y + d)"
  1219             by simp
  1219             by simp
  1220           hence "d + (b - 1) * a * y + (b - 1) * d = d + (b - 1) * b * x"
  1220           hence "d + (b - 1) * a * y + (b - 1) * d = d + (b - 1) * b * x"
  1221             by (simp only: mult_assoc distrib_left)
  1221             by (simp only: mult.assoc distrib_left)
  1222           hence "a * ((b - 1) * y) + d * (b - 1 + 1) = d + x*b*(b - 1)"
  1222           hence "a * ((b - 1) * y) + d * (b - 1 + 1) = d + x*b*(b - 1)"
  1223             by algebra
  1223             by algebra
  1224           hence "a * ((b - 1) * y) = d + x*b*(b - 1) - d*b" using bp by simp
  1224           hence "a * ((b - 1) * y) = d + x*b*(b - 1) - d*b" using bp by simp
  1225           hence "a * ((b - 1) * y) = d + (x*b*(b - 1) - d*b)"
  1225           hence "a * ((b - 1) * y) = d + (x*b*(b - 1) - d*b)"
  1226             by (simp only: diff_add_assoc[OF dble, of d, symmetric])
  1226             by (simp only: diff_add_assoc[OF dble, of d, symmetric])
  1227           hence "a * ((b - 1) * y) = b*(x*(b - 1) - d) + d"
  1227           hence "a * ((b - 1) * y) = b*(x*(b - 1) - d) + d"
  1228             by (simp only: diff_mult_distrib2 add_commute mult_ac)
  1228             by (simp only: diff_mult_distrib2 add.commute mult_ac)
  1229           hence ?thesis using H(1,2)
  1229           hence ?thesis using H(1,2)
  1230             apply -
  1230             apply -
  1231             apply (rule exI[where x=d], simp)
  1231             apply (rule exI[where x=d], simp)
  1232             apply (rule exI[where x="(b - 1) * y"])
  1232             apply (rule exI[where x="(b - 1) * y"])
  1233             by (rule exI[where x="x*(b - 1) - d"], simp)}
  1233             by (rule exI[where x="x*(b - 1) - d"], simp)}
  1672   "inj_on f A \<Longrightarrow> inj_on g B \<Longrightarrow> ALL a:A. ALL b:B. coprime (f a) (g b)
  1672   "inj_on f A \<Longrightarrow> inj_on g B \<Longrightarrow> ALL a:A. ALL b:B. coprime (f a) (g b)
  1673    \<Longrightarrow> inj_on (%(a,b). f a * g b::nat) (A \<times> B)"
  1673    \<Longrightarrow> inj_on (%(a,b). f a * g b::nat) (A \<times> B)"
  1674 apply(auto simp add:inj_on_def)
  1674 apply(auto simp add:inj_on_def)
  1675 apply (metis coprime_dvd_mult_iff_nat dvd.neq_le_trans dvd_triv_left)
  1675 apply (metis coprime_dvd_mult_iff_nat dvd.neq_le_trans dvd_triv_left)
  1676 apply (metis gcd_semilattice_nat.inf_commute coprime_dvd_mult_iff_nat
  1676 apply (metis gcd_semilattice_nat.inf_commute coprime_dvd_mult_iff_nat
  1677              dvd.neq_le_trans dvd_triv_right mult_commute)
  1677              dvd.neq_le_trans dvd_triv_right mult.commute)
  1678 done
  1678 done
  1679 
  1679 
  1680 text{* Nitpick: *}
  1680 text{* Nitpick: *}
  1681 
  1681 
  1682 lemma gcd_eq_nitpick_gcd [nitpick_unfold]: "gcd x y = Nitpick.nat_gcd x y"
  1682 lemma gcd_eq_nitpick_gcd [nitpick_unfold]: "gcd x y = Nitpick.nat_gcd x y"