2015-07-03 05:27:51 +00:00
|
|
|
|
/-
|
|
|
|
|
Copyright (c) 2015 Microsoft Corporation. All rights reserved.
|
|
|
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
2015-07-08 01:55:31 +00:00
|
|
|
|
Authors: Leonardo de Moura, Jeremy Avigad
|
2015-07-03 05:27:51 +00:00
|
|
|
|
|
2015-07-08 01:55:31 +00:00
|
|
|
|
Prime numbers.
|
2015-07-03 05:27:51 +00:00
|
|
|
|
-/
|
2015-07-04 16:49:14 +00:00
|
|
|
|
import data.nat logic.identities
|
2015-07-03 05:27:51 +00:00
|
|
|
|
open bool
|
2015-10-08 18:01:57 +00:00
|
|
|
|
open - [notations] algebra
|
2015-07-03 05:27:51 +00:00
|
|
|
|
|
|
|
|
|
namespace nat
|
|
|
|
|
open decidable
|
|
|
|
|
|
2015-07-03 06:21:10 +00:00
|
|
|
|
definition prime [reducible] (p : nat) := p ≥ 2 ∧ ∀ m, m ∣ p → m = 1 ∨ m = p
|
2015-07-03 05:27:51 +00:00
|
|
|
|
|
2015-07-03 06:21:10 +00:00
|
|
|
|
definition prime_ext (p : nat) := p ≥ 2 ∧ ∀ m, m ≤ p → m ∣ p → m = 1 ∨ m = p
|
|
|
|
|
local attribute prime_ext [reducible]
|
2015-07-03 05:27:51 +00:00
|
|
|
|
|
2015-07-03 06:21:10 +00:00
|
|
|
|
lemma prime_ext_iff_prime (p : nat) : prime_ext p ↔ prime p :=
|
2015-07-03 05:27:51 +00:00
|
|
|
|
iff.intro
|
|
|
|
|
begin
|
|
|
|
|
intro h, cases h with h₁ h₂, constructor, assumption,
|
|
|
|
|
intro m d, exact h₂ m (le_of_dvd (lt_of_succ_le (le_of_succ_le h₁)) d) d
|
|
|
|
|
end
|
|
|
|
|
begin
|
|
|
|
|
intro h, cases h with h₁ h₂, constructor, assumption,
|
|
|
|
|
intro m l d, exact h₂ m d
|
|
|
|
|
end
|
|
|
|
|
|
2015-07-03 06:21:10 +00:00
|
|
|
|
definition decidable_prime [instance] (p : nat) : decidable (prime p) :=
|
|
|
|
|
decidable_of_decidable_of_iff _ (prime_ext_iff_prime p)
|
2015-07-03 05:27:51 +00:00
|
|
|
|
|
2015-07-03 06:21:10 +00:00
|
|
|
|
lemma ge_two_of_prime {p : nat} : prime p → p ≥ 2 :=
|
2015-07-19 19:15:12 +00:00
|
|
|
|
suppose prime p, obtain h₁ h₂, from this,
|
|
|
|
|
h₁
|
2015-07-03 05:27:51 +00:00
|
|
|
|
|
2015-07-08 01:55:31 +00:00
|
|
|
|
theorem gt_one_of_prime {p : ℕ} (primep : prime p) : p > 1 :=
|
|
|
|
|
lt_of_succ_le (ge_two_of_prime primep)
|
|
|
|
|
|
|
|
|
|
theorem pos_of_prime {p : ℕ} (primep : prime p) : p > 0 :=
|
|
|
|
|
lt.trans zero_lt_one (gt_one_of_prime primep)
|
|
|
|
|
|
2015-07-04 06:31:04 +00:00
|
|
|
|
lemma not_prime_zero : ¬ prime 0 :=
|
|
|
|
|
λ h, absurd (ge_two_of_prime h) dec_trivial
|
|
|
|
|
|
|
|
|
|
lemma not_prime_one : ¬ prime 1 :=
|
|
|
|
|
λ h, absurd (ge_two_of_prime h) dec_trivial
|
|
|
|
|
|
|
|
|
|
lemma prime_two : prime 2 :=
|
|
|
|
|
dec_trivial
|
|
|
|
|
|
|
|
|
|
lemma prime_three : prime 3 :=
|
|
|
|
|
dec_trivial
|
|
|
|
|
|
2015-07-03 06:21:10 +00:00
|
|
|
|
lemma pred_prime_pos {p : nat} : prime p → pred p > 0 :=
|
2015-07-19 19:15:12 +00:00
|
|
|
|
suppose prime p,
|
|
|
|
|
have p ≥ 2, from ge_two_of_prime this,
|
|
|
|
|
show pred p > 0, from lt_of_succ_le (pred_le_pred this)
|
2015-07-03 05:27:51 +00:00
|
|
|
|
|
2015-07-03 06:21:10 +00:00
|
|
|
|
lemma succ_pred_prime {p : nat} : prime p → succ (pred p) = p :=
|
2015-07-08 01:55:31 +00:00
|
|
|
|
assume h, succ_pred_of_pos (pos_of_prime h)
|
2015-07-03 05:27:51 +00:00
|
|
|
|
|
2015-07-08 01:55:31 +00:00
|
|
|
|
lemma eq_one_or_eq_self_of_prime_of_dvd {p m : nat} : prime p → m ∣ p → m = 1 ∨ m = p :=
|
2015-07-03 05:27:51 +00:00
|
|
|
|
assume h d, obtain h₁ h₂, from h, h₂ m d
|
|
|
|
|
|
2015-07-03 06:21:10 +00:00
|
|
|
|
lemma gt_one_of_pos_of_prime_dvd {i p : nat} : prime p → 0 < i → i mod p = 0 → 1 < i :=
|
2015-07-03 05:27:51 +00:00
|
|
|
|
assume ipp pos h,
|
2015-07-21 04:43:47 +00:00
|
|
|
|
have p ≥ 2, from ge_two_of_prime ipp,
|
2015-07-21 16:10:56 +00:00
|
|
|
|
have p ∣ i, from dvd_of_mod_eq_zero h,
|
2015-07-21 04:43:47 +00:00
|
|
|
|
have p ≤ i, from le_of_dvd pos this,
|
|
|
|
|
lt_of_succ_le (le.trans `2 ≤ p` this)
|
2015-07-03 05:27:51 +00:00
|
|
|
|
|
2015-07-17 02:48:33 +00:00
|
|
|
|
definition sub_dvd_of_not_prime {n : nat} : n ≥ 2 → ¬ prime n → {m | m ∣ n ∧ m ≠ 1 ∧ m ≠ n} :=
|
2015-07-03 07:31:54 +00:00
|
|
|
|
assume h₁ h₂,
|
2015-07-18 18:36:05 +00:00
|
|
|
|
have ¬ prime_ext n, from iff.mpr (not_iff_not_of_iff !prime_ext_iff_prime) h₂,
|
|
|
|
|
have ¬ n ≥ 2 ∨ ¬ (∀ m, m ≤ n → m ∣ n → m = 1 ∨ m = n), from iff.mp !not_and_iff_not_or_not this,
|
|
|
|
|
have ¬ (∀ m, m ≤ n → m ∣ n → m = 1 ∨ m = n), from or_resolve_right this (not_not_intro h₁),
|
|
|
|
|
have ¬ (∀ m, m < succ n → m ∣ n → m = 1 ∨ m = n), from
|
|
|
|
|
assume h, absurd (λ m hl hd, h m (lt_succ_of_le hl) hd) this,
|
|
|
|
|
have {m | m < succ n ∧ ¬(m ∣ n → m = 1 ∨ m = n)}, from bsub_not_of_not_ball this,
|
|
|
|
|
obtain m hlt (h₃ : ¬(m ∣ n → m = 1 ∨ m = n)), from this,
|
2015-07-22 20:54:47 +00:00
|
|
|
|
obtain `m ∣ n` (h₅ : ¬ (m = 1 ∨ m = n)), from iff.mp !not_implies_iff_and_not h₃,
|
2015-07-18 18:36:05 +00:00
|
|
|
|
have ¬ m = 1 ∧ ¬ m = n, from iff.mp !not_or_iff_not_and_not h₅,
|
2015-07-22 20:54:47 +00:00
|
|
|
|
subtype.tag m (and.intro `m ∣ n` this)
|
2015-07-03 07:31:54 +00:00
|
|
|
|
|
2015-08-17 03:23:03 +00:00
|
|
|
|
theorem exists_dvd_of_not_prime {n : nat} : n ≥ 2 → ¬ prime n → ∃ m, m ∣ n ∧ m ≠ 1 ∧ m ≠ n :=
|
2015-07-17 02:48:33 +00:00
|
|
|
|
assume h₁ h₂, ex_of_sub (sub_dvd_of_not_prime h₁ h₂)
|
2015-07-15 19:49:47 +00:00
|
|
|
|
|
2015-07-17 02:48:33 +00:00
|
|
|
|
definition sub_dvd_of_not_prime2 {n : nat} : n ≥ 2 → ¬ prime n → {m | m ∣ n ∧ m ≥ 2 ∧ m < n} :=
|
2015-07-03 07:31:54 +00:00
|
|
|
|
assume h₁ h₂,
|
2015-07-21 16:10:56 +00:00
|
|
|
|
have n ≠ 0, from assume h, begin subst n, exact absurd h₁ dec_trivial end,
|
2015-07-17 02:48:33 +00:00
|
|
|
|
obtain m m_dvd_n m_ne_1 m_ne_n, from sub_dvd_of_not_prime h₁ h₂,
|
2015-07-21 16:10:56 +00:00
|
|
|
|
assert m_ne_0 : m ≠ 0, from assume h, begin subst m, exact absurd (eq_zero_of_zero_dvd m_dvd_n) `n ≠ 0` end,
|
2015-07-03 07:31:54 +00:00
|
|
|
|
begin
|
|
|
|
|
existsi m, split, assumption,
|
|
|
|
|
split,
|
2015-07-21 16:10:56 +00:00
|
|
|
|
{cases m with m, exact absurd rfl m_ne_0,
|
|
|
|
|
cases m with m, exact absurd rfl m_ne_1, exact succ_le_succ (succ_le_succ (zero_le _))},
|
|
|
|
|
{have m_le_n : m ≤ n, from le_of_dvd (pos_of_ne_zero `n ≠ 0`) m_dvd_n,
|
2015-07-03 07:31:54 +00:00
|
|
|
|
exact lt_of_le_and_ne m_le_n m_ne_n}
|
|
|
|
|
end
|
|
|
|
|
|
2015-08-17 03:23:03 +00:00
|
|
|
|
theorem exists_dvd_of_not_prime2 {n : nat} : n ≥ 2 → ¬ prime n → ∃ m, m ∣ n ∧ m ≥ 2 ∧ m < n :=
|
2015-07-17 02:48:33 +00:00
|
|
|
|
assume h₁ h₂, ex_of_sub (sub_dvd_of_not_prime2 h₁ h₂)
|
2015-07-15 19:49:47 +00:00
|
|
|
|
|
2015-07-17 02:48:33 +00:00
|
|
|
|
definition sub_prime_and_dvd {n : nat} : n ≥ 2 → {p | prime p ∧ p ∣ n} :=
|
2015-07-15 19:49:47 +00:00
|
|
|
|
nat.strong_rec_on n
|
2015-07-03 07:31:54 +00:00
|
|
|
|
(take n,
|
2015-07-17 02:48:33 +00:00
|
|
|
|
assume ih : ∀ m, m < n → m ≥ 2 → {p | prime p ∧ p ∣ m},
|
2015-07-21 16:10:56 +00:00
|
|
|
|
suppose n ≥ 2,
|
2015-07-03 07:31:54 +00:00
|
|
|
|
by_cases
|
2015-07-21 16:10:56 +00:00
|
|
|
|
(suppose prime n, subtype.tag n (and.intro this (dvd.refl n)))
|
|
|
|
|
(suppose ¬ prime n,
|
|
|
|
|
obtain m m_dvd_n m_ge_2 m_lt_n, from sub_dvd_of_not_prime2 `n ≥ 2` this,
|
2015-07-03 07:31:54 +00:00
|
|
|
|
obtain p (hp : prime p) (p_dvd_m : p ∣ m), from ih m m_lt_n m_ge_2,
|
2015-07-21 16:10:56 +00:00
|
|
|
|
have p ∣ n, from dvd.trans p_dvd_m m_dvd_n,
|
|
|
|
|
subtype.tag p (and.intro hp this)))
|
2015-07-15 19:49:47 +00:00
|
|
|
|
|
2015-08-17 03:23:03 +00:00
|
|
|
|
lemma exists_prime_and_dvd {n : nat} : n ≥ 2 → ∃ p, prime p ∧ p ∣ n :=
|
2015-07-17 02:48:33 +00:00
|
|
|
|
assume h, ex_of_sub (sub_prime_and_dvd h)
|
2015-07-03 07:31:54 +00:00
|
|
|
|
|
|
|
|
|
open eq.ops
|
|
|
|
|
|
2015-07-17 02:48:33 +00:00
|
|
|
|
definition infinite_primes (n : nat) : {p | p ≥ n ∧ prime p} :=
|
2015-07-03 07:31:54 +00:00
|
|
|
|
let m := fact (n + 1) in
|
2015-07-18 18:36:05 +00:00
|
|
|
|
have m ≥ 1, from le_of_lt_succ (succ_lt_succ (fact_pos _)),
|
|
|
|
|
have m + 1 ≥ 2, from succ_le_succ this,
|
2015-07-22 20:54:47 +00:00
|
|
|
|
obtain p `prime p` `p ∣ m + 1`, from sub_prime_and_dvd this,
|
2015-07-21 04:43:47 +00:00
|
|
|
|
have p ≥ 2, from ge_two_of_prime `prime p`,
|
|
|
|
|
have p > 0, from lt_of_succ_lt (lt_of_succ_le `p ≥ 2`),
|
2015-07-18 18:36:05 +00:00
|
|
|
|
have p ≥ n, from by_contradiction
|
2015-07-19 19:15:12 +00:00
|
|
|
|
(suppose ¬ p ≥ n,
|
|
|
|
|
have p < n, from lt_of_not_ge this,
|
2015-07-18 18:36:05 +00:00
|
|
|
|
have p ≤ n + 1, from le_of_lt (lt.step this),
|
2015-07-21 04:43:47 +00:00
|
|
|
|
have p ∣ m, from dvd_fact `p > 0` this,
|
|
|
|
|
have p ∣ 1, from dvd_of_dvd_add_right (!add.comm ▸ `p ∣ m + 1`) this,
|
2015-07-18 18:36:05 +00:00
|
|
|
|
have p ≤ 1, from le_of_dvd zero_lt_one this,
|
2015-07-21 04:43:47 +00:00
|
|
|
|
absurd (le.trans `2 ≤ p` `p ≤ 1`) dec_trivial),
|
|
|
|
|
subtype.tag p (and.intro this `prime p`)
|
2015-07-15 19:49:47 +00:00
|
|
|
|
|
|
|
|
|
lemma ex_infinite_primes (n : nat) : ∃ p, p ≥ n ∧ prime p :=
|
2015-07-17 02:48:33 +00:00
|
|
|
|
ex_of_sub (infinite_primes n)
|
2015-07-03 07:31:54 +00:00
|
|
|
|
|
2015-07-04 06:31:04 +00:00
|
|
|
|
lemma odd_of_prime {p : nat} : prime p → p > 2 → odd p :=
|
2015-07-05 15:21:16 +00:00
|
|
|
|
λ pp p_gt_2, by_contradiction (λ hn,
|
2015-07-21 04:43:47 +00:00
|
|
|
|
have even p, from even_of_not_odd hn,
|
2015-07-22 20:54:47 +00:00
|
|
|
|
obtain k `p = 2*k`, from exists_of_even this,
|
|
|
|
|
assert 2 ∣ p, by rewrite [`p = 2*k`]; apply dvd_mul_right,
|
2015-07-21 04:43:47 +00:00
|
|
|
|
or.elim (eq_one_or_eq_self_of_prime_of_dvd pp this)
|
|
|
|
|
(suppose 2 = 1, absurd this dec_trivial)
|
|
|
|
|
(suppose 2 = p, by subst this; exact absurd p_gt_2 !lt.irrefl))
|
2015-07-04 06:31:04 +00:00
|
|
|
|
|
2015-07-08 01:55:31 +00:00
|
|
|
|
theorem dvd_of_prime_of_not_coprime {p n : ℕ} (primep : prime p) (nc : ¬ coprime p n) : p ∣ n :=
|
|
|
|
|
have H : gcd p n = 1 ∨ gcd p n = p, from eq_one_or_eq_self_of_prime_of_dvd primep !gcd_dvd_left,
|
|
|
|
|
or_resolve_right H nc ▸ !gcd_dvd_right
|
|
|
|
|
|
|
|
|
|
theorem coprime_of_prime_of_not_dvd {p n : ℕ} (primep : prime p) (npdvdn : ¬ p ∣ n) :
|
|
|
|
|
coprime p n :=
|
2015-07-19 19:15:12 +00:00
|
|
|
|
by_contradiction (suppose ¬ coprime p n, npdvdn (dvd_of_prime_of_not_coprime primep this))
|
2015-07-08 01:55:31 +00:00
|
|
|
|
|
|
|
|
|
theorem not_dvd_of_prime_of_coprime {p n : ℕ} (primep : prime p) (cop : coprime p n) : ¬ p ∣ n :=
|
2015-07-19 19:15:12 +00:00
|
|
|
|
suppose p ∣ n,
|
|
|
|
|
have p ∣ gcd p n, from dvd_gcd !dvd.refl this,
|
2015-07-18 18:36:05 +00:00
|
|
|
|
have p ≤ gcd p n, from le_of_dvd (!gcd_pos_of_pos_left (pos_of_prime primep)) this,
|
|
|
|
|
have 2 ≤ 1, from le.trans (ge_two_of_prime primep) (cop ▸ this),
|
|
|
|
|
show false, from !not_succ_le_self this
|
2015-07-08 01:55:31 +00:00
|
|
|
|
|
|
|
|
|
theorem not_coprime_of_prime_dvd {p n : ℕ} (primep : prime p) (pdvdn : p ∣ n) : ¬ coprime p n :=
|
|
|
|
|
assume cop, not_dvd_of_prime_of_coprime primep cop pdvdn
|
|
|
|
|
|
|
|
|
|
theorem dvd_of_prime_of_dvd_mul_left {p m n : ℕ} (primep : prime p)
|
|
|
|
|
(Hmn : p ∣ m * n) (Hm : ¬ p ∣ m) :
|
|
|
|
|
p ∣ n :=
|
2015-07-18 18:36:05 +00:00
|
|
|
|
have coprime p m, from coprime_of_prime_of_not_dvd primep Hm,
|
|
|
|
|
show p ∣ n, from dvd_of_coprime_of_dvd_mul_left this Hmn
|
2015-07-08 01:55:31 +00:00
|
|
|
|
|
|
|
|
|
theorem dvd_of_prime_of_dvd_mul_right {p m n : ℕ} (primep : prime p)
|
|
|
|
|
(Hmn : p ∣ m * n) (Hn : ¬ p ∣ n) :
|
|
|
|
|
p ∣ m :=
|
|
|
|
|
dvd_of_prime_of_dvd_mul_left primep (!mul.comm ▸ Hmn) Hn
|
|
|
|
|
|
|
|
|
|
theorem not_dvd_mul_of_prime {p m n : ℕ} (primep : prime p) (Hm : ¬ p ∣ m) (Hn : ¬ p ∣ n) :
|
|
|
|
|
¬ p ∣ m * n :=
|
|
|
|
|
assume Hmn, Hm (dvd_of_prime_of_dvd_mul_right primep Hmn Hn)
|
2015-07-04 06:31:04 +00:00
|
|
|
|
|
|
|
|
|
lemma dvd_or_dvd_of_prime_of_dvd_mul {p m n : nat} : prime p → p ∣ m * n → p ∣ m ∨ p ∣ n :=
|
2015-07-08 01:55:31 +00:00
|
|
|
|
λ h₁ h₂, by_cases
|
2015-07-19 19:15:12 +00:00
|
|
|
|
(suppose p ∣ m, or.inl this)
|
|
|
|
|
(suppose ¬ p ∣ m, or.inr (dvd_of_prime_of_dvd_mul_left h₁ h₂ this))
|
2015-07-04 06:31:04 +00:00
|
|
|
|
|
|
|
|
|
lemma dvd_of_prime_of_dvd_pow {p m : nat} : ∀ {n}, prime p → p ∣ m^n → p ∣ m
|
|
|
|
|
| 0 hp hd :=
|
2015-07-18 18:36:05 +00:00
|
|
|
|
assert p = 1, from eq_one_of_dvd_one hd,
|
|
|
|
|
have 1 ≥ 2, by rewrite -this; apply ge_two_of_prime hp,
|
|
|
|
|
absurd this dec_trivial
|
2015-07-04 06:31:04 +00:00
|
|
|
|
| (succ n) hp hd :=
|
2015-08-14 15:00:16 +00:00
|
|
|
|
have p ∣ (m^n)*m, by rewrite [pow_succ' at hd]; exact hd,
|
2015-07-18 18:36:05 +00:00
|
|
|
|
or.elim (dvd_or_dvd_of_prime_of_dvd_mul hp this)
|
2015-07-21 04:43:47 +00:00
|
|
|
|
(suppose p ∣ m^n, dvd_of_prime_of_dvd_pow hp this)
|
|
|
|
|
(suppose p ∣ m, this)
|
2015-07-04 06:31:04 +00:00
|
|
|
|
|
2015-07-04 07:37:09 +00:00
|
|
|
|
lemma coprime_pow_of_prime_of_not_dvd {p m a : nat} : prime p → ¬ p ∣ a → coprime a (p^m) :=
|
|
|
|
|
λ h₁ h₂, coprime_pow_right m (coprime_swap (coprime_of_prime_of_not_dvd h₁ h₂))
|
|
|
|
|
|
|
|
|
|
lemma coprime_primes {p q : nat} : prime p → prime q → p ≠ q → coprime p q :=
|
|
|
|
|
λ hp hq hn,
|
2015-07-18 18:36:05 +00:00
|
|
|
|
assert gcd p q ∣ p, from !gcd_dvd_left,
|
|
|
|
|
or.elim (eq_one_or_eq_self_of_prime_of_dvd hp this)
|
2015-07-21 04:43:47 +00:00
|
|
|
|
(suppose gcd p q = 1, this)
|
|
|
|
|
(assume h : gcd p q = p,
|
2015-07-18 18:36:05 +00:00
|
|
|
|
assert gcd p q ∣ q, from !gcd_dvd_right,
|
|
|
|
|
have p ∣ q, by rewrite -h; exact this,
|
|
|
|
|
or.elim (eq_one_or_eq_self_of_prime_of_dvd hq this)
|
2015-07-21 04:43:47 +00:00
|
|
|
|
(suppose p = 1, by subst p; exact absurd hp not_prime_one)
|
|
|
|
|
(suppose p = q, by contradiction))
|
2015-07-04 07:37:09 +00:00
|
|
|
|
|
|
|
|
|
lemma coprime_pow_primes {p q : nat} (n m : nat) : prime p → prime q → p ≠ q → coprime (p^n) (q^m) :=
|
|
|
|
|
λ hp hq hn, coprime_pow_right m (coprime_pow_left n (coprime_primes hp hq hn))
|
|
|
|
|
|
2015-07-04 20:27:10 +00:00
|
|
|
|
lemma coprime_or_dvd_of_prime {p} (Pp : prime p) (i : nat) : coprime p i ∨ p ∣ i :=
|
|
|
|
|
by_cases
|
2015-07-21 04:43:47 +00:00
|
|
|
|
(suppose p ∣ i, or.inr this)
|
|
|
|
|
(suppose ¬ p ∣ i, or.inl (coprime_of_prime_of_not_dvd Pp this))
|
2015-07-04 20:27:10 +00:00
|
|
|
|
|
2015-07-08 01:55:31 +00:00
|
|
|
|
lemma eq_one_or_dvd_of_dvd_prime_pow {p : nat} : ∀ {m i : nat}, prime p → i ∣ (p^m) → i = 1 ∨ p ∣ i
|
2015-07-04 20:27:10 +00:00
|
|
|
|
| 0 := take i, assume Pp, begin rewrite [pow_zero], intro Pdvd, apply or.inl (eq_one_of_dvd_one Pdvd) end
|
|
|
|
|
| (succ m) := take i, assume Pp, or.elim (coprime_or_dvd_of_prime Pp i)
|
|
|
|
|
(λ Pcp, begin
|
2015-08-14 15:00:16 +00:00
|
|
|
|
rewrite [pow_succ'], intro Pdvd,
|
2015-07-08 01:55:31 +00:00
|
|
|
|
apply eq_one_or_dvd_of_dvd_prime_pow Pp,
|
2015-07-04 20:27:10 +00:00
|
|
|
|
apply dvd_of_coprime_of_dvd_mul_right,
|
|
|
|
|
apply coprime_swap Pcp, exact Pdvd
|
|
|
|
|
end)
|
|
|
|
|
(λ Pdvd, assume P, or.inr Pdvd)
|
2015-07-03 05:27:51 +00:00
|
|
|
|
end nat
|