Theorem: Nat.smoothNumbersUpTo_subset_image
File: Mathlib/NumberTheory/SmoothNumbers.lean

Proof steps:
state_before: N k : ℕ
⊢ N.smoothNumbersUpTo k ⊆
    Finset.image
      (fun x =>
        match x with
        | (s, m) => m ^ 2 * s.prod id)
      (k.primesBelow.powerset ×ˢ (Finset.range N.sqrt.succ).erase 0)
state_after: N k n : ℕ
hn : n ∈ N.smoothNumbersUpTo k
⊢ n ∈
    Finset.image
      (fun x =>
        match x with
        | (s, m) => m ^ 2 * s.prod id)
      (k.primesBelow.powerset ×ˢ (Finset.range N.sqrt.succ).erase 0)
tactic: intro n hn
state_before: N k n : ℕ
hn : n ∈ N.smoothNumbersUpTo k
⊢ n ∈
    Finset.image
      (fun x =>
        match x with
        | (s, m) => m ^ 2 * s.prod id)
      (k.primesBelow.powerset ×ˢ (Finset.range N.sqrt.succ).erase 0)
state_after: case intro
N k n : ℕ
hn : n ∈ N.smoothNumbersUpTo k
hn₁ : n ≤ N
hn₂ : n ∈ k.smoothNumbers
⊢ n ∈
    Finset.image
      (fun x =>
        match x with
        | (s, m) => m ^ 2 * s.prod id)
      (k.primesBelow.powerset ×ˢ (Finset.range N.sqrt.succ).erase 0)
tactic: obtain ⟨hn₁, hn₂⟩ := mem_smoothNumbersUpTo.mp hn
state_before: case intro
N k n : ℕ
hn : n ∈ N.smoothNumbersUpTo k
hn₁ : n ≤ N
hn₂ : n ∈ k.smoothNumbers
⊢ n ∈
    Finset.image
      (fun x =>
        match x with
        | (s, m) => m ^ 2 * s.prod id)
      (k.primesBelow.powerset ×ˢ (Finset.range N.sqrt.succ).erase 0)
state_after: case intro.intro.intro.intro
N k n : ℕ
hn : n ∈ N.smoothNumbersUpTo k
hn₁ : n ≤ N
hn₂ : n ∈ k.smoothNumbers
s : Finset ℕ
hs : s ∈ k.primesBelow.powerset
m : ℕ
hm : n = m ^ 2 * s.prod id
⊢ n ∈
    Finset.image
      (fun x =>
        match x with
        | (s, m) => m ^ 2 * s.prod id)
      (k.primesBelow.powerset ×ˢ (Finset.range N.sqrt.succ).erase 0)
tactic: obtain ⟨s, hs, m, hm⟩ := eq_prod_primes_mul_sq_of_mem_smoothNumbers hn₂
state_before: case intro.intro.intro.intro
N k n : ℕ
hn : n ∈ N.smoothNumbersUpTo k
hn₁ : n ≤ N
hn₂ : n ∈ k.smoothNumbers
s : Finset ℕ
hs : s ∈ k.primesBelow.powerset
m : ℕ
hm : n = m ^ 2 * s.prod id
⊢ n ∈
    Finset.image
      (fun x =>
        match x with
        | (s, m) => m ^ 2 * s.prod id)
      (k.primesBelow.powerset ×ˢ (Finset.range N.sqrt.succ).erase 0)
state_after: case intro.intro.intro.intro
N k n : ℕ
hn : n ∈ N.smoothNumbersUpTo k
hn₁ : n ≤ N
hn₂ : n ∈ k.smoothNumbers
s : Finset ℕ
hs : s ∈ k.primesBelow.powerset
m : ℕ
hm : n = m ^ 2 * s.prod id
⊢ ∃ a b, (a ⊆ k.primesBelow ∧ b ≠ 0 ∧ b < N.sqrt.succ) ∧ b ^ 2 * ∏ x ∈ a, x = n
tactic: simp only [id_eq, Finset.mem_range, zero_lt_succ, not_true_eq_false, Finset.mem_image,
    Finset.mem_product, Finset.mem_powerset, Finset.mem_erase, Prod.exists]
state_before: case intro.intro.intro.intro
N k n : ℕ
hn : n ∈ N.smoothNumbersUpTo k
hn₁ : n ≤ N
hn₂ : n ∈ k.smoothNumbers
s : Finset ℕ
hs : s ∈ k.primesBelow.powerset
m : ℕ
hm : n = m ^ 2 * s.prod id
⊢ ∃ a b, (a ⊆ k.primesBelow ∧ b ≠ 0 ∧ b < N.sqrt.succ) ∧ b ^ 2 * ∏ x ∈ a, x = n
state_after: case intro.intro.intro.intro.refine_1
N k n : ℕ
hn : n ∈ N.smoothNumbersUpTo k
hn₁ : n ≤ N
hn₂ : n ∈ k.smoothNumbers
s : Finset ℕ
hs : s ∈ k.primesBelow.powerset
m : ℕ
hm : n = m ^ 2 * s.prod id
⊢ m ≠ 0

case intro.intro.intro.intro.refine_2
N k n : ℕ
hn : n ∈ N.smoothNumbersUpTo k
hn₁ : n ≤ N
hn₂ : n ∈ k.smoothNumbers
s : Finset ℕ
hs : s ∈ k.primesBelow.powerset
m : ℕ
hm : n = m ^ 2 * s.prod id
⊢ m < N.sqrt.succ
tactic: refine ⟨s, m, ⟨Finset.mem_powerset.mp hs, ?_, ?_⟩, hm.symm⟩