section‹The Divides Relation and Euclid's algorithm for the GCD›
theory Primes imports ZF begin
definition
divides :: "[i,i]==>o" (infixl‹dvd›50) where "m dvd n ≡ m ∈ nat ∧ n ∈ nat ∧ (∃k ∈ nat. n = m#*k)"
definition
is_gcd :: "[i,i,i]==>o" ― ‹definition of great common divisor›where "is_gcd(p,m,n) ≡ ((p dvd m) ∧ (p dvd n)) ∧ (∀d∈nat. (d dvd m) ∧ (d dvd n) ⟶ d dvd p)"
definition
gcd :: "[i,i]==>i" ― ‹Euclid's algorithm for the gcd›where "gcd(m,n) ≡ transrec(natify(n), λn f. λm ∈ nat. if n=0 then m else f`(m mod n)`n) ` natify(m)"
lemma gcd_non_0_raw: "[0<n; n ∈ nat]==> gcd(m,n) = gcd(n, m mod n)" apply (simp add: gcd_def) apply (rule_tac P = "λz. left (z) = right"for left right in transrec [THEN ssubst]) apply (simp add: ltD [THEN mem_imp_not_eq, THEN not_sym]
mod_less_divisor [THEN ltD]) done
lemma gcd_non_0: "0 < natify(n) ==> gcd(m,n) = gcd(n, m mod n)" apply (cut_tac m = m and n = "natify (n) "in gcd_non_0_raw) apply auto done
lemma dvd_add: "[k dvd a; k dvd b]==> k dvd (a #+ b)" apply (simp add: divides_def) apply (fast intro: add_mult_distrib_left [symmetric] add_type) done
lemma dvd_mult: "k dvd n ==> k dvd (m #* n)" apply (simp add: divides_def) apply (fast intro: mult_left_commute mult_type) done
lemma dvd_mult2: "k dvd m ==> k dvd (m #* n)" apply (subst mult_commute) apply (blast intro: dvd_mult) done
(* k dvd (m*k) *) lemmas dvdI1 [simp] = dvd_refl [THEN dvd_mult] lemmas dvdI2 [simp] = dvd_refl [THEN dvd_mult2]
lemma dvd_mod_imp_dvd_raw: "[a ∈ nat; b ∈ nat; k dvd b; k dvd (a mod b)]==> k dvd a" apply (case_tac "b=0") apply (simp add: DIVISION_BY_ZERO_MOD) apply (blast intro: mod_div_equality [THEN subst]
elim: dvdE
intro!: dvd_add dvd_mult mult_type mod_type div_type) done
lemma dvd_mod_imp_dvd: "[k dvd (a mod b); k dvd b; a ∈ nat]==> k dvd a" apply (cut_tac b = "natify (b)"in dvd_mod_imp_dvd_raw) apply auto apply (simp add: divides_def) done
(*Imitating TFL*) lemma gcd_induct_lemma [rule_format (no_asm)]: "[n ∈ nat; ∀m ∈ nat. P(m,0); ∀m ∈ nat. ∀n ∈ nat. 0<n ⟶ P(n, m mod n) ⟶ P(m,n)] ==>∀m ∈ nat. P (m,n)" apply (erule_tac i = n in complete_induct) apply (case_tac "x=0") apply (simp (no_asm_simp)) apply clarify apply (drule_tac x1 = m and x = x in bspec [THEN bspec]) apply (simp_all add: Ord_0_lt_iff) apply (blast intro: mod_less_divisor [THEN ltD]) done
lemma gcd_induct: "∧P. [m ∈ nat; n ∈ nat; ∧m. m ∈ nat ==> P(m,0); ∧m n. [m ∈ nat; n ∈ nat; 0<n; P(n, m mod n)]==> P(m,n)] ==> P (m,n)" by (blast intro: gcd_induct_lemma)
subsection‹Basic Properties of term‹gcd››
text‹type of gcd› lemma gcd_type [simp,TC]: "gcd(m, n) ∈ nat" apply (subgoal_tac "gcd (natify (m), natify (n)) ∈ nat") apply simp apply (rule_tac m = "natify (m)"and n = "natify (n)"in gcd_induct) apply auto apply (simp add: gcd_non_0) done
text‹Property 1: gcd(a,b) divides a and b›
lemma gcd_dvd_both: "[m ∈ nat; n ∈ nat]==> gcd (m, n) dvd m ∧ gcd (m, n) dvd n" apply (rule_tac m = m and n = n in gcd_induct) apply (simp_all add: gcd_non_0) apply (blast intro: dvd_mod_imp_dvd_raw nat_into_Ord [THEN Ord_0_lt]) done
lemma gcd_dvd1 [simp]: "m ∈ nat ==> gcd(m,n) dvd m" apply (cut_tac m = "natify (m)"and n = "natify (n)"in gcd_dvd_both) apply auto done
lemma gcd_dvd2 [simp]: "n ∈ nat ==> gcd(m,n) dvd n" apply (cut_tac m = "natify (m)"and n = "natify (n)"in gcd_dvd_both) apply auto done
text‹if f divides a and b then f divides gcd(a,b)›
lemma dvd_mod: "[f dvd a; f dvd b]==> f dvd (a mod b)" apply (simp add: divides_def) apply (case_tac "b=0") apply (simp add: DIVISION_BY_ZERO_MOD, auto) apply (blast intro: mod_mult_distrib2 [symmetric]) done
text‹Property 2: for all a,b,f naturals,
if f divides a and f divides b then f divides gcd(a,b)›
lemma gcd_greatest_raw [rule_format]: "[m ∈ nat; n ∈ nat; f ∈ nat] ==> (f dvd m) ⟶ (f dvd n) ⟶ f dvd gcd(m,n)" apply (rule_tac m = m and n = n in gcd_induct) apply (simp_all add: gcd_non_0 dvd_mod) done
lemma gcd_greatest: "[f dvd m; f dvd n; f ∈ nat]==> f dvd gcd(m,n)" apply (rule gcd_greatest_raw) apply (auto simp add: divides_def) done
lemma gcd_greatest_iff [simp]: "[k ∈ nat; m ∈ nat; n ∈ nat] ==> (k dvd gcd (m, n)) ⟷ (k dvd m ∧ k dvd n)" by (blast intro!: gcd_greatest gcd_dvd1 gcd_dvd2 intro: dvd_trans)
subsection‹The Greatest Common Divisor›
text‹The GCD exists and function gcd computes it.›
lemma is_gcd: "[m ∈ nat; n ∈ nat]==> is_gcd(gcd(m,n), m, n)" by (simp add: is_gcd_def)
lemma gcd_add_mult: "gcd (m, k #* m #+ n) = gcd (m, n)" apply (cut_tac k = "natify (k)"in gcd_add_mult_raw) apply auto done
subsection‹Multiplication Laws›
lemma gcd_mult_distrib2_raw: "[k ∈ nat; m ∈ nat; n ∈ nat] ==> k #* gcd (m, n) = gcd (k #* m, k #* n)" apply (erule_tac m = m and n = n in gcd_induct, assumption) apply simp apply (case_tac "k = 0", simp) apply (simp add: mod_geq gcd_non_0 mod_mult_distrib2 Ord_0_lt_iff) done
lemma gcd_mult_distrib2: "k #* gcd (m, n) = gcd (k #* m, k #* n)" apply (cut_tac k = "natify (k)"and m = "natify (m)"and n = "natify (n) " in gcd_mult_distrib2_raw) apply auto done
lemma gcd_mult [simp]: "gcd (k, k #* n) = natify(k)" by (cut_tac k = k and m = 1and n = n in gcd_mult_distrib2, auto)
lemma gcd_self [simp]: "gcd (k, k) = natify(k)" by (cut_tac k = k and n = 1in gcd_mult, auto)
lemma relprime_dvd_mult: "[gcd (k,n) = 1; k dvd (m #* n); m ∈ nat]==> k dvd m" apply (cut_tac k = m and m = k and n = n in gcd_mult_distrib2, auto) apply (erule_tac b = m in ssubst) apply (simp add: dvd_imp_nat1) done
lemma relprime_dvd_mult_iff: "[gcd (k,n) = 1; m ∈ nat]==> k dvd (m #* n) ⟷ k dvd m" by (blast intro: dvdI2 relprime_dvd_mult dvd_trans)
lemma prime_imp_relprime: "[p ∈ prime; ¬ (p dvd n); n ∈ nat]==> gcd (p, n) = 1" apply (simp add: prime_def, clarify) apply (drule_tac x = "gcd (p,n)"in bspec) apply auto apply (cut_tac m = p and n = n in gcd_dvd2, auto) done
lemma prime_into_nat: "p ∈ prime ==> p ∈ nat" by (simp add: prime_def)
lemma prime_nonzero: "p ∈ prime ==> p≠0" by (auto simp add: prime_def)
text‹This theorem leads immediately to a proof of the uniqueness of
factorization. If term‹p› divides a product of primes then it is
one of those primes.›
lemma prime_dvd_mult: "[p dvd m #* n; p ∈ prime; m ∈ nat; n ∈ nat]==> p dvd m ∨ p dvd n" by (blast intro: relprime_dvd_mult prime_imp_relprime prime_into_nat)
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.