src/HOL/Library/Primes.thy
changeset 27556 292098f2efdf
parent 27487 c8a6ce181805
child 27567 e3fe9a327c63
equal deleted inserted replaced
27555:dfda3192dec2 27556:292098f2efdf
    10 imports Plain "~~/src/HOL/ATP_Linkup" GCD Parity
    10 imports Plain "~~/src/HOL/ATP_Linkup" GCD Parity
    11 begin
    11 begin
    12 
    12 
    13 definition
    13 definition
    14   coprime :: "nat => nat => bool" where
    14   coprime :: "nat => nat => bool" where
    15   "coprime m n \<longleftrightarrow> (gcd (m, n) = 1)"
    15   "coprime m n \<longleftrightarrow> (gcd m n = 1)"
    16 
    16 
    17 definition
    17 definition
    18   prime :: "nat \<Rightarrow> bool" where
    18   prime :: "nat \<Rightarrow> bool" where
    19   [code func del]: "prime p \<longleftrightarrow> (1 < p \<and> (\<forall>m. m dvd p --> m = 1 \<or> m = p))"
    19   [code func del]: "prime p \<longleftrightarrow> (1 < p \<and> (\<forall>m. m dvd p --> m = 1 \<or> m = p))"
    20 
    20 
    23   apply (auto simp add: prime_def)
    23   apply (auto simp add: prime_def)
    24   apply (case_tac m)
    24   apply (case_tac m)
    25    apply (auto dest!: dvd_imp_le)
    25    apply (auto dest!: dvd_imp_le)
    26   done
    26   done
    27 
    27 
    28 lemma prime_imp_relprime: "prime p ==> \<not> p dvd n ==> gcd (p, n) = 1"
    28 lemma prime_imp_relprime: "prime p ==> \<not> p dvd n ==> gcd p n = 1"
    29   apply (auto simp add: prime_def)
    29   apply (auto simp add: prime_def)
    30   apply (metis One_nat_def gcd_dvd1 gcd_dvd2)
    30   apply (metis One_nat_def gcd_dvd1 gcd_dvd2)
    31   done
    31   done
    32 
    32 
    33 text {*
    33 text {*
   307   ultimately have ?thesis by blast}
   307   ultimately have ?thesis by blast}
   308  ultimately show ?thesis by blast
   308  ultimately show ?thesis by blast
   309 qed
   309 qed
   310 
   310 
   311 text {* Greatest common divisor. *}
   311 text {* Greatest common divisor. *}
   312 lemma gcd_unique: "d dvd a\<and>d dvd b \<and> (\<forall>e. e dvd a \<and> e dvd b \<longrightarrow> e dvd d) \<longleftrightarrow> d = gcd(a,b)"
   312 lemma gcd_unique: "d dvd a\<and>d dvd b \<and> (\<forall>e. e dvd a \<and> e dvd b \<longrightarrow> e dvd d) \<longleftrightarrow> d = gcd a b"
   313 proof(auto)
   313 proof(auto)
   314   assume H: "d dvd a" "d dvd b" "\<forall>e. e dvd a \<and> e dvd b \<longrightarrow> e dvd d"
   314   assume H: "d dvd a" "d dvd b" "\<forall>e. e dvd a \<and> e dvd b \<longrightarrow> e dvd d"
   315   from H(3)[rule_format] gcd_dvd1[of a b] gcd_dvd2[of a b] 
   315   from H(3)[rule_format] gcd_dvd1[of a b] gcd_dvd2[of a b] 
   316   have th: "gcd (a,b) dvd d" by blast
   316   have th: "gcd a b dvd d" by blast
   317   from dvd_anti_sym[OF th gcd_greatest[OF H(1,2)]]  show "d = gcd (a,b)" by blast 
   317   from dvd_anti_sym[OF th gcd_greatest[OF H(1,2)]] show "d =gcd a b" by blast 
   318 qed
   318 qed
   319 
   319 
   320 lemma gcd_eq: assumes H: "\<forall>d. d dvd x \<and> d dvd y \<longleftrightarrow> d dvd u \<and> d dvd v"
   320 lemma gcd_eq: assumes H: "\<forall>d. d dvd x \<and> d dvd y \<longleftrightarrow> d dvd u \<and> d dvd v"
   321   shows "gcd (x,y) = gcd(u,v)"
   321   shows "gcd x y = gcd u v"
   322 proof-
   322 proof-
   323   from H have "\<forall>d. d dvd x \<and> d dvd y \<longleftrightarrow> d dvd gcd (u,v)" by simp
   323   from H have "\<forall>d. d dvd x \<and> d dvd y \<longleftrightarrow> d dvd gcd u v" by simp
   324   with gcd_unique[of "gcd(u,v)" x y]  show ?thesis by auto
   324   with gcd_unique[of "gcd u v" x y]  show ?thesis by auto
   325 qed
   325 qed
   326 
   326 
   327 lemma bezout_gcd: "\<exists>x y. a * x - b * y = gcd(a,b) \<or> b * x - a * y = gcd(a,b)"
   327 lemma bezout_gcd: "\<exists>x y. a * x - b * y = gcd a b \<or> b * x - a * y = gcd a b"
   328 proof-
   328 proof-
   329   let ?g = "gcd (a,b)"
   329   let ?g = "gcd a b"
   330   from bezout[of a b] obtain d x y where d: "d dvd a" "d dvd b" "a * x - b * y = d \<or> b * x - a * y = d" by blast
   330   from bezout[of a b] obtain d x y where d: "d dvd a" "d dvd b" "a * x - b * y = d \<or> b * x - a * y = d" by blast
   331   from d(1,2) have "d dvd ?g" by simp
   331   from d(1,2) have "d dvd ?g" by simp
   332   then obtain k where k: "?g = d*k" unfolding dvd_def by blast
   332   then obtain k where k: "?g = d*k" unfolding dvd_def by blast
   333   from d(3) have "(a * x - b * y)*k = d*k \<or> (b * x - a * y)*k = d*k" by blast 
   333   from d(3) have "(a * x - b * y)*k = d*k \<or> (b * x - a * y)*k = d*k" by blast 
   334   hence "a * x * k - b * y*k = d*k \<or> b * x * k - a * y*k = d*k"
   334   hence "a * x * k - b * y*k = d*k \<or> b * x * k - a * y*k = d*k"
   337     by (simp add: k mult_assoc)
   337     by (simp add: k mult_assoc)
   338   thus ?thesis by blast
   338   thus ?thesis by blast
   339 qed
   339 qed
   340 
   340 
   341 lemma bezout_gcd_strong: assumes a: "a \<noteq> 0" 
   341 lemma bezout_gcd_strong: assumes a: "a \<noteq> 0" 
   342   shows "\<exists>x y. a * x = b * y + gcd(a,b)"
   342   shows "\<exists>x y. a * x = b * y + gcd a b"
   343 proof-
   343 proof-
   344   let ?g = "gcd (a,b)"
   344   let ?g = "gcd a b"
   345   from bezout_add_strong[OF a, of b]
   345   from bezout_add_strong[OF a, of b]
   346   obtain d x y where d: "d dvd a" "d dvd b" "a * x = b * y + d" by blast
   346   obtain d x y where d: "d dvd a" "d dvd b" "a * x = b * y + d" by blast
   347   from d(1,2) have "d dvd ?g" by simp
   347   from d(1,2) have "d dvd ?g" by simp
   348   then obtain k where k: "?g = d*k" unfolding dvd_def by blast
   348   then obtain k where k: "?g = d*k" unfolding dvd_def by blast
   349   from d(3) have "a * x * k = (b * y + d) *k " by auto 
   349   from d(3) have "a * x * k = (b * y + d) *k " by auto 
   350   hence "a * (x * k) = b * (y*k) + ?g" by (algebra add: k)
   350   hence "a * (x * k) = b * (y*k) + ?g" by (algebra add: k)
   351   thus ?thesis by blast
   351   thus ?thesis by blast
   352 qed
   352 qed
   353 
   353 
   354 lemma gcd_mult_distrib: "gcd(a * c, b * c) = c * gcd(a,b)"
   354 lemma gcd_mult_distrib: "gcd (a * c) (b * c) = c * gcd a b"
   355 by(simp add: gcd_mult_distrib2 mult_commute)
   355 by(simp add: gcd_mult_distrib2 mult_commute)
   356 
   356 
   357 lemma gcd_bezout: "(\<exists>x y. a * x - b * y = d \<or> b * x - a * y = d) \<longleftrightarrow> gcd(a,b) dvd d"
   357 lemma gcd_bezout: "(\<exists>x y. a * x - b * y = d \<or> b * x - a * y = d) \<longleftrightarrow> gcd a b dvd d"
   358   (is "?lhs \<longleftrightarrow> ?rhs")
   358   (is "?lhs \<longleftrightarrow> ?rhs")
   359 proof-
   359 proof-
   360   let ?g = "gcd (a,b)"
   360   let ?g = "gcd a b"
   361   {assume H: ?rhs then obtain k where k: "d = ?g*k" unfolding dvd_def by blast
   361   {assume H: ?rhs then obtain k where k: "d = ?g*k" unfolding dvd_def by blast
   362     from bezout_gcd[of a b] obtain x y where xy: "a * x - b * y = ?g \<or> b * x - a * y = ?g"
   362     from bezout_gcd[of a b] obtain x y where xy: "a * x - b * y = ?g \<or> b * x - a * y = ?g"
   363       by blast
   363       by blast
   364     hence "(a * x - b * y)*k = ?g*k \<or> (b * x - a * y)*k = ?g*k" by auto
   364     hence "(a * x - b * y)*k = ?g*k \<or> (b * x - a * y)*k = ?g*k" by auto
   365     hence "a * x*k - b * y*k = ?g*k \<or> b * x * k - a * y*k = ?g*k" 
   365     hence "a * x*k - b * y*k = ?g*k \<or> b * x * k - a * y*k = ?g*k" 
   374     from dvd_diff[OF dv(1,2)] dvd_diff[OF dv(3,4)] H
   374     from dvd_diff[OF dv(1,2)] dvd_diff[OF dv(3,4)] H
   375     have ?rhs by auto}
   375     have ?rhs by auto}
   376   ultimately show ?thesis by blast
   376   ultimately show ?thesis by blast
   377 qed
   377 qed
   378 
   378 
   379 lemma gcd_bezout_sum: assumes H:"a * x + b * y = d" shows "gcd(a,b) dvd d"
   379 lemma gcd_bezout_sum: assumes H:"a * x + b * y = d" shows "gcd a b dvd d"
   380 proof-
   380 proof-
   381   let ?g = "gcd (a,b)"
   381   let ?g = "gcd a b"
   382     have dv: "?g dvd a*x" "?g dvd b * y" 
   382     have dv: "?g dvd a*x" "?g dvd b * y" 
   383       using dvd_mult2[OF gcd_dvd1[of a b]] dvd_mult2[OF gcd_dvd2[of a b]] by simp_all
   383       using dvd_mult2[OF gcd_dvd1[of a b]] dvd_mult2[OF gcd_dvd2[of a b]] by simp_all
   384     from dvd_add[OF dv] H
   384     from dvd_add[OF dv] H
   385     show ?thesis by auto
   385     show ?thesis by auto
   386 qed
   386 qed
   387 
   387 
   388 lemma gcd_mult': "gcd(b,a * b) = b"
   388 lemma gcd_mult': "gcd b (a * b) = b"
   389 by (simp add: gcd_mult mult_commute[of a b]) 
   389 by (simp add: gcd_mult mult_commute[of a b]) 
   390 
   390 
   391 lemma gcd_add: "gcd(a + b,b) = gcd(a,b)" "gcd(b + a,b) = gcd(a,b)" "gcd(a,a + b) = gcd(a,b)" "gcd(a,b + a) = gcd(a,b)"
   391 lemma gcd_add: "gcd (a + b) b = gcd a b" "gcd (b + a) b = gcd a b" "gcd a (a + b) = gcd a b" "gcd a (b + a) = gcd a b"
   392 apply (simp_all add: gcd_add1)
   392 apply (simp_all add: gcd_add1)
   393 by (simp add: gcd_commute gcd_add1)
   393 by (simp add: gcd_commute gcd_add1)
   394 
   394 
   395 lemma gcd_sub: "b <= a ==> gcd(a - b,b) = gcd(a,b)" "a <= b ==> gcd(a,b - a) = gcd(a,b)"
   395 lemma gcd_sub: "b <= a ==> gcd (a - b) b = gcd a b" "a <= b ==> gcd a (b - a) = gcd a b"
   396 proof-
   396 proof-
   397   {fix a b assume H: "b \<le> (a::nat)"
   397   {fix a b assume H: "b \<le> (a::nat)"
   398     hence th: "a - b + b = a" by arith
   398     hence th: "a - b + b = a" by arith
   399     from gcd_add(1)[of "a - b" b] th  have "gcd(a - b,b) = gcd(a,b)" by simp}
   399     from gcd_add(1)[of "a - b" b] th  have "gcd (a - b) b = gcd a b" by simp}
   400   note th = this
   400   note th = this
   401 {
   401 {
   402   assume ab: "b \<le> a"
   402   assume ab: "b \<le> a"
   403   from th[OF ab] show "gcd (a - b, b) = gcd (a, b)" by blast
   403   from th[OF ab] show "gcd (a - b) b = gcd a b" by blast
   404 next
   404 next
   405   assume ab: "a \<le> b"
   405   assume ab: "a \<le> b"
   406   from th[OF ab] show "gcd (a,b - a) = gcd (a, b)" 
   406   from th[OF ab] show "gcd a (b - a) = gcd a b" 
   407     by (simp add: gcd_commute)}
   407     by (simp add: gcd_commute)}
   408 qed
   408 qed
   409 
   409 
   410 text {* Coprimality *}
   410 text {* Coprimality *}
   411 
   411 
   423 lemma coprime_1'[simp]: "coprime 1 a" by (simp add: coprime_def)
   423 lemma coprime_1'[simp]: "coprime 1 a" by (simp add: coprime_def)
   424 lemma coprime_Suc0[simp]: "coprime a (Suc 0)" by (simp add: coprime_def)
   424 lemma coprime_Suc0[simp]: "coprime a (Suc 0)" by (simp add: coprime_def)
   425 lemma coprime_Suc0'[simp]: "coprime (Suc 0) a" by (simp add: coprime_def)
   425 lemma coprime_Suc0'[simp]: "coprime (Suc 0) a" by (simp add: coprime_def)
   426 
   426 
   427 lemma gcd_coprime: 
   427 lemma gcd_coprime: 
   428   assumes z: "gcd(a,b) \<noteq> 0" and a: "a = a' * gcd(a,b)" and b: "b = b' * gcd(a,b)" 
   428   assumes z: "gcd a b \<noteq> 0" and a: "a = a' * gcd a b" and b: "b = b' * gcd a b" 
   429   shows    "coprime a' b'"
   429   shows    "coprime a' b'"
   430 proof-
   430 proof-
   431   let ?g = "gcd(a,b)"
   431   let ?g = "gcd a b"
   432   {assume bz: "a = 0" from b bz z a have ?thesis by (simp add: gcd_zero coprime_def)}
   432   {assume bz: "a = 0" from b bz z a have ?thesis by (simp add: gcd_zero coprime_def)}
   433   moreover 
   433   moreover 
   434   {assume az: "a\<noteq> 0" 
   434   {assume az: "a\<noteq> 0" 
   435     from z have z': "?g > 0" by simp
   435     from z have z': "?g > 0" by simp
   436     from bezout_gcd_strong[OF az, of b] 
   436     from bezout_gcd_strong[OF az, of b] 
   445 qed
   445 qed
   446 lemma coprime_0: "coprime d 0 \<longleftrightarrow> d = 1" by (simp add: coprime_def)
   446 lemma coprime_0: "coprime d 0 \<longleftrightarrow> d = 1" by (simp add: coprime_def)
   447 lemma coprime_mul: assumes da: "coprime d a" and db: "coprime d b"
   447 lemma coprime_mul: assumes da: "coprime d a" and db: "coprime d b"
   448   shows "coprime d (a * b)"
   448   shows "coprime d (a * b)"
   449 proof-
   449 proof-
   450   from da have th: "gcd(a, d) = 1" by (simp add: coprime_def gcd_commute)
   450   from da have th: "gcd a d = 1" by (simp add: coprime_def gcd_commute)
   451   from gcd_mult_cancel[of a d b, OF th] db[unfolded coprime_def] have "gcd (d, a*b) = 1"
   451   from gcd_mult_cancel[of a d b, OF th] db[unfolded coprime_def] have "gcd d (a * b) = 1"
   452     by (simp add: gcd_commute)
   452     by (simp add: gcd_commute)
   453   thus ?thesis unfolding coprime_def .
   453   thus ?thesis unfolding coprime_def .
   454 qed
   454 qed
   455 lemma coprime_lmul2: assumes dab: "coprime d (a * b)" shows "coprime d b"
   455 lemma coprime_lmul2: assumes dab: "coprime d (a * b)" shows "coprime d b"
   456 using prems unfolding coprime_bezout
   456 using prems unfolding coprime_bezout
   478 lemma coprime_mul_eq: "coprime d (a * b) \<longleftrightarrow> coprime d a \<and>  coprime d b"
   478 lemma coprime_mul_eq: "coprime d (a * b) \<longleftrightarrow> coprime d a \<and>  coprime d b"
   479   using coprime_rmul2[of d a b] coprime_lmul2[of d a b] coprime_mul[of d a b] 
   479   using coprime_rmul2[of d a b] coprime_lmul2[of d a b] coprime_mul[of d a b] 
   480   by blast
   480   by blast
   481 
   481 
   482 lemma gcd_coprime_exists:
   482 lemma gcd_coprime_exists:
   483   assumes nz: "gcd(a,b) \<noteq> 0" 
   483   assumes nz: "gcd a b \<noteq> 0" 
   484   shows "\<exists>a' b'. a = a' * gcd(a,b) \<and> b = b' * gcd(a,b) \<and> coprime a' b'"
   484   shows "\<exists>a' b'. a = a' * gcd a b \<and> b = b' * gcd a b \<and> coprime a' b'"
   485 proof-
   485 proof-
   486   let ?g = "gcd (a,b)"
   486   let ?g = "gcd a b"
   487   from gcd_dvd1[of a b] gcd_dvd2[of a b] 
   487   from gcd_dvd1[of a b] gcd_dvd2[of a b] 
   488   obtain a' b' where "a = ?g*a'"  "b = ?g*b'" unfolding dvd_def by blast
   488   obtain a' b' where "a = ?g*a'"  "b = ?g*b'" unfolding dvd_def by blast
   489   hence ab': "a = a'*?g" "b = b'*?g" by algebra+
   489   hence ab': "a = a'*?g" "b = b'*?g" by algebra+
   490   from ab' gcd_coprime[OF nz ab'] show ?thesis by blast
   490   from ab' gcd_coprime[OF nz ab'] show ?thesis by blast
   491 qed
   491 qed
   503   apply simp
   503   apply simp
   504   done
   504   done
   505 lemma coprime_minus1: "n \<noteq> 0 ==> coprime (n - 1) n"
   505 lemma coprime_minus1: "n \<noteq> 0 ==> coprime (n - 1) n"
   506   using coprime_plus1[of "n - 1"] coprime_commute[of "n - 1" n] by auto
   506   using coprime_plus1[of "n - 1"] coprime_commute[of "n - 1" n] by auto
   507 
   507 
   508 lemma bezout_gcd_pow: "\<exists>x y. a ^n * x - b ^ n * y = gcd(a,b) ^ n \<or> b ^ n * x - a ^ n * y = gcd(a,b) ^ n"
   508 lemma bezout_gcd_pow: "\<exists>x y. a ^n * x - b ^ n * y = gcd a b ^ n \<or> b ^ n * x - a ^ n * y = gcd a b ^ n"
   509 proof-
   509 proof-
   510   let ?g = "gcd (a,b)"
   510   let ?g = "gcd a b"
   511   {assume z: "?g = 0" hence ?thesis 
   511   {assume z: "?g = 0" hence ?thesis 
   512       apply (cases n, simp)
   512       apply (cases n, simp)
   513       apply arith
   513       apply arith
   514       apply (simp only: z power_0_Suc)
   514       apply (simp only: z power_0_Suc)
   515       apply (rule exI[where x=0])
   515       apply (rule exI[where x=0])
   528       using z ab'' by (simp only: power_mult_distrib[symmetric] 
   528       using z ab'' by (simp only: power_mult_distrib[symmetric] 
   529 	diff_mult_distrib2 mult_assoc[symmetric])
   529 	diff_mult_distrib2 mult_assoc[symmetric])
   530     hence  ?thesis by blast }
   530     hence  ?thesis by blast }
   531   ultimately show ?thesis by blast
   531   ultimately show ?thesis by blast
   532 qed
   532 qed
   533 lemma gcd_exp: "gcd (a^n, b^n) = gcd(a,b)^n"
   533 lemma gcd_exp: "gcd (a^n) (b^n) = gcd a b ^ n"
   534 proof-
   534 proof-
   535   let ?g = "gcd(a^n,b^n)"
   535   let ?g = "gcd (a^n) (b^n)"
   536   let ?gn = "gcd(a,b)^n"
   536   let ?gn = "gcd a b ^ n"
   537   {fix e assume H: "e dvd a^n" "e dvd b^n"
   537   {fix e assume H: "e dvd a^n" "e dvd b^n"
   538     from bezout_gcd_pow[of a n b] obtain x y 
   538     from bezout_gcd_pow[of a n b] obtain x y 
   539       where xy: "a ^ n * x - b ^ n * y = ?gn \<or> b ^ n * x - a ^ n * y = ?gn" by blast
   539       where xy: "a ^ n * x - b ^ n * y = ?gn \<or> b ^ n * x - a ^ n * y = ?gn" by blast
   540     from dvd_diff [OF dvd_mult2[OF H(1), of x] dvd_mult2[OF H(2), of y]]
   540     from dvd_diff [OF dvd_mult2[OF H(1), of x] dvd_mult2[OF H(2), of y]]
   541       dvd_diff [OF dvd_mult2[OF H(2), of x] dvd_mult2[OF H(1), of y]] xy
   541       dvd_diff [OF dvd_mult2[OF H(2), of x] dvd_mult2[OF H(1), of y]] xy
   542     have "e dvd ?gn" by (cases "a ^ n * x - b ^ n * y = gcd (a, b) ^ n", simp_all)}
   542     have "e dvd ?gn" by (cases "a ^ n * x - b ^ n * y = gcd a b ^ n", simp_all)}
   543   hence th:  "\<forall>e. e dvd a^n \<and> e dvd b^n \<longrightarrow> e dvd ?gn" by blast
   543   hence th:  "\<forall>e. e dvd a^n \<and> e dvd b^n \<longrightarrow> e dvd ?gn" by blast
   544   from divides_exp[OF gcd_dvd1[of a b], of n] divides_exp[OF gcd_dvd2[of a b], of n] th
   544   from divides_exp[OF gcd_dvd1[of a b], of n] divides_exp[OF gcd_dvd2[of a b], of n] th
   545     gcd_unique have "?gn = ?g" by blast thus ?thesis by simp 
   545     gcd_unique have "?gn = ?g" by blast thus ?thesis by simp 
   546 qed
   546 qed
   547 
   547 
   549 by (simp only: coprime_def gcd_exp exp_eq_1) simp
   549 by (simp only: coprime_def gcd_exp exp_eq_1) simp
   550 
   550 
   551 lemma division_decomp: assumes dc: "(a::nat) dvd b * c"
   551 lemma division_decomp: assumes dc: "(a::nat) dvd b * c"
   552   shows "\<exists>b' c'. a = b' * c' \<and> b' dvd b \<and> c' dvd c"
   552   shows "\<exists>b' c'. a = b' * c' \<and> b' dvd b \<and> c' dvd c"
   553 proof-
   553 proof-
   554   let ?g = "gcd (a,b)"
   554   let ?g = "gcd a b"
   555   {assume "?g = 0" with dc have ?thesis apply (simp add: gcd_zero)
   555   {assume "?g = 0" with dc have ?thesis apply (simp add: gcd_zero)
   556       apply (rule exI[where x="0"])
   556       apply (rule exI[where x="0"])
   557       by (rule exI[where x="c"], simp)}
   557       by (rule exI[where x="c"], simp)}
   558   moreover
   558   moreover
   559   {assume z: "?g \<noteq> 0"
   559   {assume z: "?g \<noteq> 0"
   573 
   573 
   574 lemma nat_power_eq_0_iff: "(m::nat) ^ n = 0 \<longleftrightarrow> n \<noteq> 0 \<and> m = 0" by (induct n, auto)
   574 lemma nat_power_eq_0_iff: "(m::nat) ^ n = 0 \<longleftrightarrow> n \<noteq> 0 \<and> m = 0" by (induct n, auto)
   575 
   575 
   576 lemma divides_rev: assumes ab: "(a::nat) ^ n dvd b ^n" and n:"n \<noteq> 0" shows "a dvd b"
   576 lemma divides_rev: assumes ab: "(a::nat) ^ n dvd b ^n" and n:"n \<noteq> 0" shows "a dvd b"
   577 proof-
   577 proof-
   578   let ?g = "gcd (a,b)"
   578   let ?g = "gcd a b"
   579   from n obtain m where m: "n = Suc m" by (cases n, simp_all)
   579   from n obtain m where m: "n = Suc m" by (cases n, simp_all)
   580   {assume "?g = 0" with ab n have ?thesis by (simp add: gcd_zero)}
   580   {assume "?g = 0" with ab n have ?thesis by (simp add: gcd_zero)}
   581   moreover
   581   moreover
   582   {assume z: "?g \<noteq> 0"
   582   {assume z: "?g \<noteq> 0"
   583     hence zn: "?g ^ n \<noteq> 0" using n by (simp add: neq0_conv)
   583     hence zn: "?g ^ n \<noteq> 0" using n by (simp add: neq0_conv)