Theory Primes_Ex
section ‹Primes›
theory Primes_Ex
imports Auto2_Main
begin
subsection ‹Basic definition›
definition prime :: "nat ⇒ bool" where [rewrite]:
"prime p = (1 < p ∧ (∀m. m dvd p ⟶ m = 1 ∨ m = p))"
lemma primeD1 [forward]: "prime p ⟹ 1 < p" by auto2
lemma primeD2: "prime p ⟹ m dvd p ⟹ m = 1 ∨ m = p" by auto2
setup ‹add_forward_prfstep_cond @{thm primeD2} [with_cond "?m ≠ 1", with_cond "?m ≠ ?p"]›
setup ‹del_prfstep_thm_eqforward @{thm prime_def}›
theorem exists_prime [resolve]: "∃p. prime p"
@proof @have "prime 2" @qed
lemma prime_odd_nat: "prime p ⟹ p > 2 ⟹ odd p" by auto2
lemma prime_imp_coprime_nat [backward2]: "prime p ⟹ ¬ p dvd n ⟹ coprime p n" by auto2
lemma prime_dvd_mult_nat: "prime p ⟹ p dvd m * n ⟹ p dvd m ∨ p dvd n" by auto2
setup ‹add_forward_prfstep_cond @{thm prime_dvd_mult_nat}
(with_conds ["?m ≠ ?p", "?n ≠ ?p", "?m ≠ ?p * ?m'", "?n ≠ ?p * ?n'"])›
theorem prime_dvd_intro: "prime p ⟹ p * q = m * n ⟹ p dvd m ∨ p dvd n"
@proof @have "p dvd m * n" @qed
setup ‹add_forward_prfstep_cond @{thm prime_dvd_intro}
(with_conds ["?m ≠ ?p", "?n ≠ ?p", "?m ≠ ?p * ?m'", "?n ≠ ?p * ?n'"])›
lemma prime_dvd_mult_eq_nat: "prime p ⟹ p dvd m * n = (p dvd m ∨ p dvd n)" by auto2
lemma not_prime_eq_prod_nat [backward1]: "n > 1 ⟹ ¬ prime n ⟹
∃m k. n = m * k ∧ 1 < m ∧ m < n ∧ 1 < k ∧ k < n"
@proof
@obtain m where "m dvd n ∧ m ≠ 1 ∧ m ≠ n"
@obtain k where "n = m * k" @have "m ≤ m * k" @have "k ≤ m * k"
@qed
lemma prime_dvd_power_nat: "prime p ⟹ p dvd x^n ⟹ p dvd x" by auto2
setup ‹add_forward_prfstep_cond @{thm prime_dvd_power_nat} [with_cond "?p ≠ ?x"]›
lemma prime_dvd_power_nat_iff: "prime p ⟹ n > 0 ⟹ p dvd x^n ⟷ p dvd x" by auto2
lemma prime_nat_code: "prime p = (1 < p ∧ (∀x. 1 < x ∧ x < p ⟶ ¬ x dvd p))" by auto2
lemma prime_factor_nat [backward]: "n ≠ 1 ⟹ ∃p. p dvd n ∧ prime p"
@proof
@strong_induct n
@case "prime n" @case "n = 0"
@obtain k where "k ≠ 1" "k ≠ n" "k dvd n"
@apply_induct_hyp k
@qed
lemma prime_divprod_pow_nat:
"prime p ⟹ coprime a b ⟹ p^n dvd a * b ⟹ p^n dvd a ∨ p^n dvd b" by auto2
lemma prime_product [forward]: "prime (p * q) ⟹ p = 1 ∨ q = 1"
@proof @have "p dvd q * p" @qed
lemma prime_exp: "prime (p ^ n) ⟷ n = 1 ∧ prime p" by auto2
lemma prime_power_mult: "prime p ⟹ x * y = p ^ k ⟹ ∃i j. x = p ^ i ∧ y = p ^ j"
@proof
@induct k arbitrary x y @with
@subgoal "k = Suc k'"
@case "p dvd x" @with
@obtain x' where "x = p * x'" @have "x * y = p * (x' * y)"
@obtain i j where "x' = p ^ i" "y = p ^ j" @have "x = p ^ Suc i" @end
@case "p dvd y" @with
@obtain y' where "y = p * y'" @have "x * y = p * (x * y')"
@obtain i j where "x = p ^ i" "y' = p ^ j" @have "y = p ^ Suc j" @end
@endgoal
@end
@qed
subsection ‹Infinitude of primes›
theorem bigger_prime [resolve]: "∃p. prime p ∧ n < p"
@proof
@obtain p where "prime p" "p dvd fact n + 1"
@case "n ≥ p" @with @have "(p::nat) dvd fact n" @end
@qed
theorem primes_infinite: "¬ finite {p. prime p}"
@proof
@obtain b where "prime b" "Max {p. prime p} < b"
@qed
subsection ‹Existence and uniqueness of prime factorization›
theorem factorization_exists: "n > 0 ⟹ ∃M. (∀p∈#M. prime p) ∧ n = (∏i∈#M. i)"
@proof
@strong_induct n
@case "n = 1" @with @have "n = (∏i∈# {#}. i)" @end
@case "prime n" @with @have "n = (∏i∈# {#n#}. i)" @end
@obtain m k where "n = m * k" "1 < m" "m < n" "1 < k" "k < n"
@apply_induct_hyp m
@obtain M where "(∀p∈#M. prime p)" "m = (∏i∈#M. i)"
@apply_induct_hyp k
@obtain K where "(∀p∈#K. prime p)" "k = (∏i∈#K. i)"
@have "n = (∏i∈#(M+K). i)"
@qed
theorem prime_dvd_multiset [backward1]: "prime p ⟹ p dvd (∏i∈#M. i) ⟹ ∃n. n∈#M ∧ p dvd n"
@proof
@strong_induct M
@case "M = {#}"
@obtain M' m where "M = M' + {#m#}"
@contradiction @apply_induct_hyp M'
@qed
theorem factorization_unique_aux:
"∀p∈#M. prime p ⟹ ∀p∈#N. prime p ⟹ (∏i∈#M. i) dvd (∏i∈#N. i) ⟹ M ⊆# N"
@proof
@strong_induct M arbitrary N
@case "M = {#}"
@obtain M' m where "M = M' + {#m#}"
@have "m dvd (∏i∈#M. i)"
@obtain n where "n ∈# N" "m dvd n"
@obtain N' where "N = N' + {#n#}"
@have "m = n"
@have "(∏i∈#M'. i) dvd (∏i∈#N'. i)"
@apply_induct_hyp M' N'
@qed
setup ‹add_forward_prfstep_cond @{thm factorization_unique_aux} [with_cond "?M ≠ ?N"]›
theorem factorization_unique:
"∀p∈#M. prime p ⟹ ∀p∈#N. prime p ⟹ (∏i∈#M. i) = (∏i∈#N. i) ⟹ M = N"
@proof @have "M ⊆# N" @qed
setup ‹del_prfstep_thm @{thm factorization_unique_aux}›
end