l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem mem_divisorsAntidiagonal {x : ℕ × ℕ} :
    x ∈ divisorsAntidiagonal n ↔ x.fst * x.snd = n ∧ n ≠ 0 := by
  simp only [divisorsAntidiagonal, Finset.mem_Ico, Ne.def, Finset.mem_filter, Finset.mem_product]
  rw [and_comm]
  apply and_congr_right
  rintro rfl
  constructor <;> intro h
  · contrapose! h
    simp [h]
  · rw [Nat.lt_add_one_iff, Nat.lt_add_one_iff]
    

Proof state:
case h.mpr
x : ℕ × ℕ
h : ¬x.1 * x.2 = 0
⊢ (1 ≤ x.1 ∧ x.1 ≤ x.1 * x.2) ∧ 1 ≤ x.2 ∧ x.2 ≤ x.1 * x.2

Next tactic:
rw [mul_eq_zero, not_or] at h
@[simp]
theorem mem_divisorsAntidiagonal {x : ℕ × ℕ} :
    x ∈ divisorsAntidiagonal n ↔ x.fst * x.snd = n ∧ n ≠ 0 := by
  simp only [divisorsAntidiagonal, Finset.mem_Ico, Ne.def, Finset.mem_filter, Finset.mem_product]
  rw [and_comm]
  apply and_congr_right
  rintro rfl
  constructor <;> intro h
  · contrapose! h
    simp [h]
  · rw [Nat.lt_add_one_iff, Nat.lt_add_one_iff]
    rw [mul_eq_zero, not_or] at h
    

Proof state:
case h.mpr
x : ℕ × ℕ
h : ¬x.1 = 0 ∧ ¬x.2 = 0
⊢ (1 ≤ x.1 ∧ x.1 ≤ x.1 * x.2) ∧ 1 ≤ x.2 ∧ x.2 ≤ x.1 * x.2

Next tactic:
simp only [succ_le_of_lt (Nat.pos_of_ne_zero h.1), succ_le_of_lt (Nat.pos_of_ne_zero h.2),
      true_and_iff]
@[simp]
theorem mem_divisorsAntidiagonal {x : ℕ × ℕ} :
    x ∈ divisorsAntidiagonal n ↔ x.fst * x.snd = n ∧ n ≠ 0 := by
  simp only [divisorsAntidiagonal, Finset.mem_Ico, Ne.def, Finset.mem_filter, Finset.mem_product]
  rw [and_comm]
  apply and_congr_right
  rintro rfl
  constructor <;> intro h
  · contrapose! h
    simp [h]
  · rw [Nat.lt_add_one_iff, Nat.lt_add_one_iff]
    rw [mul_eq_zero, not_or] at h
    simp only [succ_le_of_lt (Nat.pos_of_ne_zero h.1), succ_le_of_lt (Nat.pos_of_ne_zero h.2),
      true_and_iff]
    

Proof state:
case h.mpr
x : ℕ × ℕ
h : ¬x.1 = 0 ∧ ¬x.2 = 0
⊢ x.1 ≤ x.1 * x.2 ∧ x.2 ≤ x.1 * x.2

Next tactic:
exact
      ⟨le_mul_of_pos_right (Nat.pos_of_ne_zero h.2), le_mul_of_pos_left (Nat.pos_of_ne_zero h.1)⟩
theorem divisor_le {m : ℕ} : n ∈ divisors m → n ≤ m := by
  

Proof state:
n m : ℕ
⊢ n ∈ divisors m → n ≤ m

Next tactic:
cases' m with m
theorem divisor_le {m : ℕ} : n ∈ divisors m → n ≤ m := by
  cases' m with m
  · 

Proof state:
case zero
n : ℕ
⊢ n ∈ divisors zero → n ≤ zero

Next tactic:
simp
theorem divisor_le {m : ℕ} : n ∈ divisors m → n ≤ m := by
  cases' m with m
  · simp
  · 

Proof state:
case succ
n m : ℕ
⊢ n ∈ divisors (succ m) → n ≤ succ m

Next tactic:
simp only [mem_divisors, Nat.succ_ne_zero m, and_true_iff, Ne.def, not_false_iff]
theorem divisor_le {m : ℕ} : n ∈ divisors m → n ≤ m := by
  cases' m with m
  · simp
  · simp only [mem_divisors, Nat.succ_ne_zero m, and_true_iff, Ne.def, not_false_iff]
    

Proof state:
case succ
n m : ℕ
⊢ n ∣ succ m → n ≤ succ m

Next tactic:
exact Nat.le_of_dvd (Nat.succ_pos m)
theorem divisors_subset_properDivisors {m : ℕ} (hzero : n ≠ 0) (h : m ∣ n) (hdiff : m ≠ n) :
    divisors m ⊆ properDivisors n := by
  

Proof state:
n m : ℕ
hzero : n ≠ 0
h : m ∣ n
hdiff : m ≠ n
⊢ divisors m ⊆ properDivisors n

Next tactic:
apply Finset.subset_iff.2
theorem divisors_subset_properDivisors {m : ℕ} (hzero : n ≠ 0) (h : m ∣ n) (hdiff : m ≠ n) :
    divisors m ⊆ properDivisors n := by
  apply Finset.subset_iff.2
  

Proof state:
n m : ℕ
hzero : n ≠ 0
h : m ∣ n
hdiff : m ≠ n
⊢ ∀ ⦃x : ℕ⦄, x ∈ divisors m → x ∈ properDivisors n

Next tactic:
intro x hx
theorem divisors_subset_properDivisors {m : ℕ} (hzero : n ≠ 0) (h : m ∣ n) (hdiff : m ≠ n) :
    divisors m ⊆ properDivisors n := by
  apply Finset.subset_iff.2
  intro x hx
  

Proof state:
n m : ℕ
hzero : n ≠ 0
h : m ∣ n
hdiff : m ≠ n
x : ℕ
hx : x ∈ divisors m
⊢ x ∈ properDivisors n

Next tactic:
exact
    Nat.mem_properDivisors.2
      ⟨(Nat.mem_divisors.1 hx).1.trans h,
        lt_of_le_of_lt (divisor_le hx)
          (lt_of_le_of_ne (divisor_le (Nat.mem_divisors.2 ⟨h, hzero⟩)) hdiff)⟩
lemma divisors_filter_dvd_of_dvd {n m : ℕ} (hn : n ≠ 0) (hm : m ∣ n) :
    (n.divisors.filter (· ∣ m)) = m.divisors := by
  

Proof state:
n✝ n m : ℕ
hn : n ≠ 0
hm : m ∣ n
⊢ filter (fun x => x ∣ m) (divisors n) = divisors m

Next tactic:
ext k
lemma divisors_filter_dvd_of_dvd {n m : ℕ} (hn : n ≠ 0) (hm : m ∣ n) :
    (n.divisors.filter (· ∣ m)) = m.divisors := by
  ext k
  

Proof state:
case a
n✝ n m : ℕ
hn : n ≠ 0
hm : m ∣ n
k : ℕ
⊢ k ∈ filter (fun x => x ∣ m) (divisors n) ↔ k ∈ divisors m

Next tactic:
simp_rw [mem_filter, mem_divisors]
lemma divisors_filter_dvd_of_dvd {n m : ℕ} (hn : n ≠ 0) (hm : m ∣ n) :
    (n.divisors.filter (· ∣ m)) = m.divisors := by
  ext k
  simp_rw [mem_filter, mem_divisors]
  

Proof state:
case a
n✝ n m : ℕ
hn : n ≠ 0
hm : m ∣ n
k : ℕ
⊢ (k ∣ n ∧ n ≠ 0) ∧ k ∣ m ↔ k ∣ m ∧ m ≠ 0

Next tactic:
exact ⟨fun ⟨_, hkm⟩ ↦ ⟨hkm, ne_zero_of_dvd_ne_zero hn hm⟩, fun ⟨hk, _⟩ ↦ ⟨⟨hk.trans hm, hn⟩, hk⟩⟩
@[simp]
theorem divisors_zero : divisors 0 = ∅ := by
  

Proof state:
n : ℕ
⊢ divisors 0 = ∅

Next tactic:
ext
@[simp]
theorem divisors_zero : divisors 0 = ∅ := by
  ext
  

Proof state:
case a
n a✝ : ℕ
⊢ a✝ ∈ divisors 0 ↔ a✝ ∈ ∅

Next tactic:
simp
@[simp]
theorem properDivisors_zero : properDivisors 0 = ∅ := by
  

Proof state:
n : ℕ
⊢ properDivisors 0 = ∅

Next tactic:
ext
@[simp]
theorem properDivisors_zero : properDivisors 0 = ∅ := by
  ext
  

Proof state:
case a
n a✝ : ℕ
⊢ a✝ ∈ properDivisors 0 ↔ a✝ ∈ ∅

Next tactic:
simp
@[simp]
theorem divisors_one : divisors 1 = {1} := by
  

Proof state:
n : ℕ
⊢ divisors 1 = {1}

Next tactic:
ext
@[simp]
theorem divisors_one : divisors 1 = {1} := by
  ext
  

Proof state:
case a
n a✝ : ℕ
⊢ a✝ ∈ divisors 1 ↔ a✝ ∈ {1}

Next tactic:
simp
@[simp]
theorem properDivisors_one : properDivisors 1 = ∅ := by 

Proof state:
n : ℕ
⊢ properDivisors 1 = ∅

Next tactic:
rw [properDivisors, Ico_self, filter_empty]
theorem pos_of_mem_divisors {m : ℕ} (h : m ∈ n.divisors) : 0 < m := by
  

Proof state:
n m : ℕ
h : m ∈ divisors n
⊢ 0 < m

Next tactic:
cases m
theorem pos_of_mem_divisors {m : ℕ} (h : m ∈ n.divisors) : 0 < m := by
  cases m
  · 

Proof state:
case zero
n : ℕ
h : zero ∈ divisors n
⊢ 0 < zero

Next tactic:
rw [mem_divisors, zero_eq, zero_dvd_iff (a := n)] at h
theorem pos_of_mem_divisors {m : ℕ} (h : m ∈ n.divisors) : 0 < m := by
  cases m
  · rw [mem_divisors, zero_eq, zero_dvd_iff (a := n)] at h
    

Proof state:
case zero
n : ℕ
h : n = 0 ∧ n ≠ 0
⊢ 0 < zero

Next tactic:
cases h.2 h.1
theorem pos_of_mem_divisors {m : ℕ} (h : m ∈ n.divisors) : 0 < m := by
  cases m
  · rw [mem_divisors, zero_eq, zero_dvd_iff (a := n)] at h
    cases h.2 h.1
  

Proof state:
case succ
n n✝ : ℕ
h : succ n✝ ∈ divisors n
⊢ 0 < succ n✝

Next tactic:
apply Nat.succ_pos
theorem one_mem_properDivisors_iff_one_lt : 1 ∈ n.properDivisors ↔ 1 < n := by
  

Proof state:
n : ℕ
⊢ 1 ∈ properDivisors n ↔ 1 < n

Next tactic:
rw [mem_properDivisors, and_iff_right (one_dvd _)]
@[simp]
lemma sup_divisors_id (n : ℕ) : n.divisors.sup id = n := by
  

Proof state:
n✝ n : ℕ
⊢ sup (divisors n) id = n

Next tactic:
refine le_antisymm (Finset.sup_le fun _ ↦ divisor_le) ?_
@[simp]
lemma sup_divisors_id (n : ℕ) : n.divisors.sup id = n := by
  refine le_antisymm (Finset.sup_le fun _ ↦ divisor_le) ?_
  

Proof state:
n✝ n : ℕ
⊢ n ≤ sup (divisors n) id

Next tactic:
rcases Decidable.eq_or_ne n 0 with rfl | hn
@[simp]
lemma sup_divisors_id (n : ℕ) : n.divisors.sup id = n := by
  refine le_antisymm (Finset.sup_le fun _ ↦ divisor_le) ?_
  rcases Decidable.eq_or_ne n 0 with rfl | hn
  · 

Proof state:
case inl
n : ℕ
⊢ 0 ≤ sup (divisors 0) id

Next tactic:
apply zero_le
@[simp]
lemma sup_divisors_id (n : ℕ) : n.divisors.sup id = n := by
  refine le_antisymm (Finset.sup_le fun _ ↦ divisor_le) ?_
  rcases Decidable.eq_or_ne n 0 with rfl | hn
  · apply zero_le
  · 

Proof state:
case inr
n✝ n : ℕ
hn : n ≠ 0
⊢ n ≤ sup (divisors n) id

Next tactic:
exact Finset.le_sup (f := id) <| mem_divisors_self n hn
@[simp]
theorem divisorsAntidiagonal_zero : divisorsAntidiagonal 0 = ∅ := by
  

Proof state:
n : ℕ
⊢ divisorsAntidiagonal 0 = ∅

Next tactic:
ext
@[simp]
theorem divisorsAntidiagonal_zero : divisorsAntidiagonal 0 = ∅ := by
  ext
  

Proof state:
case a
n : ℕ
a✝ : ℕ × ℕ
⊢ a✝ ∈ divisorsAntidiagonal 0 ↔ a✝ ∈ ∅

Next tactic:
simp
@[simp]
theorem divisorsAntidiagonal_one : divisorsAntidiagonal 1 = {(1, 1)} := by
  

Proof state:
n : ℕ
⊢ divisorsAntidiagonal 1 = {(1, 1)}

Next tactic:
ext
@[simp]
theorem divisorsAntidiagonal_one : divisorsAntidiagonal 1 = {(1, 1)} := by
  ext
  

Proof state:
case a
n : ℕ
a✝ : ℕ × ℕ
⊢ a✝ ∈ divisorsAntidiagonal 1 ↔ a✝ ∈ {(1, 1)}

Next tactic:
simp [mul_eq_one, Prod.ext_iff]
theorem swap_mem_divisorsAntidiagonal {x : ℕ × ℕ} :
    x.swap ∈ divisorsAntidiagonal n ↔ x ∈ divisorsAntidiagonal n := by
  

Proof state:
n : ℕ
x : ℕ × ℕ
⊢ Prod.swap x ∈ divisorsAntidiagonal n ↔ x ∈ divisorsAntidiagonal n

Next tactic:
rw [mem_divisorsAntidiagonal, mem_divisorsAntidiagonal, mul_comm, Prod.swap]
@[simp]
theorem swap_mem_divisorsAntidiagonal_aux {x : ℕ × ℕ} :
    x.snd * x.fst = n ∧ ¬n = 0 ↔ x ∈ divisorsAntidiagonal n := by
  

Proof state:
n : ℕ
x : ℕ × ℕ
⊢ x.2 * x.1 = n ∧ ¬n = 0 ↔ x ∈ divisorsAntidiagonal n

Next tactic:
rw [mem_divisorsAntidiagonal, mul_comm]
theorem fst_mem_divisors_of_mem_antidiagonal {x : ℕ × ℕ} (h : x ∈ divisorsAntidiagonal n) :
    x.fst ∈ divisors n := by
  

Proof state:
n : ℕ
x : ℕ × ℕ
h : x ∈ divisorsAntidiagonal n
⊢ x.1 ∈ divisors n

Next tactic:
rw [mem_divisorsAntidiagonal] at h
theorem fst_mem_divisors_of_mem_antidiagonal {x : ℕ × ℕ} (h : x ∈ divisorsAntidiagonal n) :
    x.fst ∈ divisors n := by
  rw [mem_divisorsAntidiagonal] at h
  

Proof state:
n : ℕ
x : ℕ × ℕ
h : x.1 * x.2 = n ∧ n ≠ 0
⊢ x.1 ∈ divisors n

Next tactic:
simp [Dvd.intro _ h.1, h.2]
theorem snd_mem_divisors_of_mem_antidiagonal {x : ℕ × ℕ} (h : x ∈ divisorsAntidiagonal n) :
    x.snd ∈ divisors n := by
  

Proof state:
n : ℕ
x : ℕ × ℕ
h : x ∈ divisorsAntidiagonal n
⊢ x.2 ∈ divisors n

Next tactic:
rw [mem_divisorsAntidiagonal] at h
theorem snd_mem_divisors_of_mem_antidiagonal {x : ℕ × ℕ} (h : x ∈ divisorsAntidiagonal n) :
    x.snd ∈ divisors n := by
  rw [mem_divisorsAntidiagonal] at h
  

Proof state:
n : ℕ
x : ℕ × ℕ
h : x.1 * x.2 = n ∧ n ≠ 0
⊢ x.2 ∈ divisors n

Next tactic:
simp [Dvd.intro_left _ h.1, h.2]
@[simp]
theorem map_swap_divisorsAntidiagonal :
    (divisorsAntidiagonal n).map (Equiv.prodComm _ _).toEmbedding = divisorsAntidiagonal n := by
  

Proof state:
n : ℕ
⊢ map (Equiv.toEmbedding (Equiv.prodComm ℕ ℕ)) (divisorsAntidiagonal n) = divisorsAntidiagonal n

Next tactic:
rw [← coe_inj, coe_map, Equiv.coe_toEmbedding, Equiv.coe_prodComm,
    Set.image_swap_eq_preimage_swap]
@[simp]
theorem map_swap_divisorsAntidiagonal :
    (divisorsAntidiagonal n).map (Equiv.prodComm _ _).toEmbedding = divisorsAntidiagonal n := by
  rw [← coe_inj, coe_map, Equiv.coe_toEmbedding, Equiv.coe_prodComm,
    Set.image_swap_eq_preimage_swap]
  

Proof state:
n : ℕ
⊢ Prod.swap ⁻¹' ↑(divisorsAntidiagonal n) = ↑(divisorsAntidiagonal n)

Next tactic:
ext
@[simp]
theorem map_swap_divisorsAntidiagonal :
    (divisorsAntidiagonal n).map (Equiv.prodComm _ _).toEmbedding = divisorsAntidiagonal n := by
  rw [← coe_inj, coe_map, Equiv.coe_toEmbedding, Equiv.coe_prodComm,
    Set.image_swap_eq_preimage_swap]
  ext
  

Proof state:
case h
n : ℕ
x✝ : ℕ × ℕ
⊢ x✝ ∈ Prod.swap ⁻¹' ↑(divisorsAntidiagonal n) ↔ x✝ ∈ ↑(divisorsAntidiagonal n)

Next tactic:
exact swap_mem_divisorsAntidiagonal
@[simp]
theorem image_fst_divisorsAntidiagonal : (divisorsAntidiagonal n).image Prod.fst = divisors n := by
  

Proof state:
n : ℕ
⊢ image Prod.fst (divisorsAntidiagonal n) = divisors n

Next tactic:
ext
@[simp]
theorem image_fst_divisorsAntidiagonal : (divisorsAntidiagonal n).image Prod.fst = divisors n := by
  ext
  

Proof state:
case a
n a✝ : ℕ
⊢ a✝ ∈ image Prod.fst (divisorsAntidiagonal n) ↔ a✝ ∈ divisors n

Next tactic:
simp [Dvd.dvd, @eq_comm _ n (_ * _)]
@[simp]
theorem image_snd_divisorsAntidiagonal : (divisorsAntidiagonal n).image Prod.snd = divisors n := by
  

Proof state:
n : ℕ
⊢ image Prod.snd (divisorsAntidiagonal n) = divisors n

Next tactic:
rw [← map_swap_divisorsAntidiagonal, map_eq_image, image_image]
@[simp]
theorem image_snd_divisorsAntidiagonal : (divisorsAntidiagonal n).image Prod.snd = divisors n := by
  rw [← map_swap_divisorsAntidiagonal, map_eq_image, image_image]
  

Proof state:
n : ℕ
⊢ image (Prod.snd ∘ ⇑(Equiv.toEmbedding (Equiv.prodComm ℕ ℕ))) (divisorsAntidiagonal n) = divisors n

Next tactic:
exact image_fst_divisorsAntidiagonal
theorem map_div_right_divisors :
    n.divisors.map ⟨fun d => (d, n / d), fun p₁ p₂ => congr_arg Prod.fst⟩ =
      n.divisorsAntidiagonal := by
  

Proof state:
n : ℕ
⊢ map
      { 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) }
      (divisors n) =
    divisorsAntidiagonal n

Next tactic:
ext ⟨d, nd⟩
theorem map_div_right_divisors :
    n.divisors.map ⟨fun d => (d, n / d), fun p₁ p₂ => congr_arg Prod.fst⟩ =
      n.divisorsAntidiagonal := by
  ext ⟨d, nd⟩
  

Proof state:
case a.mk
n d nd : ℕ
⊢ (d, nd) ∈
      map
        { 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) }
        (divisors n) ↔
    (d, nd) ∈ divisorsAntidiagonal n

Next tactic:
simp only [mem_map, mem_divisorsAntidiagonal, Function.Embedding.coeFn_mk, mem_divisors,
    Prod.ext_iff, exists_prop, and_left_comm, exists_eq_left]
theorem map_div_right_divisors :
    n.divisors.map ⟨fun d => (d, n / d), fun p₁ p₂ => congr_arg Prod.fst⟩ =
      n.divisorsAntidiagonal := by
  ext ⟨d, nd⟩
  simp only [mem_map, mem_divisorsAntidiagonal, Function.Embedding.coeFn_mk, mem_divisors,
    Prod.ext_iff, exists_prop, and_left_comm, exists_eq_left]
  

Proof state:
case a.mk
n d nd : ℕ
⊢ (d ∣ n ∧ n ≠ 0) ∧ n / d = nd ↔ d * nd = n ∧ n ≠ 0

Next tactic:
constructor
theorem map_div_right_divisors :
    n.divisors.map ⟨fun d => (d, n / d), fun p₁ p₂ => congr_arg Prod.fst⟩ =
      n.divisorsAntidiagonal := by
  ext ⟨d, nd⟩
  simp only [mem_map, mem_divisorsAntidiagonal, Function.Embedding.coeFn_mk, mem_divisors,
    Prod.ext_iff, exists_prop, and_left_comm, exists_eq_left]
  constructor
  · 

Proof state:
case a.mk.mp
n d nd : ℕ
⊢ (d ∣ n ∧ n ≠ 0) ∧ n / d = nd → d * nd = n ∧ n ≠ 0

Next tactic:
rintro ⟨⟨⟨k, rfl⟩, hn⟩, rfl⟩
theorem map_div_right_divisors :
    n.divisors.map ⟨fun d => (d, n / d), fun p₁ p₂ => congr_arg Prod.fst⟩ =
      n.divisorsAntidiagonal := by
  ext ⟨d, nd⟩
  simp only [mem_map, mem_divisorsAntidiagonal, Function.Embedding.coeFn_mk, mem_divisors,
    Prod.ext_iff, exists_prop, and_left_comm, exists_eq_left]
  constructor
  · rintro ⟨⟨⟨k, rfl⟩, hn⟩, rfl⟩
    

Proof state:
case a.mk.mp.intro.intro.intro
d k : ℕ
hn : d * k ≠ 0
⊢ d * (d * k / d) = d * k ∧ d * k ≠ 0

Next tactic:
rw [Nat.mul_div_cancel_left _ (left_ne_zero_of_mul hn).bot_lt]
theorem map_div_right_divisors :
    n.divisors.map ⟨fun d => (d, n / d), fun p₁ p₂ => congr_arg Prod.fst⟩ =
      n.divisorsAntidiagonal := by
  ext ⟨d, nd⟩
  simp only [mem_map, mem_divisorsAntidiagonal, Function.Embedding.coeFn_mk, mem_divisors,
    Prod.ext_iff, exists_prop, and_left_comm, exists_eq_left]
  constructor
  · rintro ⟨⟨⟨k, rfl⟩, hn⟩, rfl⟩
    rw [Nat.mul_div_cancel_left _ (left_ne_zero_of_mul hn).bot_lt]
    

Proof state:
case a.mk.mp.intro.intro.intro
d k : ℕ
hn : d * k ≠ 0
⊢ d * k = d * k ∧ d * k ≠ 0

Next tactic:
exact ⟨rfl, hn⟩
theorem map_div_right_divisors :
    n.divisors.map ⟨fun d => (d, n / d), fun p₁ p₂ => congr_arg Prod.fst⟩ =
      n.divisorsAntidiagonal := by
  ext ⟨d, nd⟩
  simp only [mem_map, mem_divisorsAntidiagonal, Function.Embedding.coeFn_mk, mem_divisors,
    Prod.ext_iff, exists_prop, and_left_comm, exists_eq_left]
  constructor
  · rintro ⟨⟨⟨k, rfl⟩, hn⟩, rfl⟩
    rw [Nat.mul_div_cancel_left _ (left_ne_zero_of_mul hn).bot_lt]
    exact ⟨rfl, hn⟩
  · 

Proof state:
case a.mk.mpr
n d nd : ℕ
⊢ d * nd = n ∧ n ≠ 0 → (d ∣ n ∧ n ≠ 0) ∧ n / d = nd

Next tactic:
rintro ⟨rfl, hn⟩
theorem map_div_right_divisors :
    n.divisors.map ⟨fun d => (d, n / d), fun p₁ p₂ => congr_arg Prod.fst⟩ =
      n.divisorsAntidiagonal := by
  ext ⟨d, nd⟩
  simp only [mem_map, mem_divisorsAntidiagonal, Function.Embedding.coeFn_mk, mem_divisors,
    Prod.ext_iff, exists_prop, and_left_comm, exists_eq_left]
  constructor
  · rintro ⟨⟨⟨k, rfl⟩, hn⟩, rfl⟩
    rw [Nat.mul_div_cancel_left _ (left_ne_zero_of_mul hn).bot_lt]
    exact ⟨rfl, hn⟩
  · rintro ⟨rfl, hn⟩
    

Proof state:
case a.mk.mpr.intro
d nd : ℕ
hn : d * nd ≠ 0
⊢ (d ∣ d * nd ∧ d * nd ≠ 0) ∧ d * nd / d = nd

Next tactic:
exact ⟨⟨dvd_mul_right _ _, hn⟩, Nat.mul_div_cancel_left _ (left_ne_zero_of_mul hn).bot_lt⟩
theorem map_div_left_divisors :
    n.divisors.map ⟨fun d => (n / d, d), fun p₁ p₂ => congr_arg Prod.snd⟩ =
      n.divisorsAntidiagonal := by
  

Proof state:
n : ℕ
⊢ map
      { toFun := fun d => (n / d, d),
        inj' :=
          (_ :
            ∀ (p₁ p₂ : ℕ),
              (fun d => (n / d, d)) p₁ = (fun d => (n / d, d)) p₂ →
                ((fun d => (n / d, d)) p₁).2 = ((fun d => (n / d, d)) p₂).2) }
      (divisors n) =
    divisorsAntidiagonal n

Next tactic:
apply Finset.map_injective (Equiv.prodComm _ _).toEmbedding
theorem map_div_left_divisors :
    n.divisors.map ⟨fun d => (n / d, d), fun p₁ p₂ => congr_arg Prod.snd⟩ =
      n.divisorsAntidiagonal := by
  apply Finset.map_injective (Equiv.prodComm _ _).toEmbedding
  

Proof state:
case a
n : ℕ
⊢ map (Equiv.toEmbedding (Equiv.prodComm ℕ ℕ))
      (map
        { toFun := fun d => (n / d, d),
          inj' :=
            (_ :
              ∀ (p₁ p₂ : ℕ),
                (fun d => (n / d, d)) p₁ = (fun d => (n / d, d)) p₂ →
                  ((fun d => (n / d, d)) p₁).2 = ((fun d => (n / d, d)) p₂).2) }
        (divisors n)) =
    map (Equiv.toEmbedding (Equiv.prodComm ℕ ℕ)) (divisorsAntidiagonal n)

Next tactic:
ext
theorem map_div_left_divisors :
    n.divisors.map ⟨fun d => (n / d, d), fun p₁ p₂ => congr_arg Prod.snd⟩ =
      n.divisorsAntidiagonal := by
  apply Finset.map_injective (Equiv.prodComm _ _).toEmbedding
  ext
  

Proof state:
case a.a
n : ℕ
a✝ : ℕ × ℕ
⊢ a✝ ∈
      map (Equiv.toEmbedding (Equiv.prodComm ℕ ℕ))
        (map
          { toFun := fun d => (n / d, d),
            inj' :=
              (_ :
                ∀ (p₁ p₂ : ℕ),
                  (fun d => (n / d, d)) p₁ = (fun d => (n / d, d)) p₂ →
                    ((fun d => (n / d, d)) p₁).2 = ((fun d => (n / d, d)) p₂).2) }
          (divisors n)) ↔
    a✝ ∈ map (Equiv.toEmbedding (Equiv.prodComm ℕ ℕ)) (divisorsAntidiagonal n)

Next tactic:
rw [map_swap_divisorsAntidiagonal, ← map_div_right_divisors, Finset.map_map]
theorem map_div_left_divisors :
    n.divisors.map ⟨fun d => (n / d, d), fun p₁ p₂ => congr_arg Prod.snd⟩ =
      n.divisorsAntidiagonal := by
  apply Finset.map_injective (Equiv.prodComm _ _).toEmbedding
  ext
  rw [map_swap_divisorsAntidiagonal, ← map_div_right_divisors, Finset.map_map]
  

Proof state:
case a.a
n : ℕ
a✝ : ℕ × ℕ
⊢ a✝ ∈
      map
        (Function.Embedding.trans
          { toFun := fun d => (n / d, d),
            inj' :=
              (_ :
                ∀ (p₁ p₂ : ℕ),
                  (fun d => (n / d, d)) p₁ = (fun d => (n / d, d)) p₂ →
                    ((fun d => (n / d, d)) p₁).2 = ((fun d => (n / d, d)) p₂).2) }
          (Equiv.toEmbedding (Equiv.prodComm ℕ ℕ)))
        (divisors n) ↔
    a✝ ∈
      map
        { 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) }
        (divisors n)

Next tactic:
simp
theorem sum_divisors_eq_sum_properDivisors_add_self :
    ∑ i in divisors n, i = (∑ i in properDivisors n, i) + n := by
  

Proof state:
n : ℕ
⊢ ∑ i in divisors n, i = ∑ i in properDivisors n, i + n

Next tactic:
rcases Decidable.eq_or_ne n 0 with (rfl | hn)
theorem sum_divisors_eq_sum_properDivisors_add_self :
    ∑ i in divisors n, i = (∑ i in properDivisors n, i) + n := by
  rcases Decidable.eq_or_ne n 0 with (rfl | hn)
  · 

Proof state:
case inl
⊢ ∑ i in divisors 0, i = ∑ i in properDivisors 0, i + 0

Next tactic:
simp
theorem sum_divisors_eq_sum_properDivisors_add_self :
    ∑ i in divisors n, i = (∑ i in properDivisors n, i) + n := by
  rcases Decidable.eq_or_ne n 0 with (rfl | hn)
  · simp
  · 

Proof state:
case inr
n : ℕ
hn : n ≠ 0
⊢ ∑ i in divisors n, i = ∑ i in properDivisors n, i + n

Next tactic:
rw [← cons_self_properDivisors hn, Finset.sum_cons, add_comm]
theorem perfect_iff_sum_divisors_eq_two_mul (h : 0 < n) :
    Perfect n ↔ ∑ i in divisors n, i = 2 * n := by
  

Proof state:
n : ℕ
h : 0 < n
⊢ Perfect n ↔ ∑ i in divisors n, i = 2 * n

Next tactic:
rw [perfect_iff_sum_properDivisors h, sum_divisors_eq_sum_properDivisors_add_self, two_mul]
theorem perfect_iff_sum_divisors_eq_two_mul (h : 0 < n) :
    Perfect n ↔ ∑ i in divisors n, i = 2 * n := by
  rw [perfect_iff_sum_properDivisors h, sum_divisors_eq_sum_properDivisors_add_self, two_mul]
  

Proof state:
n : ℕ
h : 0 < n
⊢ ∑ i in properDivisors n, i = n ↔ ∑ i in properDivisors n, i + n = n + n

Next tactic:
constructor
theorem perfect_iff_sum_divisors_eq_two_mul (h : 0 < n) :
    Perfect n ↔ ∑ i in divisors n, i = 2 * n := by
  rw [perfect_iff_sum_properDivisors h, sum_divisors_eq_sum_properDivisors_add_self, two_mul]
  constructor <;> 

Proof state:
case mp
n : ℕ
h : 0 < n
⊢ ∑ i in properDivisors n, i = n → ∑ i in properDivisors n, i + n = n + n

Next tactic:
intro h
theorem perfect_iff_sum_divisors_eq_two_mul (h : 0 < n) :
    Perfect n ↔ ∑ i in divisors n, i = 2 * n := by
  rw [perfect_iff_sum_properDivisors h, sum_divisors_eq_sum_properDivisors_add_self, two_mul]
  constructor <;> 

Proof state:
case mpr
n : ℕ
h : 0 < n
⊢ ∑ i in properDivisors n, i + n = n + n → ∑ i in properDivisors n, i = n

Next tactic:
intro h
theorem perfect_iff_sum_divisors_eq_two_mul (h : 0 < n) :
    Perfect n ↔ ∑ i in divisors n, i = 2 * n := by
  rw [perfect_iff_sum_properDivisors h, sum_divisors_eq_sum_properDivisors_add_self, two_mul]
  constructor <;> intro h
  · 

Proof state:
case mp
n : ℕ
h✝ : 0 < n
h : ∑ i in properDivisors n, i = n
⊢ ∑ i in properDivisors n, i + n = n + n

Next tactic:
rw [h]
theorem perfect_iff_sum_divisors_eq_two_mul (h : 0 < n) :
    Perfect n ↔ ∑ i in divisors n, i = 2 * n := by
  rw [perfect_iff_sum_properDivisors h, sum_divisors_eq_sum_properDivisors_add_self, two_mul]
  constructor <;> intro h
  · rw [h]
  · 

Proof state:
case mpr
n : ℕ
h✝ : 0 < n
h : ∑ i in properDivisors n, i + n = n + n
⊢ ∑ i in properDivisors n, i = n

Next tactic:
apply add_right_cancel h
theorem mem_divisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) {x : ℕ} :
    x ∈ divisors (p ^ k) ↔ ∃ j ≤ k, x = p ^ j := by
  

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

Next tactic:
rw [mem_divisors, Nat.dvd_prime_pow pp, and_iff_left (ne_of_gt (pow_pos pp.pos k))]
theorem Prime.divisors {p : ℕ} (pp : p.Prime) : divisors p = {1, p} := by
  

Proof state:
n p : ℕ
pp : Prime p
⊢ Nat.divisors p = {1, p}

Next tactic:
ext
theorem Prime.divisors {p : ℕ} (pp : p.Prime) : divisors p = {1, p} := by
  ext
  

Proof state:
case a
n p : ℕ
pp : Prime p
a✝ : ℕ
⊢ a✝ ∈ Nat.divisors p ↔ a✝ ∈ {1, p}

Next tactic:
rw [mem_divisors, dvd_prime pp, and_iff_left pp.ne_zero, Finset.mem_insert, Finset.mem_singleton]
theorem Prime.properDivisors {p : ℕ} (pp : p.Prime) : properDivisors p = {1} := by
  

Proof state:
n p : ℕ
pp : Prime p
⊢ Nat.properDivisors p = {1}

Next tactic:
rw [← erase_insert properDivisors.not_self_mem, insert_self_properDivisors pp.ne_zero,
    pp.divisors, pair_comm, erase_insert fun con => pp.ne_one (mem_singleton.1 con)]
theorem divisors_prime_pow {p : ℕ} (pp : p.Prime) (k : ℕ) :
    divisors (p ^ k) = (Finset.range (k + 1)).map ⟨(p ^ ·), Nat.pow_right_injective pp.two_le⟩ := by
  

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

Next tactic:
ext a