l3lab/ntp-mathlib huggingface dataset:
/-- The set of positive powers of prime `p` that divide `n` is exactly the set of
positive natural numbers up to `n.factorization p`. -/
theorem Icc_factorization_eq_pow_dvd (n : ℕ) {p : ℕ} (pp : Prime p) :
    Icc 1 (n.factorization p) = (Ico 1 n).filter fun i : ℕ => p ^ i ∣ n := by
  rcases eq_or_ne n 0 with (rfl | hn)
  · simp
  ext x
  simp only [mem_Icc, Finset.mem_filter, mem_Ico, and_assoc, and_congr_right_iff,
    pp.pow_dvd_iff_le_factorization hn, iff_and_self]
  

Proof state:
case inr.a
a b m n✝ p✝ n p : ℕ
pp : Prime p
hn : n ≠ 0
x : ℕ
⊢ 1 ≤ x → x ≤ (factorization n) p → x < n

Next tactic:
exact fun _ H => lt_of_le_of_lt H (factorization_lt p hn)
theorem factorization_eq_card_pow_dvd (n : ℕ) {p : ℕ} (pp : p.Prime) :
    n.factorization p = ((Ico 1 n).filter fun i => p ^ i ∣ n).card := by
  

Proof state:
a b m n✝ p✝ n p : ℕ
pp : Prime p
⊢ (factorization n) p = card (Finset.filter (fun i => p ^ i ∣ n) (Ico 1 n))

Next tactic:
simp [← Icc_factorization_eq_pow_dvd n pp]
theorem Ico_filter_pow_dvd_eq {n p b : ℕ} (pp : p.Prime) (hn : n ≠ 0) (hb : n ≤ p ^ b) :
    ((Ico 1 n).filter fun i => p ^ i ∣ n) = (Icc 1 b).filter fun i => p ^ i ∣ n := by
  

Proof state:
a b✝ m n✝ p✝ n p b : ℕ
pp : Prime p
hn : n ≠ 0
hb : n ≤ p ^ b
⊢ Finset.filter (fun i => p ^ i ∣ n) (Ico 1 n) = Finset.filter (fun i => p ^ i ∣ n) (Icc 1 b)

Next tactic:
ext x
theorem Ico_filter_pow_dvd_eq {n p b : ℕ} (pp : p.Prime) (hn : n ≠ 0) (hb : n ≤ p ^ b) :
    ((Ico 1 n).filter fun i => p ^ i ∣ n) = (Icc 1 b).filter fun i => p ^ i ∣ n := by
  ext x
  

Proof state:
case a
a b✝ m n✝ p✝ n p b : ℕ
pp : Prime p
hn : n ≠ 0
hb : n ≤ p ^ b
x : ℕ
⊢ x ∈ Finset.filter (fun i => p ^ i ∣ n) (Ico 1 n) ↔ x ∈ Finset.filter (fun i => p ^ i ∣ n) (Icc 1 b)

Next tactic:
simp only [Finset.mem_filter, mem_Ico, mem_Icc, and_congr_left_iff, and_congr_right_iff]
theorem Ico_filter_pow_dvd_eq {n p b : ℕ} (pp : p.Prime) (hn : n ≠ 0) (hb : n ≤ p ^ b) :
    ((Ico 1 n).filter fun i => p ^ i ∣ n) = (Icc 1 b).filter fun i => p ^ i ∣ n := by
  ext x
  simp only [Finset.mem_filter, mem_Ico, mem_Icc, and_congr_left_iff, and_congr_right_iff]
  

Proof state:
case a
a b✝ m n✝ p✝ n p b : ℕ
pp : Prime p
hn : n ≠ 0
hb : n ≤ p ^ b
x : ℕ
⊢ p ^ x ∣ n → 1 ≤ x → (x < n ↔ x ≤ b)

Next tactic:
rintro h1 -
theorem Ico_filter_pow_dvd_eq {n p b : ℕ} (pp : p.Prime) (hn : n ≠ 0) (hb : n ≤ p ^ b) :
    ((Ico 1 n).filter fun i => p ^ i ∣ n) = (Icc 1 b).filter fun i => p ^ i ∣ n := by
  ext x
  simp only [Finset.mem_filter, mem_Ico, mem_Icc, and_congr_left_iff, and_congr_right_iff]
  rintro h1 -
  

Proof state:
case a
a b✝ m n✝ p✝ n p b : ℕ
pp : Prime p
hn : n ≠ 0
hb : n ≤ p ^ b
x : ℕ
h1 : p ^ x ∣ n
⊢ x < n ↔ x ≤ b

Next tactic:
exact iff_of_true (lt_of_pow_dvd_right hn pp.two_le h1) $
    (pow_le_pow_iff_right pp.one_lt).1 $ (le_of_dvd hn.bot_lt h1).trans hb
/-- For coprime `a` and `b`, the power of `p` in `a * b` is the sum of the powers in `a` and `b` -/
theorem factorization_mul_apply_of_coprime {p a b : ℕ} (hab : Coprime a b) :
    (a * b).factorization p = a.factorization p + b.factorization p := by
  

Proof state:
a✝ b✝ m n p✝ p a b : ℕ
hab : Coprime a b
⊢ (factorization (a * b)) p = (factorization a) p + (factorization b) p

Next tactic:
simp only [← factors_count_eq, perm_iff_count.mp (perm_factors_mul_of_coprime hab), count_append]
/-- For coprime `a` and `b`, the power of `p` in `a * b` is the sum of the powers in `a` and `b` -/
theorem factorization_mul_of_coprime {a b : ℕ} (hab : Coprime a b) :
    (a * b).factorization = a.factorization + b.factorization := by
  

Proof state:
a✝ b✝ m n p a b : ℕ
hab : Coprime a b
⊢ factorization (a * b) = factorization a + factorization b

Next tactic:
ext q
/-- For coprime `a` and `b`, the power of `p` in `a * b` is the sum of the powers in `a` and `b` -/
theorem factorization_mul_of_coprime {a b : ℕ} (hab : Coprime a b) :
    (a * b).factorization = a.factorization + b.factorization := by
  ext q
  

Proof state:
case h
a✝ b✝ m n p a b : ℕ
hab : Coprime a b
q : ℕ
⊢ (factorization (a * b)) q = (factorization a + factorization b) q

Next tactic:
rw [Finsupp.add_apply, factorization_mul_apply_of_coprime hab]
/-- If `p` is a prime factor of `a` then the power of `p` in `a` is the same that in `a * b`,
for any `b` coprime to `a`. -/
theorem factorization_eq_of_coprime_left {p a b : ℕ} (hab : Coprime a b) (hpa : p ∈ a.factors) :
    (a * b).factorization p = a.factorization p := by
  

Proof state:
a✝ b✝ m n p✝ p a b : ℕ
hab : Coprime a b
hpa : p ∈ factors a
⊢ (factorization (a * b)) p = (factorization a) p

Next tactic:
rw [factorization_mul_apply_of_coprime hab, ← factors_count_eq, ← factors_count_eq,
    count_eq_zero_of_not_mem (coprime_factors_disjoint hab hpa), add_zero]
/-- If `p` is a prime factor of `b` then the power of `p` in `b` is the same that in `a * b`,
for any `a` coprime to `b`. -/
theorem factorization_eq_of_coprime_right {p a b : ℕ} (hab : Coprime a b) (hpb : p ∈ b.factors) :
    (a * b).factorization p = b.factorization p := by
  

Proof state:
a✝ b✝ m n p✝ p a b : ℕ
hab : Coprime a b
hpb : p ∈ factors b
⊢ (factorization (a * b)) p = (factorization b) p

Next tactic:
rw [mul_comm]
/-- If `p` is a prime factor of `b` then the power of `p` in `b` is the same that in `a * b`,
for any `a` coprime to `b`. -/
theorem factorization_eq_of_coprime_right {p a b : ℕ} (hab : Coprime a b) (hpb : p ∈ b.factors) :
    (a * b).factorization p = b.factorization p := by
  rw [mul_comm]
  

Proof state:
a✝ b✝ m n p✝ p a b : ℕ
hab : Coprime a b
hpb : p ∈ factors b
⊢ (factorization (b * a)) p = (factorization b) p

Next tactic:
exact factorization_eq_of_coprime_left (coprime_comm.mp hab) hpb
/-- Given `P 0, P 1` and a way to extend `P a` to `P (p ^ n * a)` for prime `p` not dividing `a`,
we can define `P` for all natural numbers. -/
@[elab_as_elim]
def recOnPrimePow {P : ℕ → Sort*} (h0 : P 0) (h1 : P 1)
    (h : ∀ a p n : ℕ, p.Prime → ¬p ∣ a → 0 < n → P a → P (p ^ n * a)) : ∀ a : ℕ, P a := fun a =>
  Nat.strongRecOn a fun n =>
    match n with
    | 0 => fun _ => h0
    | 1 => fun _ => h1
    | k + 2 => fun hk => by
      

Proof state:
a✝ b m n✝ p : ℕ
P : ℕ → Sort u_1
h0 : P 0
h1 : P 1
h : (a p n : ℕ) → Prime p → ¬p ∣ a → 0 < n → P a → P (p ^ n * a)
a n k : ℕ
hk : (m : ℕ) → m < k + 2 → P m
⊢ P (k + 2)

Next tactic:
letI p := (k + 2).minFac
/-- Given `P 0, P 1` and a way to extend `P a` to `P (p ^ n * a)` for prime `p` not dividing `a`,
we can define `P` for all natural numbers. -/
@[elab_as_elim]
def recOnPrimePow {P : ℕ → Sort*} (h0 : P 0) (h1 : P 1)
    (h : ∀ a p n : ℕ, p.Prime → ¬p ∣ a → 0 < n → P a → P (p ^ n * a)) : ∀ a : ℕ, P a := fun a =>
  Nat.strongRecOn a fun n =>
    match n with
    | 0 => fun _ => h0
    | 1 => fun _ => h1
    | k + 2 => fun hk => by
      letI p := (k + 2).minFac
      

Proof state:
a✝ b m n✝ p✝ : ℕ
P : ℕ → Sort u_1
h0 : P 0
h1 : P 1
h : (a p n : ℕ) → Prime p → ¬p ∣ a → 0 < n → P a → P (p ^ n * a)
a n k : ℕ
hk : (m : ℕ) → m < k + 2 → P m
p : ℕ := minFac (k + 2)
⊢ P (k + 2)

Next tactic:
haveI hp : Prime p := minFac_prime (succ_succ_ne_one k)
/-- Given `P 0, P 1` and a way to extend `P a` to `P (p ^ n * a)` for prime `p` not dividing `a`,
we can define `P` for all natural numbers. -/
@[elab_as_elim]
def recOnPrimePow {P : ℕ → Sort*} (h0 : P 0) (h1 : P 1)
    (h : ∀ a p n : ℕ, p.Prime → ¬p ∣ a → 0 < n → P a → P (p ^ n * a)) : ∀ a : ℕ, P a := fun a =>
  Nat.strongRecOn a fun n =>
    match n with
    | 0 => fun _ => h0
    | 1 => fun _ => h1
    | k + 2 => fun hk => by
      letI p := (k + 2).minFac
      haveI hp : Prime p := minFac_prime (succ_succ_ne_one k)
      

Proof state:
a✝ b m n✝ p✝ : ℕ
P : ℕ → Sort u_1
h0 : P 0
h1 : P 1
h : (a p n : ℕ) → Prime p → ¬p ∣ a → 0 < n → P a → P (p ^ n * a)
a n k : ℕ
hk : (m : ℕ) → m < k + 2 → P m
p : ℕ := minFac (k + 2)
hp : Prime p
⊢ P (k + 2)

Next tactic:
letI t := (k + 2).factorization p
/-- Given `P 0, P 1` and a way to extend `P a` to `P (p ^ n * a)` for prime `p` not dividing `a`,
we can define `P` for all natural numbers. -/
@[elab_as_elim]
def recOnPrimePow {P : ℕ → Sort*} (h0 : P 0) (h1 : P 1)
    (h : ∀ a p n : ℕ, p.Prime → ¬p ∣ a → 0 < n → P a → P (p ^ n * a)) : ∀ a : ℕ, P a := fun a =>
  Nat.strongRecOn a fun n =>
    match n with
    | 0 => fun _ => h0
    | 1 => fun _ => h1
    | k + 2 => fun hk => by
      letI p := (k + 2).minFac
      haveI hp : Prime p := minFac_prime (succ_succ_ne_one k)
      letI t := (k + 2).factorization p
      

Proof state:
a✝ b m n✝ p✝ : ℕ
P : ℕ → Sort u_1
h0 : P 0
h1 : P 1
h : (a p n : ℕ) → Prime p → ¬p ∣ a → 0 < n → P a → P (p ^ n * a)
a n k : ℕ
hk : (m : ℕ) → m < k + 2 → P m
p : ℕ := minFac (k + 2)
hp : Prime p
t : ℕ := (factorization (k + 2)) p
⊢ P (k + 2)

Next tactic:
haveI hpt : p ^ t ∣ k + 2 := ord_proj_dvd _ _
/-- Given `P 0, P 1` and a way to extend `P a` to `P (p ^ n * a)` for prime `p` not dividing `a`,
we can define `P` for all natural numbers. -/
@[elab_as_elim]
def recOnPrimePow {P : ℕ → Sort*} (h0 : P 0) (h1 : P 1)
    (h : ∀ a p n : ℕ, p.Prime → ¬p ∣ a → 0 < n → P a → P (p ^ n * a)) : ∀ a : ℕ, P a := fun a =>
  Nat.strongRecOn a fun n =>
    match n with
    | 0 => fun _ => h0
    | 1 => fun _ => h1
    | k + 2 => fun hk => by
      letI p := (k + 2).minFac
      haveI hp : Prime p := minFac_prime (succ_succ_ne_one k)
      letI t := (k + 2).factorization p
      haveI hpt : p ^ t ∣ k + 2 := ord_proj_dvd _ _
      

Proof state:
a✝ b m n✝ p✝ : ℕ
P : ℕ → Sort u_1
h0 : P 0
h1 : P 1
h : (a p n : ℕ) → Prime p → ¬p ∣ a → 0 < n → P a → P (p ^ n * a)
a n k : ℕ
hk : (m : ℕ) → m < k + 2 → P m
p : ℕ := minFac (k + 2)
hp : Prime p
t : ℕ := (factorization (k + 2)) p
hpt : p ^ t ∣ k + 2
⊢ P (k + 2)

Next tactic:
haveI htp : 0 < t := hp.factorization_pos_of_dvd (k + 1).succ_ne_zero (k + 2).minFac_dvd
/-- Given `P 0, P 1` and a way to extend `P a` to `P (p ^ n * a)` for prime `p` not dividing `a`,
we can define `P` for all natural numbers. -/
@[elab_as_elim]
def recOnPrimePow {P : ℕ → Sort*} (h0 : P 0) (h1 : P 1)
    (h : ∀ a p n : ℕ, p.Prime → ¬p ∣ a → 0 < n → P a → P (p ^ n * a)) : ∀ a : ℕ, P a := fun a =>
  Nat.strongRecOn a fun n =>
    match n with
    | 0 => fun _ => h0
    | 1 => fun _ => h1
    | k + 2 => fun hk => by
      letI p := (k + 2).minFac
      haveI hp : Prime p := minFac_prime (succ_succ_ne_one k)
      letI t := (k + 2).factorization p
      haveI hpt : p ^ t ∣ k + 2 := ord_proj_dvd _ _
      haveI htp : 0 < t := hp.factorization_pos_of_dvd (k + 1).succ_ne_zero (k + 2).minFac_dvd
      

Proof state:
a✝ b m n✝ p✝ : ℕ
P : ℕ → Sort u_1
h0 : P 0
h1 : P 1
h : (a p n : ℕ) → Prime p → ¬p ∣ a → 0 < n → P a → P (p ^ n * a)
a n k : ℕ
hk : (m : ℕ) → m < k + 2 → P m
p : ℕ := minFac (k + 2)
hp : Prime p
t : ℕ := (factorization (k + 2)) p
hpt : p ^ t ∣ k + 2
htp : 0 < t
⊢ P (k + 2)

Next tactic:
convert h ((k + 2) / p ^ t) p t hp _ htp (hk _ (Nat.div_lt_of_lt_mul _)) using 1
/-- Given `P 0, P 1` and a way to extend `P a` to `P (p ^ n * a)` for prime `p` not dividing `a`,
we can define `P` for all natural numbers. -/
@[elab_as_elim]
def recOnPrimePow {P : ℕ → Sort*} (h0 : P 0) (h1 : P 1)
    (h : ∀ a p n : ℕ, p.Prime → ¬p ∣ a → 0 < n → P a → P (p ^ n * a)) : ∀ a : ℕ, P a := fun a =>
  Nat.strongRecOn a fun n =>
    match n with
    | 0 => fun _ => h0
    | 1 => fun _ => h1
    | k + 2 => fun hk => by
      letI p := (k + 2).minFac
      haveI hp : Prime p := minFac_prime (succ_succ_ne_one k)
      letI t := (k + 2).factorization p
      haveI hpt : p ^ t ∣ k + 2 := ord_proj_dvd _ _
      haveI htp : 0 < t := hp.factorization_pos_of_dvd (k + 1).succ_ne_zero (k + 2).minFac_dvd
      convert h ((k + 2) / p ^ t) p t hp _ htp (hk _ (Nat.div_lt_of_lt_mul _)) using 1
      · 

Proof state:
case h.e'_1
a✝ b m n✝ p✝ : ℕ
P : ℕ → Sort u_1
h0 : P 0
h1 : P 1
h : (a p n : ℕ) → Prime p → ¬p ∣ a → 0 < n → P a → P (p ^ n * a)
a n k : ℕ
hk : (m : ℕ) → m < k + 2 → P m
p : ℕ := minFac (k + 2)
hp : Prime p
t : ℕ := (factorization (k + 2)) p
hpt : p ^ t ∣ k + 2
htp : 0 < t
⊢ k + 2 = p ^ t * ((k + 2) / p ^ t)

Next tactic:
rw [Nat.mul_div_cancel' hpt]
/-- Given `P 0, P 1` and a way to extend `P a` to `P (p ^ n * a)` for prime `p` not dividing `a`,
we can define `P` for all natural numbers. -/
@[elab_as_elim]
def recOnPrimePow {P : ℕ → Sort*} (h0 : P 0) (h1 : P 1)
    (h : ∀ a p n : ℕ, p.Prime → ¬p ∣ a → 0 < n → P a → P (p ^ n * a)) : ∀ a : ℕ, P a := fun a =>
  Nat.strongRecOn a fun n =>
    match n with
    | 0 => fun _ => h0
    | 1 => fun _ => h1
    | k + 2 => fun hk => by
      letI p := (k + 2).minFac
      haveI hp : Prime p := minFac_prime (succ_succ_ne_one k)
      letI t := (k + 2).factorization p
      haveI hpt : p ^ t ∣ k + 2 := ord_proj_dvd _ _
      haveI htp : 0 < t := hp.factorization_pos_of_dvd (k + 1).succ_ne_zero (k + 2).minFac_dvd
      convert h ((k + 2) / p ^ t) p t hp _ htp (hk _ (Nat.div_lt_of_lt_mul _)) using 1
      · rw [Nat.mul_div_cancel' hpt]
      · 

Proof state:
case convert_1
a✝ b m n✝ p✝ : ℕ
P : ℕ → Sort u_1
h0 : P 0
h1 : P 1
h : (a p n : ℕ) → Prime p → ¬p ∣ a → 0 < n → P a → P (p ^ n * a)
a n k : ℕ
hk : (m : ℕ) → m < k + 2 → P m
p : ℕ := minFac (k + 2)
hp : Prime p
t : ℕ := (factorization (k + 2)) p
hpt : p ^ t ∣ k + 2
htp : 0 < t
⊢ ¬p ∣ (k + 2) / p ^ t

Next tactic:
rw [Nat.dvd_div_iff hpt, ← pow_succ]
/-- Given `P 0, P 1` and a way to extend `P a` to `P (p ^ n * a)` for prime `p` not dividing `a`,
we can define `P` for all natural numbers. -/
@[elab_as_elim]
def recOnPrimePow {P : ℕ → Sort*} (h0 : P 0) (h1 : P 1)
    (h : ∀ a p n : ℕ, p.Prime → ¬p ∣ a → 0 < n → P a → P (p ^ n * a)) : ∀ a : ℕ, P a := fun a =>
  Nat.strongRecOn a fun n =>
    match n with
    | 0 => fun _ => h0
    | 1 => fun _ => h1
    | k + 2 => fun hk => by
      letI p := (k + 2).minFac
      haveI hp : Prime p := minFac_prime (succ_succ_ne_one k)
      letI t := (k + 2).factorization p
      haveI hpt : p ^ t ∣ k + 2 := ord_proj_dvd _ _
      haveI htp : 0 < t := hp.factorization_pos_of_dvd (k + 1).succ_ne_zero (k + 2).minFac_dvd
      convert h ((k + 2) / p ^ t) p t hp _ htp (hk _ (Nat.div_lt_of_lt_mul _)) using 1
      · rw [Nat.mul_div_cancel' hpt]
      · rw [Nat.dvd_div_iff hpt, ← pow_succ]
        

Proof state:
case convert_1
a✝ b m n✝ p✝ : ℕ
P : ℕ → Sort u_1
h0 : P 0
h1 : P 1
h : (a p n : ℕ) → Prime p → ¬p ∣ a → 0 < n → P a → P (p ^ n * a)
a n k : ℕ
hk : (m : ℕ) → m < k + 2 → P m
p : ℕ := minFac (k + 2)
hp : Prime p
t : ℕ := (factorization (k + 2)) p
hpt : p ^ t ∣ k + 2
htp : 0 < t
⊢ ¬p ^ succ t ∣ k + 2

Next tactic:
exact pow_succ_factorization_not_dvd (k + 1).succ_ne_zero hp
/-- Given `P 0, P 1` and a way to extend `P a` to `P (p ^ n * a)` for prime `p` not dividing `a`,
we can define `P` for all natural numbers. -/
@[elab_as_elim]
def recOnPrimePow {P : ℕ → Sort*} (h0 : P 0) (h1 : P 1)
    (h : ∀ a p n : ℕ, p.Prime → ¬p ∣ a → 0 < n → P a → P (p ^ n * a)) : ∀ a : ℕ, P a := fun a =>
  Nat.strongRecOn a fun n =>
    match n with
    | 0 => fun _ => h0
    | 1 => fun _ => h1
    | k + 2 => fun hk => by
      letI p := (k + 2).minFac
      haveI hp : Prime p := minFac_prime (succ_succ_ne_one k)
      letI t := (k + 2).factorization p
      haveI hpt : p ^ t ∣ k + 2 := ord_proj_dvd _ _
      haveI htp : 0 < t := hp.factorization_pos_of_dvd (k + 1).succ_ne_zero (k + 2).minFac_dvd
      convert h ((k + 2) / p ^ t) p t hp _ htp (hk _ (Nat.div_lt_of_lt_mul _)) using 1
      · rw [Nat.mul_div_cancel' hpt]
      · rw [Nat.dvd_div_iff hpt, ← pow_succ]
        exact pow_succ_factorization_not_dvd (k + 1).succ_ne_zero hp
      · 

Proof state:
case convert_2
a✝ b m n✝ p✝ : ℕ
P : ℕ → Sort u_1
h0 : P 0
h1 : P 1
h : (a p n : ℕ) → Prime p → ¬p ∣ a → 0 < n → P a → P (p ^ n * a)
a n k : ℕ
hk : (m : ℕ) → m < k + 2 → P m
p : ℕ := minFac (k + 2)
hp : Prime p
t : ℕ := (factorization (k + 2)) p
hpt : p ^ t ∣ k + 2
htp : 0 < t
⊢ k + 2 < p ^ t * (k + 2)

Next tactic:
simp [lt_mul_iff_one_lt_left Nat.succ_pos', one_lt_pow_iff htp.ne', hp.one_lt]
/-- Given `P 0`, `P 1`, and `P (p ^ n)` for positive prime powers, and a way to extend `P a` and
`P b` to `P (a * b)` when `a, b` are positive coprime, we can define `P` for all natural numbers. -/
@[elab_as_elim]
def recOnPosPrimePosCoprime {P : ℕ → Sort*} (hp : ∀ p n : ℕ, Prime p → 0 < n → P (p ^ n))
    (h0 : P 0) (h1 : P 1) (h : ∀ a b, 1 < a → 1 < b → Coprime a b → P a → P b → P (a * b)) :
    ∀ a, P a :=
  recOnPrimePow h0 h1 <| by
    

Proof state:
a b m n p : ℕ
P : ℕ → Sort u_1
hp : (p n : ℕ) → Prime p → 0 < n → P (p ^ n)
h0 : P 0
h1 : P 1
h : (a b : ℕ) → 1 < a → 1 < b → Coprime a b → P a → P b → P (a * b)
⊢ (a p n : ℕ) → Prime p → ¬p ∣ a → 0 < n → P a → P (p ^ n * a)

Next tactic:
intro a p n hp' hpa hn hPa
/-- Given `P 0`, `P 1`, and `P (p ^ n)` for positive prime powers, and a way to extend `P a` and
`P b` to `P (a * b)` when `a, b` are positive coprime, we can define `P` for all natural numbers. -/
@[elab_as_elim]
def recOnPosPrimePosCoprime {P : ℕ → Sort*} (hp : ∀ p n : ℕ, Prime p → 0 < n → P (p ^ n))
    (h0 : P 0) (h1 : P 1) (h : ∀ a b, 1 < a → 1 < b → Coprime a b → P a → P b → P (a * b)) :
    ∀ a, P a :=
  recOnPrimePow h0 h1 <| by
    intro a p n hp' hpa hn hPa
    

Proof state:
a✝ b m n✝ p✝ : ℕ
P : ℕ → Sort u_1
hp : (p n : ℕ) → Prime p → 0 < n → P (p ^ n)
h0 : P 0
h1 : P 1
h : (a b : ℕ) → 1 < a → 1 < b → Coprime a b → P a → P b → P (a * b)
a p n : ℕ
hp' : Prime p
hpa : ¬p ∣ a
hn : 0 < n
hPa : P a
⊢ P (p ^ n * a)

Next tactic:
by_cases ha1 : a = 1
/-- Given `P 0`, `P 1`, and `P (p ^ n)` for positive prime powers, and a way to extend `P a` and
`P b` to `P (a * b)` when `a, b` are positive coprime, we can define `P` for all natural numbers. -/
@[elab_as_elim]
def recOnPosPrimePosCoprime {P : ℕ → Sort*} (hp : ∀ p n : ℕ, Prime p → 0 < n → P (p ^ n))
    (h0 : P 0) (h1 : P 1) (h : ∀ a b, 1 < a → 1 < b → Coprime a b → P a → P b → P (a * b)) :
    ∀ a, P a :=
  recOnPrimePow h0 h1 <| by
    intro a p n hp' hpa hn hPa
    by_cases ha1 : a = 1
    · 

Proof state:
case pos
a✝ b m n✝ p✝ : ℕ
P : ℕ → Sort u_1
hp : (p n : ℕ) → Prime p → 0 < n → P (p ^ n)
h0 : P 0
h1 : P 1
h : (a b : ℕ) → 1 < a → 1 < b → Coprime a b → P a → P b → P (a * b)
a p n : ℕ
hp' : Prime p
hpa : ¬p ∣ a
hn : 0 < n
hPa : P a
ha1 : a = 1
⊢ P (p ^ n * a)

Next tactic:
rw [ha1, mul_one]
/-- Given `P 0`, `P 1`, and `P (p ^ n)` for positive prime powers, and a way to extend `P a` and
`P b` to `P (a * b)` when `a, b` are positive coprime, we can define `P` for all natural numbers. -/
@[elab_as_elim]
def recOnPosPrimePosCoprime {P : ℕ → Sort*} (hp : ∀ p n : ℕ, Prime p → 0 < n → P (p ^ n))
    (h0 : P 0) (h1 : P 1) (h : ∀ a b, 1 < a → 1 < b → Coprime a b → P a → P b → P (a * b)) :
    ∀ a, P a :=
  recOnPrimePow h0 h1 <| by
    intro a p n hp' hpa hn hPa
    by_cases ha1 : a = 1
    · rw [ha1, mul_one]
      

Proof state:
case pos
a✝ b m n✝ p✝ : ℕ
P : ℕ → Sort u_1
hp : (p n : ℕ) → Prime p → 0 < n → P (p ^ n)
h0 : P 0
h1 : P 1
h : (a b : ℕ) → 1 < a → 1 < b → Coprime a b → P a → P b → P (a * b)
a p n : ℕ
hp' : Prime p
hpa : ¬p ∣ a
hn : 0 < n
hPa : P a
ha1 : a = 1
⊢ P (p ^ n)

Next tactic:
exact hp p n hp' hn
/-- Given `P 0`, `P 1`, and `P (p ^ n)` for positive prime powers, and a way to extend `P a` and
`P b` to `P (a * b)` when `a, b` are positive coprime, we can define `P` for all natural numbers. -/
@[elab_as_elim]
def recOnPosPrimePosCoprime {P : ℕ → Sort*} (hp : ∀ p n : ℕ, Prime p → 0 < n → P (p ^ n))
    (h0 : P 0) (h1 : P 1) (h : ∀ a b, 1 < a → 1 < b → Coprime a b → P a → P b → P (a * b)) :
    ∀ a, P a :=
  recOnPrimePow h0 h1 <| by
    intro a p n hp' hpa hn hPa
    by_cases ha1 : a = 1
    · rw [ha1, mul_one]
      exact hp p n hp' hn
    

Proof state:
case neg
a✝ b m n✝ p✝ : ℕ
P : ℕ → Sort u_1
hp : (p n : ℕ) → Prime p → 0 < n → P (p ^ n)
h0 : P 0
h1 : P 1
h : (a b : ℕ) → 1 < a → 1 < b → Coprime a b → P a → P b → P (a * b)
a p n : ℕ
hp' : Prime p
hpa : ¬p ∣ a
hn : 0 < n
hPa : P a
ha1 : ¬a = 1
⊢ P (p ^ n * a)

Next tactic:
refine' h (p ^ n) a (hp'.one_lt.trans_le (le_self_pow hn.ne' _)) _ _ (hp _ _ hp' hn) hPa
/-- Given `P 0`, `P 1`, and `P (p ^ n)` for positive prime powers, and a way to extend `P a` and
`P b` to `P (a * b)` when `a, b` are positive coprime, we can define `P` for all natural numbers. -/
@[elab_as_elim]
def recOnPosPrimePosCoprime {P : ℕ → Sort*} (hp : ∀ p n : ℕ, Prime p → 0 < n → P (p ^ n))
    (h0 : P 0) (h1 : P 1) (h : ∀ a b, 1 < a → 1 < b → Coprime a b → P a → P b → P (a * b)) :
    ∀ a, P a :=
  recOnPrimePow h0 h1 <| by
    intro a p n hp' hpa hn hPa
    by_cases ha1 : a = 1
    · rw [ha1, mul_one]
      exact hp p n hp' hn
    refine' h (p ^ n) a (hp'.one_lt.trans_le (le_self_pow hn.ne' _)) _ _ (hp _ _ hp' hn) hPa
    · 

Proof state:
case neg.refine'_1
a✝ b m n✝ p✝ : ℕ
P : ℕ → Sort u_1
hp : (p n : ℕ) → Prime p → 0 < n → P (p ^ n)
h0 : P 0
h1 : P 1
h : (a b : ℕ) → 1 < a → 1 < b → Coprime a b → P a → P b → P (a * b)
a p n : ℕ
hp' : Prime p
hpa : ¬p ∣ a
hn : 0 < n
hPa : P a
ha1 : ¬a = 1
⊢ 1 < a

Next tactic:
contrapose! hpa
/-- Given `P 0`, `P 1`, and `P (p ^ n)` for positive prime powers, and a way to extend `P a` and
`P b` to `P (a * b)` when `a, b` are positive coprime, we can define `P` for all natural numbers. -/
@[elab_as_elim]
def recOnPosPrimePosCoprime {P : ℕ → Sort*} (hp : ∀ p n : ℕ, Prime p → 0 < n → P (p ^ n))
    (h0 : P 0) (h1 : P 1) (h : ∀ a b, 1 < a → 1 < b → Coprime a b → P a → P b → P (a * b)) :
    ∀ a, P a :=
  recOnPrimePow h0 h1 <| by
    intro a p n hp' hpa hn hPa
    by_cases ha1 : a = 1
    · rw [ha1, mul_one]
      exact hp p n hp' hn
    refine' h (p ^ n) a (hp'.one_lt.trans_le (le_self_pow hn.ne' _)) _ _ (hp _ _ hp' hn) hPa
    · contrapose! hpa
      

Proof state:
case neg.refine'_1
a✝ b m n✝ p✝ : ℕ
P : ℕ → Sort u_1
hp : (p n : ℕ) → Prime p → 0 < n → P (p ^ n)
h0 : P 0
h1 : P 1
h : (a b : ℕ) → 1 < a → 1 < b → Coprime a b → P a → P b → P (a * b)
a p n : ℕ
hp' : Prime p
hn : 0 < n
hPa : P a
ha1 : ¬a = 1
hpa : a ≤ 1
⊢ p ∣ a

Next tactic:
simp [lt_one_iff.1 (lt_of_le_of_ne hpa ha1)]
/-- Given `P 0`, `P 1`, and `P (p ^ n)` for positive prime powers, and a way to extend `P a` and
`P b` to `P (a * b)` when `a, b` are positive coprime, we can define `P` for all natural numbers. -/
@[elab_as_elim]
def recOnPosPrimePosCoprime {P : ℕ → Sort*} (hp : ∀ p n : ℕ, Prime p → 0 < n → P (p ^ n))
    (h0 : P 0) (h1 : P 1) (h : ∀ a b, 1 < a → 1 < b → Coprime a b → P a → P b → P (a * b)) :
    ∀ a, P a :=
  recOnPrimePow h0 h1 <| by
    intro a p n hp' hpa hn hPa
    by_cases ha1 : a = 1
    · rw [ha1, mul_one]
      exact hp p n hp' hn
    refine' h (p ^ n) a (hp'.one_lt.trans_le (le_self_pow hn.ne' _)) _ _ (hp _ _ hp' hn) hPa
    · contrapose! hpa
      simp [lt_one_iff.1 (lt_of_le_of_ne hpa ha1)]
    

Proof state:
case neg.refine'_2
a✝ b m n✝ p✝ : ℕ
P : ℕ → Sort u_1
hp : (p n : ℕ) → Prime p → 0 < n → P (p ^ n)
h0 : P 0
h1 : P 1
h : (a b : ℕ) → 1 < a → 1 < b → Coprime a b → P a → P b → P (a * b)
a p n : ℕ
hp' : Prime p
hpa : ¬p ∣ a
hn : 0 < n
hPa : P a
ha1 : ¬a = 1
⊢ Coprime (p ^ n) a

Next tactic:
simpa [hn, Prime.coprime_iff_not_dvd hp']
/-- Given `P 0`, `P 1`, `P p` for all primes, and a way to extend `P a` and `P b` to
`P (a * b)`, we can define `P` for all natural numbers. -/
@[elab_as_elim]
def recOnMul {P : ℕ → Sort*} (h0 : P 0) (h1 : P 1) (hp : ∀ p, Prime p → P p)
    (h : ∀ a b, P a → P b → P (a * b)) : ∀ a, P a :=
  let hp : ∀ p n : ℕ, Prime p → P (p ^ n) := fun p n hp' =>
    n.recOn h1 (fun n hn => by 

Proof state:
a b m n✝¹ p✝ : ℕ
P : ℕ → Sort u_1
h0 : P 0
h1 : P 1
hp : (p : ℕ) → Prime p → P p
h : (a b : ℕ) → P a → P b → P (a * b)
p n✝ : ℕ
hp' : Prime p
n : ℕ
hn : P (p ^ n)
⊢ P (p ^ succ n)

Next tactic:
rw [pow_succ]
/-- Given `P 0`, `P 1`, `P p` for all primes, and a way to extend `P a` and `P b` to
`P (a * b)`, we can define `P` for all natural numbers. -/
@[elab_as_elim]
def recOnMul {P : ℕ → Sort*} (h0 : P 0) (h1 : P 1) (hp : ∀ p, Prime p → P p)
    (h : ∀ a b, P a → P b → P (a * b)) : ∀ a, P a :=
  let hp : ∀ p n : ℕ, Prime p → P (p ^ n) := fun p n hp' =>
    n.recOn h1 (fun n hn => by rw [pow_succ]; 

Proof state:
a b m n✝¹ p✝ : ℕ
P : ℕ → Sort u_1
h0 : P 0
h1 : P 1
hp : (p : ℕ) → Prime p → P p
h : (a b : ℕ) → P a → P b → P (a * b)
p n✝ : ℕ
hp' : Prime p
n : ℕ
hn : P (p ^ n)
⊢ P (p ^ n * p)

Next tactic:
apply h _ _ hn (hp p hp')