l3lab/ntp-mathlib huggingface dataset:
theorem properDivisors_eq_singleton_one_iff_prime : n.properDivisors = {1} ↔ n.Prime := by
  refine ⟨?_, ?_⟩
  · intro h
    refine' Nat.prime_def_lt''.mpr ⟨_, fun m hdvd => _⟩
    · match n with
      | 0 => contradiction
      | 1 => contradiction
      | Nat.succ (Nat.succ n) => simp [succ_le_succ]
    · rw [← mem_singleton, ← h, mem_properDivisors]
      have := Nat.le_of_dvd ?_ hdvd
      · simp [hdvd, this]
        exact (le_iff_eq_or_lt.mp this).symm
      · by_contra!
        simp only [nonpos_iff_eq_zero.mp this, this] at h
        contradiction
  · 

Proof state:
case refine_2
n : ℕ
⊢ Prime n → properDivisors n = {1}

Next tactic:
exact fun h => Prime.properDivisors h
theorem sum_properDivisors_eq_one_iff_prime : ∑ x in n.properDivisors, x = 1 ↔ n.Prime := by
  

Proof state:
n : ℕ
⊢ ∑ x in properDivisors n, x = 1 ↔ Prime n

Next tactic:
cases' n with n
theorem sum_properDivisors_eq_one_iff_prime : ∑ x in n.properDivisors, x = 1 ↔ n.Prime := by
  cases' n with n
  · 

Proof state:
case zero
⊢ ∑ x in properDivisors zero, x = 1 ↔ Prime zero

Next tactic:
simp [Nat.not_prime_zero]
theorem sum_properDivisors_eq_one_iff_prime : ∑ x in n.properDivisors, x = 1 ↔ n.Prime := by
  cases' n with n
  · simp [Nat.not_prime_zero]
  · 

Proof state:
case succ
n : ℕ
⊢ ∑ x in properDivisors (succ n), x = 1 ↔ Prime (succ n)

Next tactic:
cases n
theorem sum_properDivisors_eq_one_iff_prime : ∑ x in n.properDivisors, x = 1 ↔ n.Prime := by
  cases' n with n
  · simp [Nat.not_prime_zero]
  · cases n
    · 

Proof state:
case succ.zero
⊢ ∑ x in properDivisors (succ zero), x = 1 ↔ Prime (succ zero)

Next tactic:
simp [Nat.not_prime_one]
theorem sum_properDivisors_eq_one_iff_prime : ∑ x in n.properDivisors, x = 1 ↔ n.Prime := by
  cases' n with n
  · simp [Nat.not_prime_zero]
  · cases n
    · simp [Nat.not_prime_one]
    · 

Proof state:
case succ.succ
n✝ : ℕ
⊢ ∑ x in properDivisors (succ (succ n✝)), x = 1 ↔ Prime (succ (succ n✝))

Next tactic:
rw [← properDivisors_eq_singleton_one_iff_prime]
theorem sum_properDivisors_eq_one_iff_prime : ∑ x in n.properDivisors, x = 1 ↔ n.Prime := by
  cases' n with n
  · simp [Nat.not_prime_zero]
  · cases n
    · simp [Nat.not_prime_one]
    · rw [← properDivisors_eq_singleton_one_iff_prime]
      

Proof state:
case succ.succ
n✝ : ℕ
⊢ ∑ x in properDivisors (succ (succ n✝)), x = 1 ↔ properDivisors (succ (succ n✝)) = {1}

Next tactic:
refine' ⟨fun h => _, fun h => h.symm ▸ sum_singleton _ _⟩
theorem sum_properDivisors_eq_one_iff_prime : ∑ x in n.properDivisors, x = 1 ↔ n.Prime := by
  cases' n with n
  · simp [Nat.not_prime_zero]
  · cases n
    · simp [Nat.not_prime_one]
    · rw [← properDivisors_eq_singleton_one_iff_prime]
      refine' ⟨fun h => _, fun h => h.symm ▸ sum_singleton _ _⟩
      

Proof state:
case succ.succ
n✝ : ℕ
h : ∑ x in properDivisors (succ (succ n✝)), x = 1
⊢ properDivisors (succ (succ n✝)) = {1}

Next tactic:
rw [@eq_comm (Finset ℕ) _ _]
theorem sum_properDivisors_eq_one_iff_prime : ∑ x in n.properDivisors, x = 1 ↔ n.Prime := by
  cases' n with n
  · simp [Nat.not_prime_zero]
  · cases n
    · simp [Nat.not_prime_one]
    · rw [← properDivisors_eq_singleton_one_iff_prime]
      refine' ⟨fun h => _, fun h => h.symm ▸ sum_singleton _ _⟩
      rw [@eq_comm (Finset ℕ) _ _]
      

Proof state:
case succ.succ
n✝ : ℕ
h : ∑ x in properDivisors (succ (succ n✝)), x = 1
⊢ {1} = properDivisors (succ (succ n✝))

Next tactic:
apply
        eq_properDivisors_of_subset_of_sum_eq_sum
          (singleton_subset_iff.2
            (one_mem_properDivisors_iff_one_lt.2 (succ_lt_succ (Nat.succ_pos _))))
          ((sum_singleton _ _).trans h.symm)
theorem mem_properDivisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) {x : ℕ} :
    x ∈ properDivisors (p ^ k) ↔ ∃ (j : ℕ) (_ : j < k), x = p ^ j := by
  

Proof state:
n p : ℕ
pp : Prime p
k x : ℕ
⊢ x ∈ properDivisors (p ^ k) ↔ ∃ j, ∃ (_ : j < k), x = p ^ j

Next tactic:
rw [mem_properDivisors, Nat.dvd_prime_pow pp, ← exists_and_right]
theorem mem_properDivisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) {x : ℕ} :
    x ∈ properDivisors (p ^ k) ↔ ∃ (j : ℕ) (_ : j < k), x = p ^ j := by
  rw [mem_properDivisors, Nat.dvd_prime_pow pp, ← exists_and_right]
  

Proof state:
n p : ℕ
pp : Prime p
k x : ℕ
⊢ (∃ x_1, (x_1 ≤ k ∧ x = p ^ x_1) ∧ x < p ^ k) ↔ ∃ j, ∃ (_ : j < k), x = p ^ j

Next tactic:
simp only [exists_prop, and_assoc]
theorem mem_properDivisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) {x : ℕ} :
    x ∈ properDivisors (p ^ k) ↔ ∃ (j : ℕ) (_ : j < k), x = p ^ j := by
  rw [mem_properDivisors, Nat.dvd_prime_pow pp, ← exists_and_right]
  simp only [exists_prop, and_assoc]
  

Proof state:
n p : ℕ
pp : Prime p
k x : ℕ
⊢ (∃ x_1 ≤ k, x = p ^ x_1 ∧ x < p ^ k) ↔ ∃ j < k, x = p ^ j

Next tactic:
apply exists_congr
theorem mem_properDivisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) {x : ℕ} :
    x ∈ properDivisors (p ^ k) ↔ ∃ (j : ℕ) (_ : j < k), x = p ^ j := by
  rw [mem_properDivisors, Nat.dvd_prime_pow pp, ← exists_and_right]
  simp only [exists_prop, and_assoc]
  apply exists_congr
  

Proof state:
case h
n p : ℕ
pp : Prime p
k x : ℕ
⊢ ∀ (a : ℕ), a ≤ k ∧ x = p ^ a ∧ x < p ^ k ↔ a < k ∧ x = p ^ a

Next tactic:
intro a
theorem mem_properDivisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) {x : ℕ} :
    x ∈ properDivisors (p ^ k) ↔ ∃ (j : ℕ) (_ : j < k), x = p ^ j := by
  rw [mem_properDivisors, Nat.dvd_prime_pow pp, ← exists_and_right]
  simp only [exists_prop, and_assoc]
  apply exists_congr
  intro a
  

Proof state:
case h
n p : ℕ
pp : Prime p
k x a : ℕ
⊢ a ≤ k ∧ x = p ^ a ∧ x < p ^ k ↔ a < k ∧ x = p ^ a

Next tactic:
constructor
theorem mem_properDivisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) {x : ℕ} :
    x ∈ properDivisors (p ^ k) ↔ ∃ (j : ℕ) (_ : j < k), x = p ^ j := by
  rw [mem_properDivisors, Nat.dvd_prime_pow pp, ← exists_and_right]
  simp only [exists_prop, and_assoc]
  apply exists_congr
  intro a
  constructor <;> 

Proof state:
case h.mp
n p : ℕ
pp : Prime p
k x a : ℕ
⊢ a ≤ k ∧ x = p ^ a ∧ x < p ^ k → a < k ∧ x = p ^ a

Next tactic:
intro h
theorem mem_properDivisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) {x : ℕ} :
    x ∈ properDivisors (p ^ k) ↔ ∃ (j : ℕ) (_ : j < k), x = p ^ j := by
  rw [mem_properDivisors, Nat.dvd_prime_pow pp, ← exists_and_right]
  simp only [exists_prop, and_assoc]
  apply exists_congr
  intro a
  constructor <;> 

Proof state:
case h.mpr
n p : ℕ
pp : Prime p
k x a : ℕ
⊢ a < k ∧ x = p ^ a → a ≤ k ∧ x = p ^ a ∧ x < p ^ k

Next tactic:
intro h
theorem mem_properDivisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) {x : ℕ} :
    x ∈ properDivisors (p ^ k) ↔ ∃ (j : ℕ) (_ : j < k), x = p ^ j := by
  rw [mem_properDivisors, Nat.dvd_prime_pow pp, ← exists_and_right]
  simp only [exists_prop, and_assoc]
  apply exists_congr
  intro a
  constructor <;> intro h
  · 

Proof state:
case h.mp
n p : ℕ
pp : Prime p
k x a : ℕ
h : a ≤ k ∧ x = p ^ a ∧ x < p ^ k
⊢ a < k ∧ x = p ^ a

Next tactic:
rcases h with ⟨_h_left, rfl, h_right⟩
theorem mem_properDivisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) {x : ℕ} :
    x ∈ properDivisors (p ^ k) ↔ ∃ (j : ℕ) (_ : j < k), x = p ^ j := by
  rw [mem_properDivisors, Nat.dvd_prime_pow pp, ← exists_and_right]
  simp only [exists_prop, and_assoc]
  apply exists_congr
  intro a
  constructor <;> intro h
  · rcases h with ⟨_h_left, rfl, h_right⟩
    

Proof state:
case h.mp.intro.intro
n p : ℕ
pp : Prime p
k a : ℕ
_h_left : a ≤ k
h_right : p ^ a < p ^ k
⊢ a < k ∧ p ^ a = p ^ a

Next tactic:
rw [pow_lt_pow_iff_right pp.one_lt] at h_right
theorem mem_properDivisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) {x : ℕ} :
    x ∈ properDivisors (p ^ k) ↔ ∃ (j : ℕ) (_ : j < k), x = p ^ j := by
  rw [mem_properDivisors, Nat.dvd_prime_pow pp, ← exists_and_right]
  simp only [exists_prop, and_assoc]
  apply exists_congr
  intro a
  constructor <;> intro h
  · rcases h with ⟨_h_left, rfl, h_right⟩
    rw [pow_lt_pow_iff_right pp.one_lt] at h_right
    

Proof state:
case h.mp.intro.intro
n p : ℕ
pp : Prime p
k a : ℕ
_h_left : a ≤ k
h_right : a < k
⊢ a < k ∧ p ^ a = p ^ a

Next tactic:
exact ⟨h_right, by rfl⟩
theorem mem_properDivisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) {x : ℕ} :
    x ∈ properDivisors (p ^ k) ↔ ∃ (j : ℕ) (_ : j < k), x = p ^ j := by
  rw [mem_properDivisors, Nat.dvd_prime_pow pp, ← exists_and_right]
  simp only [exists_prop, and_assoc]
  apply exists_congr
  intro a
  constructor <;> intro h
  · rcases h with ⟨_h_left, rfl, h_right⟩
    rw [pow_lt_pow_iff_right pp.one_lt] at h_right
    exact ⟨h_right, by 

Proof state:
n p : ℕ
pp : Prime p
k a : ℕ
_h_left : a ≤ k
h_right : a < k
⊢ p ^ a = p ^ a

Next tactic:
rfl
theorem mem_properDivisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) {x : ℕ} :
    x ∈ properDivisors (p ^ k) ↔ ∃ (j : ℕ) (_ : j < k), x = p ^ j := by
  rw [mem_properDivisors, Nat.dvd_prime_pow pp, ← exists_and_right]
  simp only [exists_prop, and_assoc]
  apply exists_congr
  intro a
  constructor <;> intro h
  · rcases h with ⟨_h_left, rfl, h_right⟩
    rw [pow_lt_pow_iff_right pp.one_lt] at h_right
    exact ⟨h_right, by rfl⟩
  · 

Proof state:
case h.mpr
n p : ℕ
pp : Prime p
k x a : ℕ
h : a < k ∧ x = p ^ a
⊢ a ≤ k ∧ x = p ^ a ∧ x < p ^ k

Next tactic:
rcases h with ⟨h_left, rfl⟩
theorem mem_properDivisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) {x : ℕ} :
    x ∈ properDivisors (p ^ k) ↔ ∃ (j : ℕ) (_ : j < k), x = p ^ j := by
  rw [mem_properDivisors, Nat.dvd_prime_pow pp, ← exists_and_right]
  simp only [exists_prop, and_assoc]
  apply exists_congr
  intro a
  constructor <;> intro h
  · rcases h with ⟨_h_left, rfl, h_right⟩
    rw [pow_lt_pow_iff_right pp.one_lt] at h_right
    exact ⟨h_right, by rfl⟩
  · rcases h with ⟨h_left, rfl⟩
    

Proof state:
case h.mpr.intro
n p : ℕ
pp : Prime p
k a : ℕ
h_left : a < k
⊢ a ≤ k ∧ p ^ a = p ^ a ∧ p ^ a < p ^ k

Next tactic:
rw [pow_lt_pow_iff_right pp.one_lt]
theorem mem_properDivisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) {x : ℕ} :
    x ∈ properDivisors (p ^ k) ↔ ∃ (j : ℕ) (_ : j < k), x = p ^ j := by
  rw [mem_properDivisors, Nat.dvd_prime_pow pp, ← exists_and_right]
  simp only [exists_prop, and_assoc]
  apply exists_congr
  intro a
  constructor <;> intro h
  · rcases h with ⟨_h_left, rfl, h_right⟩
    rw [pow_lt_pow_iff_right pp.one_lt] at h_right
    exact ⟨h_right, by rfl⟩
  · rcases h with ⟨h_left, rfl⟩
    rw [pow_lt_pow_iff_right pp.one_lt]
    

Proof state:
case h.mpr.intro
n p : ℕ
pp : Prime p
k a : ℕ
h_left : a < k
⊢ a ≤ k ∧ p ^ a = p ^ a ∧ a < k

Next tactic:
simp [h_left, le_of_lt]
theorem properDivisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) :
    properDivisors (p ^ k) = (Finset.range k).map ⟨(p ^ ·), Nat.pow_right_injective pp.two_le⟩ := by
  

Proof state:
n p : ℕ
pp : Prime p
k : ℕ
⊢ properDivisors (p ^ k) = map { toFun := fun x => p ^ x, inj' := (_ : Function.Injective fun x => p ^ x) } (range k)

Next tactic:
ext a
theorem properDivisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) :
    properDivisors (p ^ k) = (Finset.range k).map ⟨(p ^ ·), Nat.pow_right_injective pp.two_le⟩ := by
  ext a
  

Proof state:
case a
n p : ℕ
pp : Prime p
k a : ℕ
⊢ a ∈ properDivisors (p ^ k) ↔
    a ∈ map { toFun := fun x => p ^ x, inj' := (_ : Function.Injective fun x => p ^ x) } (range k)

Next tactic:
simp only [mem_properDivisors, Nat.isUnit_iff, mem_map, mem_range, Function.Embedding.coeFn_mk,
    pow_eq]
theorem properDivisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) :
    properDivisors (p ^ k) = (Finset.range k).map ⟨(p ^ ·), Nat.pow_right_injective pp.two_le⟩ := by
  ext a
  simp only [mem_properDivisors, Nat.isUnit_iff, mem_map, mem_range, Function.Embedding.coeFn_mk,
    pow_eq]
  

Proof state:
case a
n p : ℕ
pp : Prime p
k a : ℕ
⊢ a ∣ p ^ k ∧ a < p ^ k ↔ ∃ a_1 < k, p ^ a_1 = a

Next tactic:
have := mem_properDivisors_prime_pow pp k (x := a)
theorem properDivisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) :
    properDivisors (p ^ k) = (Finset.range k).map ⟨(p ^ ·), Nat.pow_right_injective pp.two_le⟩ := by
  ext a
  simp only [mem_properDivisors, Nat.isUnit_iff, mem_map, mem_range, Function.Embedding.coeFn_mk,
    pow_eq]
  have := mem_properDivisors_prime_pow pp k (x := a)
  

Proof state:
case a
n p : ℕ
pp : Prime p
k a : ℕ
this : a ∈ properDivisors (p ^ k) ↔ ∃ j, ∃ (_ : j < k), a = p ^ j
⊢ a ∣ p ^ k ∧ a < p ^ k ↔ ∃ a_1 < k, p ^ a_1 = a

Next tactic:
rw [mem_properDivisors] at this
theorem properDivisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) :
    properDivisors (p ^ k) = (Finset.range k).map ⟨(p ^ ·), Nat.pow_right_injective pp.two_le⟩ := by
  ext a
  simp only [mem_properDivisors, Nat.isUnit_iff, mem_map, mem_range, Function.Embedding.coeFn_mk,
    pow_eq]
  have := mem_properDivisors_prime_pow pp k (x := a)
  rw [mem_properDivisors] at this
  

Proof state:
case a
n p : ℕ
pp : Prime p
k a : ℕ
this : a ∣ p ^ k ∧ a < p ^ k ↔ ∃ j, ∃ (_ : j < k), a = p ^ j
⊢ a ∣ p ^ k ∧ a < p ^ k ↔ ∃ a_1 < k, p ^ a_1 = a

Next tactic:
rw [this]
theorem properDivisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) :
    properDivisors (p ^ k) = (Finset.range k).map ⟨(p ^ ·), Nat.pow_right_injective pp.two_le⟩ := by
  ext a
  simp only [mem_properDivisors, Nat.isUnit_iff, mem_map, mem_range, Function.Embedding.coeFn_mk,
    pow_eq]
  have := mem_properDivisors_prime_pow pp k (x := a)
  rw [mem_properDivisors] at this
  rw [this]
  

Proof state:
case a
n p : ℕ
pp : Prime p
k a : ℕ
this : a ∣ p ^ k ∧ a < p ^ k ↔ ∃ j, ∃ (_ : j < k), a = p ^ j
⊢ (∃ j, ∃ (_ : j < k), a = p ^ j) ↔ ∃ a_1 < k, p ^ a_1 = a

Next tactic:
refine ⟨?_, ?_⟩
theorem properDivisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) :
    properDivisors (p ^ k) = (Finset.range k).map ⟨(p ^ ·), Nat.pow_right_injective pp.two_le⟩ := by
  ext a
  simp only [mem_properDivisors, Nat.isUnit_iff, mem_map, mem_range, Function.Embedding.coeFn_mk,
    pow_eq]
  have := mem_properDivisors_prime_pow pp k (x := a)
  rw [mem_properDivisors] at this
  rw [this]
  refine ⟨?_, ?_⟩
  · 

Proof state:
case a.refine_1
n p : ℕ
pp : Prime p
k a : ℕ
this : a ∣ p ^ k ∧ a < p ^ k ↔ ∃ j, ∃ (_ : j < k), a = p ^ j
⊢ (∃ j, ∃ (_ : j < k), a = p ^ j) → ∃ a_2 < k, p ^ a_2 = a

Next tactic:
intro h
theorem properDivisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) :
    properDivisors (p ^ k) = (Finset.range k).map ⟨(p ^ ·), Nat.pow_right_injective pp.two_le⟩ := by
  ext a
  simp only [mem_properDivisors, Nat.isUnit_iff, mem_map, mem_range, Function.Embedding.coeFn_mk,
    pow_eq]
  have := mem_properDivisors_prime_pow pp k (x := a)
  rw [mem_properDivisors] at this
  rw [this]
  refine ⟨?_, ?_⟩
  · intro h; 

Proof state:
case a.refine_1
n p : ℕ
pp : Prime p
k a : ℕ
this : a ∣ p ^ k ∧ a < p ^ k ↔ ∃ j, ∃ (_ : j < k), a = p ^ j
h : ∃ j, ∃ (_ : j < k), a = p ^ j
⊢ ∃ a_1 < k, p ^ a_1 = a

Next tactic:
rcases h with ⟨j, hj, hap⟩
theorem properDivisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) :
    properDivisors (p ^ k) = (Finset.range k).map ⟨(p ^ ·), Nat.pow_right_injective pp.two_le⟩ := by
  ext a
  simp only [mem_properDivisors, Nat.isUnit_iff, mem_map, mem_range, Function.Embedding.coeFn_mk,
    pow_eq]
  have := mem_properDivisors_prime_pow pp k (x := a)
  rw [mem_properDivisors] at this
  rw [this]
  refine ⟨?_, ?_⟩
  · intro h; rcases h with ⟨j, hj, hap⟩; 

Proof state:
case a.refine_1.intro.intro
n p : ℕ
pp : Prime p
k a : ℕ
this : a ∣ p ^ k ∧ a < p ^ k ↔ ∃ j, ∃ (_ : j < k), a = p ^ j
j : ℕ
hj : j < k
hap : a = p ^ j
⊢ ∃ a_1 < k, p ^ a_1 = a

Next tactic:
use j
theorem properDivisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) :
    properDivisors (p ^ k) = (Finset.range k).map ⟨(p ^ ·), Nat.pow_right_injective pp.two_le⟩ := by
  ext a
  simp only [mem_properDivisors, Nat.isUnit_iff, mem_map, mem_range, Function.Embedding.coeFn_mk,
    pow_eq]
  have := mem_properDivisors_prime_pow pp k (x := a)
  rw [mem_properDivisors] at this
  rw [this]
  refine ⟨?_, ?_⟩
  · intro h; rcases h with ⟨j, hj, hap⟩; use j; 

Proof state:
case h
n p : ℕ
pp : Prime p
k a : ℕ
this : a ∣ p ^ k ∧ a < p ^ k ↔ ∃ j, ∃ (_ : j < k), a = p ^ j
j : ℕ
hj : j < k
hap : a = p ^ j
⊢ j < k ∧ p ^ j = a

Next tactic:
tauto
theorem properDivisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) :
    properDivisors (p ^ k) = (Finset.range k).map ⟨(p ^ ·), Nat.pow_right_injective pp.two_le⟩ := by
  ext a
  simp only [mem_properDivisors, Nat.isUnit_iff, mem_map, mem_range, Function.Embedding.coeFn_mk,
    pow_eq]
  have := mem_properDivisors_prime_pow pp k (x := a)
  rw [mem_properDivisors] at this
  rw [this]
  refine ⟨?_, ?_⟩
  · intro h; rcases h with ⟨j, hj, hap⟩; use j; tauto
  · 

Proof state:
case a.refine_2
n p : ℕ
pp : Prime p
k a : ℕ
this : a ∣ p ^ k ∧ a < p ^ k ↔ ∃ j, ∃ (_ : j < k), a = p ^ j
⊢ (∃ a_1 < k, p ^ a_1 = a) → ∃ j, ∃ (_ : j < k), a = p ^ j

Next tactic:
tauto
@[to_additive (attr := simp)]
theorem prod_properDivisors_prime_pow {α : Type*} [CommMonoid α] {k p : ℕ} {f : ℕ → α}
    (h : p.Prime) : (∏ x in (p ^ k).properDivisors, f x) = ∏ x in range k, f (p ^ x) := by
  

Proof state:
n : ℕ
α : Type u_1
inst✝ : CommMonoid α
k p : ℕ
f : ℕ → α
h : Prime p
⊢ ∏ x in properDivisors (p ^ k), f x = ∏ x in range k, f (p ^ x)

Next tactic:
simp [h, properDivisors_prime_pow]
@[to_additive (attr := simp) sum_divisors_prime_pow]
theorem prod_divisors_prime_pow {α : Type*} [CommMonoid α] {k p : ℕ} {f : ℕ → α} (h : p.Prime) :
    (∏ x in (p ^ k).divisors, f x) = ∏ x in range (k + 1), f (p ^ x) := by
  

Proof state:
n : ℕ
α : Type u_1
inst✝ : CommMonoid α
k p : ℕ
f : ℕ → α
h : Prime p
⊢ ∏ x in divisors (p ^ k), f x = ∏ x in range (k + 1), f (p ^ x)

Next tactic:
simp [h, divisors_prime_pow]
@[to_additive]
theorem prod_divisorsAntidiagonal {M : Type*} [CommMonoid M] (f : ℕ → ℕ → M) {n : ℕ} :
    ∏ i in n.divisorsAntidiagonal, f i.1 i.2 = ∏ i in n.divisors, f i (n / i) := by
  

Proof state:
n✝ : ℕ
M : Type u_1
inst✝ : CommMonoid M
f : ℕ → ℕ → M
n : ℕ
⊢ ∏ i in divisorsAntidiagonal n, f i.1 i.2 = ∏ i in divisors n, f i (n / i)

Next tactic:
rw [← map_div_right_divisors, Finset.prod_map]
@[to_additive]
theorem prod_divisorsAntidiagonal {M : Type*} [CommMonoid M] (f : ℕ → ℕ → M) {n : ℕ} :
    ∏ i in n.divisorsAntidiagonal, f i.1 i.2 = ∏ i in n.divisors, f i (n / i) := by
  rw [← map_div_right_divisors, Finset.prod_map]
  

Proof state:
n✝ : ℕ
M : Type u_1
inst✝ : CommMonoid M
f : ℕ → ℕ → M
n : ℕ
⊢ ∏ x in divisors n,
      f
        ({ toFun := fun d => (d, n / d),
              inj' :=
                (_ :
                  ∀ (p₁ p₂ : ℕ),
                    (fun d => (d, n / d)) p₁ = (fun d => (d, n / d)) p₂ →
                      ((fun d => (d, n / d)) p₁).1 = ((fun d => (d, n / d)) p₂).1) }
            x).1
        ({ toFun := fun d => (d, n / d),
              inj' :=
                (_ :
                  ∀ (p₁ p₂ : ℕ),
                    (fun d => (d, n / d)) p₁ = (fun d => (d, n / d)) p₂ →
                      ((fun d => (d, n / d)) p₁).1 = ((fun d => (d, n / d)) p₂).1) }
            x).2 =
    ∏ i in divisors n, f i (n / i)

Next tactic:
rfl
@[to_additive]
theorem prod_divisorsAntidiagonal' {M : Type*} [CommMonoid M] (f : ℕ → ℕ → M) {n : ℕ} :
    ∏ i in n.divisorsAntidiagonal, f i.1 i.2 = ∏ i in n.divisors, f (n / i) i := by
  

Proof state:
n✝ : ℕ
M : Type u_1
inst✝ : CommMonoid M
f : ℕ → ℕ → M
n : ℕ
⊢ ∏ i in divisorsAntidiagonal n, f i.1 i.2 = ∏ i in divisors n, f (n / i) i

Next tactic:
rw [← map_swap_divisorsAntidiagonal, Finset.prod_map]
@[to_additive]
theorem prod_divisorsAntidiagonal' {M : Type*} [CommMonoid M] (f : ℕ → ℕ → M) {n : ℕ} :
    ∏ i in n.divisorsAntidiagonal, f i.1 i.2 = ∏ i in n.divisors, f (n / i) i := by
  rw [← map_swap_divisorsAntidiagonal, Finset.prod_map]
  

Proof state:
n✝ : ℕ
M : Type u_1
inst✝ : CommMonoid M
f : ℕ → ℕ → M
n : ℕ
⊢ ∏ x in divisorsAntidiagonal n,
      f ((Equiv.toEmbedding (Equiv.prodComm ℕ ℕ)) x).1 ((Equiv.toEmbedding (Equiv.prodComm ℕ ℕ)) x).2 =
    ∏ i in divisors n, f (n / i) i

Next tactic:
exact prod_divisorsAntidiagonal fun i j => f j i
/-- The factors of `n` are the prime divisors -/
theorem prime_divisors_eq_to_filter_divisors_prime (n : ℕ) :
    n.factors.toFinset = (divisors n).filter Prime := by
  

Proof state:
n✝ n : ℕ
⊢ List.toFinset (factors n) = filter Prime (divisors n)

Next tactic:
rcases n.eq_zero_or_pos with (rfl | hn)
/-- The factors of `n` are the prime divisors -/
theorem prime_divisors_eq_to_filter_divisors_prime (n : ℕ) :
    n.factors.toFinset = (divisors n).filter Prime := by
  rcases n.eq_zero_or_pos with (rfl | hn)
  · 

Proof state:
case inl
n : ℕ
⊢ List.toFinset (factors 0) = filter Prime (divisors 0)

Next tactic:
simp
/-- The factors of `n` are the prime divisors -/
theorem prime_divisors_eq_to_filter_divisors_prime (n : ℕ) :
    n.factors.toFinset = (divisors n).filter Prime := by
  rcases n.eq_zero_or_pos with (rfl | hn)
  · simp
  · 

Proof state:
case inr
n✝ n : ℕ
hn : n > 0
⊢ List.toFinset (factors n) = filter Prime (divisors n)

Next tactic:
ext q
/-- The factors of `n` are the prime divisors -/
theorem prime_divisors_eq_to_filter_divisors_prime (n : ℕ) :
    n.factors.toFinset = (divisors n).filter Prime := by
  rcases n.eq_zero_or_pos with (rfl | hn)
  · simp
  · ext q
    

Proof state:
case inr.a
n✝ n : ℕ
hn : n > 0
q : ℕ
⊢ q ∈ List.toFinset (factors n) ↔ q ∈ filter Prime (divisors n)

Next tactic:
simpa [hn, hn.ne', mem_factors] using and_comm
lemma prime_divisors_filter_dvd_of_dvd {m n : ℕ} (hn : n ≠ 0) (hmn : m ∣ n) :
    n.factors.toFinset.filter (· ∣ m) = m.factors.toFinset := by
  

Proof state:
n✝ m n : ℕ
hn : n ≠ 0
hmn : m ∣ n
⊢ filter (fun x => x ∣ m) (List.toFinset (factors n)) = List.toFinset (factors m)

Next tactic:
simp_rw [prime_divisors_eq_to_filter_divisors_prime, filter_comm,
    divisors_filter_dvd_of_dvd hn hmn]
@[simp]
theorem image_div_divisors_eq_divisors (n : ℕ) :
    image (fun x : ℕ => n / x) n.divisors = n.divisors := by
  

Proof state:
n✝ n : ℕ
⊢ image (fun x => n / x) (divisors n) = divisors n

Next tactic:
by_cases hn : n = 0
@[simp]
theorem image_div_divisors_eq_divisors (n : ℕ) :
    image (fun x : ℕ => n / x) n.divisors = n.divisors := by
  by_cases hn : n = 0
  · 

Proof state:
case pos
n✝ n : ℕ
hn : n = 0
⊢ image (fun x => n / x) (divisors n) = divisors n

Next tactic:
simp [hn]
@[simp]
theorem image_div_divisors_eq_divisors (n : ℕ) :
    image (fun x : ℕ => n / x) n.divisors = n.divisors := by
  by_cases hn : n = 0
  · simp [hn]
  

Proof state:
case neg
n✝ n : ℕ
hn : ¬n = 0
⊢ image (fun x => n / x) (divisors n) = divisors n

Next tactic:
ext a
@[simp]
theorem image_div_divisors_eq_divisors (n : ℕ) :
    image (fun x : ℕ => n / x) n.divisors = n.divisors := by
  by_cases hn : n = 0
  · simp [hn]
  ext a
  

Proof state:
case neg.a
n✝ n : ℕ
hn : ¬n = 0
a : ℕ
⊢ a ∈ image (fun x => n / x) (divisors n) ↔ a ∈ divisors n

Next tactic:
constructor
@[simp]
theorem image_div_divisors_eq_divisors (n : ℕ) :
    image (fun x : ℕ => n / x) n.divisors = n.divisors := by
  by_cases hn : n = 0
  · simp [hn]
  ext a
  constructor
  · 

Proof state:
case neg.a.mp
n✝ n : ℕ
hn : ¬n = 0
a : ℕ
⊢ a ∈ image (fun x => n / x) (divisors n) → a ∈ divisors n

Next tactic:
rw [mem_image]
@[simp]
theorem image_div_divisors_eq_divisors (n : ℕ) :
    image (fun x : ℕ => n / x) n.divisors = n.divisors := by
  by_cases hn : n = 0
  · simp [hn]
  ext a
  constructor
  · rw [mem_image]
    

Proof state:
case neg.a.mp
n✝ n : ℕ
hn : ¬n = 0
a : ℕ
⊢ (∃ a_1 ∈ divisors n, n / a_1 = a) → a ∈ divisors n

Next tactic:
rintro ⟨x, hx1, hx2⟩
@[simp]
theorem image_div_divisors_eq_divisors (n : ℕ) :
    image (fun x : ℕ => n / x) n.divisors = n.divisors := by
  by_cases hn : n = 0
  · simp [hn]
  ext a
  constructor
  · rw [mem_image]
    rintro ⟨x, hx1, hx2⟩
    

Proof state:
case neg.a.mp.intro.intro
n✝ n : ℕ
hn : ¬n = 0
a x : ℕ
hx1 : x ∈ divisors n
hx2 : n / x = a
⊢ a ∈ divisors n

Next tactic:
rw [mem_divisors] at *
@[simp]
theorem image_div_divisors_eq_divisors (n : ℕ) :
    image (fun x : ℕ => n / x) n.divisors = n.divisors := by
  by_cases hn : n = 0
  · simp [hn]
  ext a
  constructor
  · rw [mem_image]
    rintro ⟨x, hx1, hx2⟩
    rw [mem_divisors] at *
    

Proof state:
case neg.a.mp.intro.intro
n✝ n : ℕ
hn : ¬n = 0
a x : ℕ
hx1 : x ∣ n ∧ n ≠ 0
hx2 : n / x = a
⊢ a ∣ n ∧ n ≠ 0

Next tactic:
refine' ⟨_, hn⟩