l3lab/ntp-mathlib huggingface dataset:
theorem minFacAux_has_prop {n : ℕ} (n2 : 2 ≤ n) :
    ∀ k i, k = 2 * i + 3 → (∀ m, 2 ≤ m → m ∣ n → k ≤ m) → minFacProp n (minFacAux n k)
  | k => fun i e a => by
    rw [minFacAux]
    by_cases h : n < k * k <;> simp [h]
    · have pp : Prime n :=
        prime_def_le_sqrt.2
          ⟨n2, fun m m2 l d => not_lt_of_ge l <| lt_of_lt_of_le (sqrt_lt.2 h) (a m m2 d)⟩
      exact ⟨n2, dvd_rfl, fun m m2 d => le_of_eq ((dvd_prime_two_le pp m2).1 d).symm⟩
    have k2 : 2 ≤ k := by
      subst e
      apply Nat.le_add_left
    by_cases dk : k ∣ n <;> simp [dk]
    · exact ⟨k2, dk, a⟩
    · refine'
        have := minFac_lemma n k h
        minFacAux_has_prop n2 (k + 2) (i + 1) (by simp [e, left_distrib]) fun m m2 d => _
      rcases Nat.eq_or_lt_of_le (a m m2 d) with me | ml
      · subst me
        contradiction
      apply (Nat.eq_or_lt_of_le ml).resolve_left
      intro me
      rw [← me, e] at d
      have d' : 2 * (i + 2) ∣ n := d
      have := a _ le_rfl (dvd_of_mul_right_dvd d')
      rw [e] at this
      exact absurd this (by 

Proof state:
n : ℕ
n2 : 2 ≤ n
x✝ : ℕ
k : ℕ := x✝
i : ℕ
e : x✝ = 2 * i + 3
a : ∀ (m : ℕ), 2 ≤ m → m ∣ n → x✝ ≤ m
h : ¬n < k * k
k2 : 2 ≤ k
dk : ¬k ∣ n
this✝ : sqrt n - k < sqrt n + 2 - k
m : ℕ
m2 : 2 ≤ m
d : succ (2 * i + 3) ∣ n
ml : x✝ < m
me : succ x✝ = m
d' : 2 * (i + 2) ∣ n
this : 2 * i + 3 ≤ 2
⊢ ¬2 * i + 3 ≤ 2

Next tactic:
contradiction
theorem minFac_has_prop {n : ℕ} (n1 : n ≠ 1) : minFacProp n (minFac n) := by
  

Proof state:
n : ℕ
n1 : n ≠ 1
⊢ Nat.minFacProp n (minFac n)

Next tactic:
by_cases n0 : n = 0
theorem minFac_has_prop {n : ℕ} (n1 : n ≠ 1) : minFacProp n (minFac n) := by
  by_cases n0 : n = 0
  · 

Proof state:
case pos
n : ℕ
n1 : n ≠ 1
n0 : n = 0
⊢ Nat.minFacProp n (minFac n)

Next tactic:
simp [n0, minFacProp, GE.ge]
theorem minFac_has_prop {n : ℕ} (n1 : n ≠ 1) : minFacProp n (minFac n) := by
  by_cases n0 : n = 0
  · simp [n0, minFacProp, GE.ge]
  

Proof state:
case neg
n : ℕ
n1 : n ≠ 1
n0 : ¬n = 0
⊢ Nat.minFacProp n (minFac n)

Next tactic:
have n2 : 2 ≤ n := by
    revert n0 n1
    rcases n with (_ | _ | _) <;> simp [succ_le_succ]
theorem minFac_has_prop {n : ℕ} (n1 : n ≠ 1) : minFacProp n (minFac n) := by
  by_cases n0 : n = 0
  · simp [n0, minFacProp, GE.ge]
  have n2 : 2 ≤ n := by
    

Proof state:
n : ℕ
n1 : n ≠ 1
n0 : ¬n = 0
⊢ 2 ≤ n

Next tactic:
revert n0 n1
theorem minFac_has_prop {n : ℕ} (n1 : n ≠ 1) : minFacProp n (minFac n) := by
  by_cases n0 : n = 0
  · simp [n0, minFacProp, GE.ge]
  have n2 : 2 ≤ n := by
    revert n0 n1
    

Proof state:
n : ℕ
⊢ n ≠ 1 → ¬n = 0 → 2 ≤ n

Next tactic:
rcases n with (_ | _ | _)
theorem minFac_has_prop {n : ℕ} (n1 : n ≠ 1) : minFacProp n (minFac n) := by
  by_cases n0 : n = 0
  · simp [n0, minFacProp, GE.ge]
  have n2 : 2 ≤ n := by
    revert n0 n1
    rcases n with (_ | _ | _) <;> 

Proof state:
case zero
⊢ zero ≠ 1 → ¬zero = 0 → 2 ≤ zero

Next tactic:
simp [succ_le_succ]
theorem minFac_has_prop {n : ℕ} (n1 : n ≠ 1) : minFacProp n (minFac n) := by
  by_cases n0 : n = 0
  · simp [n0, minFacProp, GE.ge]
  have n2 : 2 ≤ n := by
    revert n0 n1
    rcases n with (_ | _ | _) <;> 

Proof state:
case succ.zero
⊢ succ zero ≠ 1 → ¬succ zero = 0 → 2 ≤ succ zero

Next tactic:
simp [succ_le_succ]
theorem minFac_has_prop {n : ℕ} (n1 : n ≠ 1) : minFacProp n (minFac n) := by
  by_cases n0 : n = 0
  · simp [n0, minFacProp, GE.ge]
  have n2 : 2 ≤ n := by
    revert n0 n1
    rcases n with (_ | _ | _) <;> 

Proof state:
case succ.succ
n✝ : ℕ
⊢ succ (succ n✝) ≠ 1 → ¬succ (succ n✝) = 0 → 2 ≤ succ (succ n✝)

Next tactic:
simp [succ_le_succ]
theorem minFac_has_prop {n : ℕ} (n1 : n ≠ 1) : minFacProp n (minFac n) := by
  by_cases n0 : n = 0
  · simp [n0, minFacProp, GE.ge]
  have n2 : 2 ≤ n := by
    revert n0 n1
    rcases n with (_ | _ | _) <;> simp [succ_le_succ]
  

Proof state:
case neg
n : ℕ
n1 : n ≠ 1
n0 : ¬n = 0
n2 : 2 ≤ n
⊢ Nat.minFacProp n (minFac n)

Next tactic:
simp only [minFac_eq, Nat.isUnit_iff]
theorem minFac_has_prop {n : ℕ} (n1 : n ≠ 1) : minFacProp n (minFac n) := by
  by_cases n0 : n = 0
  · simp [n0, minFacProp, GE.ge]
  have n2 : 2 ≤ n := by
    revert n0 n1
    rcases n with (_ | _ | _) <;> simp [succ_le_succ]
  simp only [minFac_eq, Nat.isUnit_iff]
  

Proof state:
case neg
n : ℕ
n1 : n ≠ 1
n0 : ¬n = 0
n2 : 2 ≤ n
⊢ Nat.minFacProp n (if 2 ∣ n then 2 else minFacAux n 3)

Next tactic:
by_cases d2 : 2 ∣ n
theorem minFac_has_prop {n : ℕ} (n1 : n ≠ 1) : minFacProp n (minFac n) := by
  by_cases n0 : n = 0
  · simp [n0, minFacProp, GE.ge]
  have n2 : 2 ≤ n := by
    revert n0 n1
    rcases n with (_ | _ | _) <;> simp [succ_le_succ]
  simp only [minFac_eq, Nat.isUnit_iff]
  by_cases d2 : 2 ∣ n <;> 

Proof state:
case pos
n : ℕ
n1 : n ≠ 1
n0 : ¬n = 0
n2 : 2 ≤ n
d2 : 2 ∣ n
⊢ Nat.minFacProp n (if 2 ∣ n then 2 else minFacAux n 3)

Next tactic:
simp [d2]
theorem minFac_has_prop {n : ℕ} (n1 : n ≠ 1) : minFacProp n (minFac n) := by
  by_cases n0 : n = 0
  · simp [n0, minFacProp, GE.ge]
  have n2 : 2 ≤ n := by
    revert n0 n1
    rcases n with (_ | _ | _) <;> simp [succ_le_succ]
  simp only [minFac_eq, Nat.isUnit_iff]
  by_cases d2 : 2 ∣ n <;> 

Proof state:
case neg
n : ℕ
n1 : n ≠ 1
n0 : ¬n = 0
n2 : 2 ≤ n
d2 : ¬2 ∣ n
⊢ Nat.minFacProp n (if 2 ∣ n then 2 else minFacAux n 3)

Next tactic:
simp [d2]
theorem minFac_has_prop {n : ℕ} (n1 : n ≠ 1) : minFacProp n (minFac n) := by
  by_cases n0 : n = 0
  · simp [n0, minFacProp, GE.ge]
  have n2 : 2 ≤ n := by
    revert n0 n1
    rcases n with (_ | _ | _) <;> simp [succ_le_succ]
  simp only [minFac_eq, Nat.isUnit_iff]
  by_cases d2 : 2 ∣ n <;> simp [d2]
  · 

Proof state:
case pos
n : ℕ
n1 : n ≠ 1
n0 : ¬n = 0
n2 : 2 ≤ n
d2 : 2 ∣ n
⊢ Nat.minFacProp n 2

Next tactic:
exact ⟨le_rfl, d2, fun k k2 _ => k2⟩
theorem minFac_has_prop {n : ℕ} (n1 : n ≠ 1) : minFacProp n (minFac n) := by
  by_cases n0 : n = 0
  · simp [n0, minFacProp, GE.ge]
  have n2 : 2 ≤ n := by
    revert n0 n1
    rcases n with (_ | _ | _) <;> simp [succ_le_succ]
  simp only [minFac_eq, Nat.isUnit_iff]
  by_cases d2 : 2 ∣ n <;> simp [d2]
  · exact ⟨le_rfl, d2, fun k k2 _ => k2⟩
  · 

Proof state:
case neg
n : ℕ
n1 : n ≠ 1
n0 : ¬n = 0
n2 : 2 ≤ n
d2 : ¬2 ∣ n
⊢ Nat.minFacProp n (minFacAux n 3)

Next tactic:
refine'
      minFacAux_has_prop n2 3 0 rfl fun m m2 d => (Nat.eq_or_lt_of_le m2).resolve_left (mt _ d2)
theorem minFac_has_prop {n : ℕ} (n1 : n ≠ 1) : minFacProp n (minFac n) := by
  by_cases n0 : n = 0
  · simp [n0, minFacProp, GE.ge]
  have n2 : 2 ≤ n := by
    revert n0 n1
    rcases n with (_ | _ | _) <;> simp [succ_le_succ]
  simp only [minFac_eq, Nat.isUnit_iff]
  by_cases d2 : 2 ∣ n <;> simp [d2]
  · exact ⟨le_rfl, d2, fun k k2 _ => k2⟩
  · refine'
      minFacAux_has_prop n2 3 0 rfl fun m m2 d => (Nat.eq_or_lt_of_le m2).resolve_left (mt _ d2)
    

Proof state:
case neg
n : ℕ
n1 : n ≠ 1
n0 : ¬n = 0
n2 : 2 ≤ n
d2 : ¬2 ∣ n
m : ℕ
m2 : 2 ≤ m
d : m ∣ n
⊢ 2 = m → 2 ∣ n

Next tactic:
exact fun e => e.symm ▸ d
theorem minFac_dvd (n : ℕ) : minFac n ∣ n :=
  if n1 : n = 1 then by 

Proof state:
n : ℕ
n1 : n = 1
⊢ minFac n ∣ n

Next tactic:
simp [n1]
theorem minFac_le_of_dvd {n : ℕ} : ∀ {m : ℕ}, 2 ≤ m → m ∣ n → minFac n ≤ m := by
  

Proof state:
n : ℕ
⊢ ∀ {m : ℕ}, 2 ≤ m → m ∣ n → minFac n ≤ m

Next tactic:
by_cases n1 : n = 1 <;> [exact fun m2 _ => n1.symm ▸ le_trans (by decide) m2;
    apply (minFac_has_prop n1).2.2]
theorem minFac_le_of_dvd {n : ℕ} : ∀ {m : ℕ}, 2 ≤ m → m ∣ n → minFac n ≤ m := by
  

Proof state:
n : ℕ
⊢ ∀ {m : ℕ}, 2 ≤ m → m ∣ n → minFac n ≤ m

Next tactic:
by_cases n1 : n = 1
theorem minFac_le_of_dvd {n : ℕ} : ∀ {m : ℕ}, 2 ≤ m → m ∣ n → minFac n ≤ m := by
  by_cases n1 : n = 1 <;> [

Proof state:
case pos
n m✝ : ℕ
n1 : n = 1
⊢ 2 ≤ m✝ → m✝ ∣ n → minFac n ≤ m✝

Next tactic:
exact fun m2 _ => n1.symm ▸ le_trans (by decide) m2
theorem minFac_le_of_dvd {n : ℕ} : ∀ {m : ℕ}, 2 ≤ m → m ∣ n → minFac n ≤ m := by
  by_cases n1 : n = 1 <;> [exact fun m2 _ => n1.symm ▸ le_trans (by 

Proof state:
n m✝ : ℕ
n1 : n = 1
m2 : 2 ≤ m✝
x✝ : m✝ ∣ n
⊢ minFac 1 ≤ 2

Next tactic:
decide
theorem minFac_le_of_dvd {n : ℕ} : ∀ {m : ℕ}, 2 ≤ m → m ∣ n → minFac n ≤ m := by
  by_cases n1 : n = 1 <;> [exact fun m2 _ => n1.symm ▸ le_trans (by decide) m2;
    

Proof state:
case neg
n m✝ : ℕ
n1 : ¬n = 1
⊢ 2 ≤ m✝ → m✝ ∣ n → minFac n ≤ m✝

Next tactic:
apply (minFac_has_prop n1).2.2
theorem minFac_pos (n : ℕ) : 0 < minFac n := by
  

Proof state:
n : ℕ
⊢ 0 < minFac n

Next tactic:
by_cases n1 : n = 1 <;> [exact n1.symm ▸ (by decide); exact (minFac_prime n1).pos]
theorem minFac_pos (n : ℕ) : 0 < minFac n := by
  

Proof state:
n : ℕ
⊢ 0 < minFac n

Next tactic:
by_cases n1 : n = 1
theorem minFac_pos (n : ℕ) : 0 < minFac n := by
  by_cases n1 : n = 1 <;> [

Proof state:
case pos
n : ℕ
n1 : n = 1
⊢ 0 < minFac n

Next tactic:
exact n1.symm ▸ (by decide)
theorem minFac_pos (n : ℕ) : 0 < minFac n := by
  by_cases n1 : n = 1 <;> [exact n1.symm ▸ (by 

Proof state:
n : ℕ
n1 : n = 1
⊢ 0 < minFac 1

Next tactic:
decide
theorem minFac_pos (n : ℕ) : 0 < minFac n := by
  by_cases n1 : n = 1 <;> [exact n1.symm ▸ (by decide); 

Proof state:
case neg
n : ℕ
n1 : ¬n = 1
⊢ 0 < minFac n

Next tactic:
exact (minFac_prime n1).pos
theorem le_minFac {m n : ℕ} : n = 1 ∨ m ≤ minFac n ↔ ∀ p, Prime p → p ∣ n → m ≤ p :=
  ⟨fun h p pp d =>
    h.elim (by 

Proof state:
m n : ℕ
h : n = 1 ∨ m ≤ minFac n
p : ℕ
pp : Prime p
d : p ∣ n
⊢ n = 1 → m ≤ p

Next tactic:
rintro rfl
theorem le_minFac {m n : ℕ} : n = 1 ∨ m ≤ minFac n ↔ ∀ p, Prime p → p ∣ n → m ≤ p :=
  ⟨fun h p pp d =>
    h.elim (by rintro rfl; 

Proof state:
m p : ℕ
pp : Prime p
h : 1 = 1 ∨ m ≤ minFac 1
d : p ∣ 1
⊢ m ≤ p

Next tactic:
cases pp.not_dvd_one d
theorem le_minFac' {m n : ℕ} : n = 1 ∨ m ≤ minFac n ↔ ∀ p, 2 ≤ p → p ∣ n → m ≤ p :=
  ⟨fun h p (pp : 1 < p) d =>
    h.elim (by 

Proof state:
m n : ℕ
h : n = 1 ∨ m ≤ minFac n
p : ℕ
pp : 1 < p
d : p ∣ n
⊢ n = 1 → m ≤ p

Next tactic:
rintro rfl
theorem le_minFac' {m n : ℕ} : n = 1 ∨ m ≤ minFac n ↔ ∀ p, 2 ≤ p → p ∣ n → m ≤ p :=
  ⟨fun h p (pp : 1 < p) d =>
    h.elim (by rintro rfl; 

Proof state:
m p : ℕ
pp : 1 < p
h : 1 = 1 ∨ m ≤ minFac 1
d : p ∣ 1
⊢ m ≤ p

Next tactic:
cases not_le_of_lt pp (le_of_dvd (by decide) d)
theorem le_minFac' {m n : ℕ} : n = 1 ∨ m ≤ minFac n ↔ ∀ p, 2 ≤ p → p ∣ n → m ≤ p :=
  ⟨fun h p (pp : 1 < p) d =>
    h.elim (by rintro rfl; cases not_le_of_lt pp (le_of_dvd (by 

Proof state:
m p : ℕ
pp : 1 < p
h : 1 = 1 ∨ m ≤ minFac 1
d : p ∣ 1
⊢ 0 < 1

Next tactic:
decide
theorem minFac_le_div {n : ℕ} (pos : 0 < n) (np : ¬Prime n) : minFac n ≤ n / minFac n :=
  match minFac_dvd n with
  | ⟨0, h0⟩ => absurd pos <| by 

Proof state:
n : ℕ
pos : 0 < n
np : ¬Prime n
h0 : n = minFac n * 0
⊢ ¬0 < n

Next tactic:
rw [h0, mul_zero]
theorem minFac_le_div {n : ℕ} (pos : 0 < n) (np : ¬Prime n) : minFac n ≤ n / minFac n :=
  match minFac_dvd n with
  | ⟨0, h0⟩ => absurd pos <| by rw [h0, mul_zero]; 

Proof state:
n : ℕ
pos : 0 < n
np : ¬Prime n
h0 : n = minFac n * 0
⊢ ¬0 < 0

Next tactic:
exact by decide
theorem minFac_le_div {n : ℕ} (pos : 0 < n) (np : ¬Prime n) : minFac n ≤ n / minFac n :=
  match minFac_dvd n with
  | ⟨0, h0⟩ => absurd pos <| by rw [h0, mul_zero]; exact by 

Proof state:
n : ℕ
pos : 0 < n
np : ¬Prime n
h0 : n = minFac n * 0
⊢ ¬0 < 0

Next tactic:
decide
theorem minFac_le_div {n : ℕ} (pos : 0 < n) (np : ¬Prime n) : minFac n ≤ n / minFac n :=
  match minFac_dvd n with
  | ⟨0, h0⟩ => absurd pos <| by rw [h0, mul_zero]; exact by decide
  | ⟨1, h1⟩ => by
    

Proof state:
n : ℕ
pos : 0 < n
np : ¬Prime n
h1 : n = minFac n * 1
⊢ minFac n ≤ n / minFac n

Next tactic:
rw [mul_one] at h1
theorem minFac_le_div {n : ℕ} (pos : 0 < n) (np : ¬Prime n) : minFac n ≤ n / minFac n :=
  match minFac_dvd n with
  | ⟨0, h0⟩ => absurd pos <| by rw [h0, mul_zero]; exact by decide
  | ⟨1, h1⟩ => by
    rw [mul_one] at h1
    

Proof state:
n : ℕ
pos : 0 < n
np : ¬Prime n
h1 : n = minFac n
⊢ minFac n ≤ n / minFac n

Next tactic:
rw [prime_def_minFac, not_and_or, ← h1, eq_self_iff_true, _root_.not_true, or_false_iff,
      not_le] at np
theorem minFac_le_div {n : ℕ} (pos : 0 < n) (np : ¬Prime n) : minFac n ≤ n / minFac n :=
  match minFac_dvd n with
  | ⟨0, h0⟩ => absurd pos <| by rw [h0, mul_zero]; exact by decide
  | ⟨1, h1⟩ => by
    rw [mul_one] at h1
    rw [prime_def_minFac, not_and_or, ← h1, eq_self_iff_true, _root_.not_true, or_false_iff,
      not_le] at np
    

Proof state:
n : ℕ
pos : 0 < n
np : n < 2
h1 : n = minFac n
⊢ minFac n ≤ n / minFac n

Next tactic:
rw [le_antisymm (le_of_lt_succ np) (succ_le_of_lt pos), minFac_one, Nat.div_one]
theorem minFac_le_div {n : ℕ} (pos : 0 < n) (np : ¬Prime n) : minFac n ≤ n / minFac n :=
  match minFac_dvd n with
  | ⟨0, h0⟩ => absurd pos <| by rw [h0, mul_zero]; exact by decide
  | ⟨1, h1⟩ => by
    rw [mul_one] at h1
    rw [prime_def_minFac, not_and_or, ← h1, eq_self_iff_true, _root_.not_true, or_false_iff,
      not_le] at np
    rw [le_antisymm (le_of_lt_succ np) (succ_le_of_lt pos), minFac_one, Nat.div_one]
  | ⟨x + 2, hx⟩ => by
    

Proof state:
n : ℕ
pos : 0 < n
np : ¬Prime n
x : ℕ
hx : n = minFac n * (x + 2)
⊢ minFac n ≤ n / minFac n

Next tactic:
conv_rhs =>
      congr
      rw [hx]
theorem minFac_le_div {n : ℕ} (pos : 0 < n) (np : ¬Prime n) : minFac n ≤ n / minFac n :=
  match minFac_dvd n with
  | ⟨0, h0⟩ => absurd pos <| by rw [h0, mul_zero]; exact by decide
  | ⟨1, h1⟩ => by
    rw [mul_one] at h1
    rw [prime_def_minFac, not_and_or, ← h1, eq_self_iff_true, _root_.not_true, or_false_iff,
      not_le] at np
    rw [le_antisymm (le_of_lt_succ np) (succ_le_of_lt pos), minFac_one, Nat.div_one]
  | ⟨x + 2, hx⟩ => by
    conv_rhs =>
      

Proof state:
n : ℕ
pos : 0 < n
np : ¬Prime n
x : ℕ
hx : n = minFac n * (x + 2)
| n / minFac n

Next tactic:
congr
      rw [hx]
theorem minFac_le_div {n : ℕ} (pos : 0 < n) (np : ¬Prime n) : minFac n ≤ n / minFac n :=
  match minFac_dvd n with
  | ⟨0, h0⟩ => absurd pos <| by rw [h0, mul_zero]; exact by decide
  | ⟨1, h1⟩ => by
    rw [mul_one] at h1
    rw [prime_def_minFac, not_and_or, ← h1, eq_self_iff_true, _root_.not_true, or_false_iff,
      not_le] at np
    rw [le_antisymm (le_of_lt_succ np) (succ_le_of_lt pos), minFac_one, Nat.div_one]
  | ⟨x + 2, hx⟩ => by
    conv_rhs =>
      

Proof state:
n : ℕ
pos : 0 < n
np : ¬Prime n
x : ℕ
hx : n = minFac n * (x + 2)
| n / minFac n

Next tactic:
congr
theorem minFac_le_div {n : ℕ} (pos : 0 < n) (np : ¬Prime n) : minFac n ≤ n / minFac n :=
  match minFac_dvd n with
  | ⟨0, h0⟩ => absurd pos <| by rw [h0, mul_zero]; exact by decide
  | ⟨1, h1⟩ => by
    rw [mul_one] at h1
    rw [prime_def_minFac, not_and_or, ← h1, eq_self_iff_true, _root_.not_true, or_false_iff,
      not_le] at np
    rw [le_antisymm (le_of_lt_succ np) (succ_le_of_lt pos), minFac_one, Nat.div_one]
  | ⟨x + 2, hx⟩ => by
    conv_rhs =>
      congr
      

Proof state:
case a
n : ℕ
pos : 0 < n
np : ¬Prime n
x : ℕ
hx : n = minFac n * (x + 2)
| n
case a n : ℕ pos : 0 < n np : ¬Prime n x : ℕ hx : n = minFac n * (x + 2) | minFac n

Next tactic:
rw [hx]
theorem minFac_le_div {n : ℕ} (pos : 0 < n) (np : ¬Prime n) : minFac n ≤ n / minFac n :=
  match minFac_dvd n with
  | ⟨0, h0⟩ => absurd pos <| by rw [h0, mul_zero]; exact by decide
  | ⟨1, h1⟩ => by
    rw [mul_one] at h1
    rw [prime_def_minFac, not_and_or, ← h1, eq_self_iff_true, _root_.not_true, or_false_iff,
      not_le] at np
    rw [le_antisymm (le_of_lt_succ np) (succ_le_of_lt pos), minFac_one, Nat.div_one]
  | ⟨x + 2, hx⟩ => by
    conv_rhs =>
      congr
      rw [hx]
    

Proof state:
n : ℕ
pos : 0 < n
np : ¬Prime n
x : ℕ
hx : n = minFac n * (x + 2)
⊢ minFac n ≤ minFac n * (x + 2) / minFac n

Next tactic:
rw [Nat.mul_div_cancel_left _ (minFac_pos _)]
theorem minFac_le_div {n : ℕ} (pos : 0 < n) (np : ¬Prime n) : minFac n ≤ n / minFac n :=
  match minFac_dvd n with
  | ⟨0, h0⟩ => absurd pos <| by rw [h0, mul_zero]; exact by decide
  | ⟨1, h1⟩ => by
    rw [mul_one] at h1
    rw [prime_def_minFac, not_and_or, ← h1, eq_self_iff_true, _root_.not_true, or_false_iff,
      not_le] at np
    rw [le_antisymm (le_of_lt_succ np) (succ_le_of_lt pos), minFac_one, Nat.div_one]
  | ⟨x + 2, hx⟩ => by
    conv_rhs =>
      congr
      rw [hx]
    rw [Nat.mul_div_cancel_left _ (minFac_pos _)]
    

Proof state:
n : ℕ
pos : 0 < n
np : ¬Prime n
x : ℕ
hx : n = minFac n * (x + 2)
⊢ minFac n ≤ x + 2

Next tactic:
exact minFac_le_of_dvd (le_add_left 2 x) ⟨minFac n, by rwa [mul_comm]⟩
theorem minFac_le_div {n : ℕ} (pos : 0 < n) (np : ¬Prime n) : minFac n ≤ n / minFac n :=
  match minFac_dvd n with
  | ⟨0, h0⟩ => absurd pos <| by rw [h0, mul_zero]; exact by decide
  | ⟨1, h1⟩ => by
    rw [mul_one] at h1
    rw [prime_def_minFac, not_and_or, ← h1, eq_self_iff_true, _root_.not_true, or_false_iff,
      not_le] at np
    rw [le_antisymm (le_of_lt_succ np) (succ_le_of_lt pos), minFac_one, Nat.div_one]
  | ⟨x + 2, hx⟩ => by
    conv_rhs =>
      congr
      rw [hx]
    rw [Nat.mul_div_cancel_left _ (minFac_pos _)]
    exact minFac_le_of_dvd (le_add_left 2 x) ⟨minFac n, by 

Proof state:
n : ℕ
pos : 0 < n
np : ¬Prime n
x : ℕ
hx : n = minFac n * (x + 2)
⊢ n = (x + 2) * minFac n

Next tactic:
rwa [mul_comm]
@[simp]
theorem minFac_eq_one_iff {n : ℕ} : minFac n = 1 ↔ n = 1 := by
  

Proof state:
n : ℕ
⊢ minFac n = 1 ↔ n = 1

Next tactic:
constructor
@[simp]
theorem minFac_eq_one_iff {n : ℕ} : minFac n = 1 ↔ n = 1 := by
  constructor
  · 

Proof state:
case mp
n : ℕ
⊢ minFac n = 1 → n = 1

Next tactic:
intro h
@[simp]
theorem minFac_eq_one_iff {n : ℕ} : minFac n = 1 ↔ n = 1 := by
  constructor
  · intro h
    

Proof state:
case mp
n : ℕ
h : minFac n = 1
⊢ n = 1

Next tactic:
by_contra hn
@[simp]
theorem minFac_eq_one_iff {n : ℕ} : minFac n = 1 ↔ n = 1 := by
  constructor
  · intro h
    by_contra hn
    

Proof state:
case mp
n : ℕ
h : minFac n = 1
hn : ¬n = 1
⊢ False

Next tactic:
have := minFac_prime hn
@[simp]
theorem minFac_eq_one_iff {n : ℕ} : minFac n = 1 ↔ n = 1 := by
  constructor
  · intro h
    by_contra hn
    have := minFac_prime hn
    

Proof state:
case mp
n : ℕ
h : minFac n = 1
hn : ¬n = 1
this : Prime (minFac n)
⊢ False

Next tactic:
rw [h] at this
@[simp]
theorem minFac_eq_one_iff {n : ℕ} : minFac n = 1 ↔ n = 1 := by
  constructor
  · intro h
    by_contra hn
    have := minFac_prime hn
    rw [h] at this
    

Proof state:
case mp
n : ℕ
h : minFac n = 1
hn : ¬n = 1
this : Prime 1
⊢ False

Next tactic:
exact not_prime_one this
@[simp]
theorem minFac_eq_one_iff {n : ℕ} : minFac n = 1 ↔ n = 1 := by
  constructor
  · intro h
    by_contra hn
    have := minFac_prime hn
    rw [h] at this
    exact not_prime_one this
  · 

Proof state:
case mpr
n : ℕ
⊢ n = 1 → minFac n = 1

Next tactic:
rintro rfl
@[simp]
theorem minFac_eq_one_iff {n : ℕ} : minFac n = 1 ↔ n = 1 := by
  constructor
  · intro h
    by_contra hn
    have := minFac_prime hn
    rw [h] at this
    exact not_prime_one this
  · rintro rfl
    

Proof state:
case mpr
⊢ minFac 1 = 1

Next tactic:
rfl
@[simp]
theorem minFac_eq_two_iff (n : ℕ) : minFac n = 2 ↔ 2 ∣ n := by
  

Proof state:
n : ℕ
⊢ minFac n = 2 ↔ 2 ∣ n

Next tactic:
constructor
@[simp]
theorem minFac_eq_two_iff (n : ℕ) : minFac n = 2 ↔ 2 ∣ n := by
  constructor
  · 

Proof state:
case mp
n : ℕ
⊢ minFac n = 2 → 2 ∣ n

Next tactic:
intro h
@[simp]
theorem minFac_eq_two_iff (n : ℕ) : minFac n = 2 ↔ 2 ∣ n := by
  constructor
  · intro h
    

Proof state:
case mp
n : ℕ
h : minFac n = 2
⊢ 2 ∣ n

Next tactic:
rw [← h]
@[simp]
theorem minFac_eq_two_iff (n : ℕ) : minFac n = 2 ↔ 2 ∣ n := by
  constructor
  · intro h
    rw [← h]
    

Proof state:
case mp
n : ℕ
h : minFac n = 2
⊢ minFac n ∣ n

Next tactic:
exact minFac_dvd n
@[simp]
theorem minFac_eq_two_iff (n : ℕ) : minFac n = 2 ↔ 2 ∣ n := by
  constructor
  · intro h
    rw [← h]
    exact minFac_dvd n
  · 

Proof state:
case mpr
n : ℕ
⊢ 2 ∣ n → minFac n = 2

Next tactic:
intro h
@[simp]
theorem minFac_eq_two_iff (n : ℕ) : minFac n = 2 ↔ 2 ∣ n := by
  constructor
  · intro h
    rw [← h]
    exact minFac_dvd n
  · intro h
    

Proof state:
case mpr
n : ℕ
h : 2 ∣ n
⊢ minFac n = 2

Next tactic:
have ub := minFac_le_of_dvd (le_refl 2) h
@[simp]
theorem minFac_eq_two_iff (n : ℕ) : minFac n = 2 ↔ 2 ∣ n := by
  constructor
  · intro h
    rw [← h]
    exact minFac_dvd n
  · intro h
    have ub := minFac_le_of_dvd (le_refl 2) h
    

Proof state:
case mpr
n : ℕ
h : 2 ∣ n
ub : minFac n ≤ 2
⊢ minFac n = 2

Next tactic:
have lb := minFac_pos n
@[simp]
theorem minFac_eq_two_iff (n : ℕ) : minFac n = 2 ↔ 2 ∣ n := by
  constructor
  · intro h
    rw [← h]
    exact minFac_dvd n
  · intro h
    have ub := minFac_le_of_dvd (le_refl 2) h
    have lb := minFac_pos n
    

Proof state:
case mpr
n : ℕ
h : 2 ∣ n
ub : minFac n ≤ 2
lb : 0 < minFac n
⊢ minFac n = 2

Next tactic:
refine ub.eq_or_lt.resolve_right fun h' => ?_
@[simp]
theorem minFac_eq_two_iff (n : ℕ) : minFac n = 2 ↔ 2 ∣ n := by
  constructor
  · intro h
    rw [← h]
    exact minFac_dvd n
  · intro h
    have ub := minFac_le_of_dvd (le_refl 2) h
    have lb := minFac_pos n
    refine ub.eq_or_lt.resolve_right fun h' => ?_
    

Proof state:
case mpr
n : ℕ
h : 2 ∣ n
ub : minFac n ≤ 2
lb : 0 < minFac n
h' : minFac n < 2
⊢ False

Next tactic:
have := le_antisymm (Nat.succ_le_of_lt lb) (lt_succ_iff.mp h')
@[simp]
theorem minFac_eq_two_iff (n : ℕ) : minFac n = 2 ↔ 2 ∣ n := by
  constructor
  · intro h
    rw [← h]
    exact minFac_dvd n
  · intro h
    have ub := minFac_le_of_dvd (le_refl 2) h
    have lb := minFac_pos n
    refine ub.eq_or_lt.resolve_right fun h' => ?_
    have := le_antisymm (Nat.succ_le_of_lt lb) (lt_succ_iff.mp h')
    

Proof state:
case mpr
n : ℕ
h : 2 ∣ n
ub : minFac n ≤ 2
lb : 0 < minFac n
h' : minFac n < 2
this : succ 0 = minFac n
⊢ False

Next tactic:
rw [eq_comm, Nat.minFac_eq_one_iff] at this
@[simp]
theorem minFac_eq_two_iff (n : ℕ) : minFac n = 2 ↔ 2 ∣ n := by
  constructor
  · intro h
    rw [← h]
    exact minFac_dvd n
  · intro h
    have ub := minFac_le_of_dvd (le_refl 2) h
    have lb := minFac_pos n
    refine ub.eq_or_lt.resolve_right fun h' => ?_
    have := le_antisymm (Nat.succ_le_of_lt lb) (lt_succ_iff.mp h')
    rw [eq_comm, Nat.minFac_eq_one_iff] at this
    

Proof state:
case mpr
n : ℕ
h : 2 ∣ n
ub : minFac n ≤ 2
lb : 0 < minFac n
h' : minFac n < 2
this : n = 1
⊢ False

Next tactic:
subst this
@[simp]
theorem minFac_eq_two_iff (n : ℕ) : minFac n = 2 ↔ 2 ∣ n := by
  constructor
  · intro h
    rw [← h]
    exact minFac_dvd n
  · intro h
    have ub := minFac_le_of_dvd (le_refl 2) h
    have lb := minFac_pos n
    refine ub.eq_or_lt.resolve_right fun h' => ?_
    have := le_antisymm (Nat.succ_le_of_lt lb) (lt_succ_iff.mp h')
    rw [eq_comm, Nat.minFac_eq_one_iff] at this
    subst this
    

Proof state:
case mpr
h : 2 ∣ 1
ub : minFac 1 ≤ 2
lb : 0 < minFac 1
h' : minFac 1 < 2
⊢ False

Next tactic:
exact not_lt_of_le (le_of_dvd zero_lt_one h) one_lt_two
theorem dvd_of_forall_prime_mul_dvd {a b : ℕ}
    (hdvd : ∀ p : ℕ, p.Prime → p ∣ a → p * a ∣ b) : a ∣ b := by
  

Proof state:
a b : ℕ
hdvd : ∀ (p : ℕ), Prime p → p ∣ a → p * a ∣ b
⊢ a ∣ b

Next tactic:
obtain rfl | ha := eq_or_ne a 1
theorem dvd_of_forall_prime_mul_dvd {a b : ℕ}
    (hdvd : ∀ p : ℕ, p.Prime → p ∣ a → p * a ∣ b) : a ∣ b := by
  obtain rfl | ha := eq_or_ne a 1
  · 

Proof state:
case inl
b : ℕ
hdvd : ∀ (p : ℕ), Prime p → p ∣ 1 → p * 1 ∣ b
⊢ 1 ∣ b

Next tactic:
apply one_dvd
theorem dvd_of_forall_prime_mul_dvd {a b : ℕ}
    (hdvd : ∀ p : ℕ, p.Prime → p ∣ a → p * a ∣ b) : a ∣ b := by
  obtain rfl | ha := eq_or_ne a 1
  · apply one_dvd
  

Proof state:
case inr
a b : ℕ
hdvd : ∀ (p : ℕ), Prime p → p ∣ a → p * a ∣ b
ha : a ≠ 1
⊢ a ∣ b

Next tactic:
obtain ⟨p, hp⟩ := exists_prime_and_dvd ha
theorem dvd_of_forall_prime_mul_dvd {a b : ℕ}
    (hdvd : ∀ p : ℕ, p.Prime → p ∣ a → p * a ∣ b) : a ∣ b := by
  obtain rfl | ha := eq_or_ne a 1
  · apply one_dvd
  obtain ⟨p, hp⟩ := exists_prime_and_dvd ha
  

Proof state:
case inr.intro
a b : ℕ
hdvd : ∀ (p : ℕ), Prime p → p ∣ a → p * a ∣ b
ha : a ≠ 1
p : ℕ
hp : Prime p ∧ p ∣ a
⊢ a ∣ b

Next tactic:
exact _root_.trans (dvd_mul_left a p) (hdvd p hp.1 hp.2)
/-- A version of `Nat.exists_infinite_primes` using the `BddAbove` predicate. -/
theorem not_bddAbove_setOf_prime : ¬BddAbove { p | Prime p } := by
  

Proof state:
⊢ ¬BddAbove {p | Prime p}

Next tactic:
rw [not_bddAbove_iff]