Theorem: Nat.sq_mul_squarefree_of_pos
File: Mathlib/Data/Nat/Squarefree.lean

tactic: set S := (Finset.range (n + 1)).filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2)
state_before: n : ℕ
hn : 0 < n
⊢ ∃ a b, 0 < a ∧ 0 < b ∧ b ^ 2 * a = n ∧ Squarefree a

tactic: have hSne : S.Nonempty := by
  use 1
  have h1 : 0 < n ∧ ∃ x : ℕ, 1 = x ^ 2 := ⟨hn, ⟨1, (one_pow 2).symm⟩⟩
  simp [h1]
state_before: n : ℕ
hn : 0 < n
S : Finset ℕ := Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))
⊢ ∃ a b, 0 < a ∧ 0 < b ∧ b ^ 2 * a = n ∧ Squarefree a

tactic: let s := Finset.max' S hSne
state_before: n : ℕ
hn : 0 < n
S : Finset ℕ := Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))
hSne : Finset.Nonempty S
⊢ ∃ a b, 0 < a ∧ 0 < b ∧ b ^ 2 * a = n ∧ Squarefree a

tactic: have hs : s ∈ S := Finset.max'_mem S hSne
state_before: n : ℕ
hn : 0 < n
S : Finset ℕ := Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))
hSne : Finset.Nonempty S
s : ℕ := Finset.max' S hSne
⊢ ∃ a b, 0 < a ∧ 0 < b ∧ b ^ 2 * a = n ∧ Squarefree a

tactic: simp only [Finset.mem_filter, Finset.mem_range] at hs
state_before: n : ℕ
hn : 0 < n
S : Finset ℕ := Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))
hSne : Finset.Nonempty S
s : ℕ := Finset.max' S hSne
hs : s ∈ S
⊢ ∃ a b, 0 < a ∧ 0 < b ∧ b ^ 2 * a = n ∧ Squarefree a

tactic: obtain ⟨-, ⟨a, hsa⟩, ⟨b, hsb⟩⟩ := hs
state_before: n : ℕ
hn : 0 < n
S : Finset ℕ := Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))
hSne : Finset.Nonempty S
s : ℕ := Finset.max' S hSne
hs :
  Finset.max' (Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))) hSne < n + 1 ∧
    Finset.max' (Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))) hSne ∣ n ∧
      ∃ x, Finset.max' (Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))) hSne = x ^ 2
⊢ ∃ a b, 0 < a ∧ 0 < b ∧ b ^ 2 * a = n ∧ Squarefree a

tactic: rw [hsa] at hn
state_before: case intro.intro.intro.intro
n : ℕ
hn : 0 < n
S : Finset ℕ := Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))
hSne : Finset.Nonempty S
s : ℕ := Finset.max' S hSne
a : ℕ
hsa : n = Finset.max' (Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))) hSne * a
b : ℕ
hsb : Finset.max' (Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))) hSne = b ^ 2
⊢ ∃ a b, 0 < a ∧ 0 < b ∧ b ^ 2 * a = n ∧ Squarefree a

tactic: obtain ⟨hlts, hlta⟩ := CanonicallyOrderedCommSemiring.mul_pos.mp hn
state_before: case intro.intro.intro.intro
n : ℕ
S : Finset ℕ := Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))
hSne : Finset.Nonempty S
s : ℕ := Finset.max' S hSne
a : ℕ
hn : 0 < Finset.max' (Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))) hSne * a
hsa : n = Finset.max' (Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))) hSne * a
b : ℕ
hsb : Finset.max' (Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))) hSne = b ^ 2
⊢ ∃ a b, 0 < a ∧ 0 < b ∧ b ^ 2 * a = n ∧ Squarefree a

tactic: rw [hsb] at hsa hn hlts
state_before: case intro.intro.intro.intro.intro
n : ℕ
S : Finset ℕ := Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))
hSne : Finset.Nonempty S
s : ℕ := Finset.max' S hSne
a : ℕ
hn : 0 < Finset.max' (Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))) hSne * a
hsa : n = Finset.max' (Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))) hSne * a
b : ℕ
hsb : Finset.max' (Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))) hSne = b ^ 2
hlts : 0 < Finset.max' (Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))) hSne
hlta : 0 < a
⊢ ∃ a b, 0 < a ∧ 0 < b ∧ b ^ 2 * a = n ∧ Squarefree a

tactic: refine' ⟨a, b, hlta, (pow_pos_iff zero_lt_two).mp hlts, hsa.symm, _⟩
state_before: case intro.intro.intro.intro.intro
n : ℕ
S : Finset ℕ := Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))
hSne : Finset.Nonempty S
s : ℕ := Finset.max' S hSne
a b : ℕ
hn : 0 < b ^ 2 * a
hsa : n = b ^ 2 * a
hsb : Finset.max' (Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))) hSne = b ^ 2
hlts : 0 < b ^ 2
hlta : 0 < a
⊢ ∃ a b, 0 < a ∧ 0 < b ∧ b ^ 2 * a = n ∧ Squarefree a

tactic: rintro x ⟨y, hy⟩
state_before: case intro.intro.intro.intro.intro
n : ℕ
S : Finset ℕ := Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))
hSne : Finset.Nonempty S
s : ℕ := Finset.max' S hSne
a b : ℕ
hn : 0 < b ^ 2 * a
hsa : n = b ^ 2 * a
hsb : Finset.max' (Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))) hSne = b ^ 2
hlts : 0 < b ^ 2
hlta : 0 < a
⊢ Squarefree a

tactic: rw [Nat.isUnit_iff]
state_before: case intro.intro.intro.intro.intro.intro
n : ℕ
S : Finset ℕ := Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))
hSne : Finset.Nonempty S
s : ℕ := Finset.max' S hSne
a b : ℕ
hn : 0 < b ^ 2 * a
hsa : n = b ^ 2 * a
hsb : Finset.max' (Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))) hSne = b ^ 2
hlts : 0 < b ^ 2
hlta : 0 < a
x y : ℕ
hy : a = x * x * y
⊢ IsUnit x

tactic: by_contra hx
state_before: case intro.intro.intro.intro.intro.intro
n : ℕ
S : Finset ℕ := Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))
hSne : Finset.Nonempty S
s : ℕ := Finset.max' S hSne
a b : ℕ
hn : 0 < b ^ 2 * a
hsa : n = b ^ 2 * a
hsb : Finset.max' (Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))) hSne = b ^ 2
hlts : 0 < b ^ 2
hlta : 0 < a
x y : ℕ
hy : a = x * x * y
⊢ x = 1

tactic: refine' lt_le_antisymm _ (Finset.le_max' S ((b * x) ^ 2) _)
state_before: case intro.intro.intro.intro.intro.intro
n : ℕ
S : Finset ℕ := Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))
hSne : Finset.Nonempty S
s : ℕ := Finset.max' S hSne
a b : ℕ
hn : 0 < b ^ 2 * a
hsa : n = b ^ 2 * a
hsb : Finset.max' (Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))) hSne = b ^ 2
hlts : 0 < b ^ 2
hlta : 0 < a
x y : ℕ
hy : a = x * x * y
hx : ¬x = 1
⊢ False

tactic: use 1
state_before: n : ℕ
hn : 0 < n
S : Finset ℕ := Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))
⊢ Finset.Nonempty S

tactic: have h1 : 0 < n ∧ ∃ x : ℕ, 1 = x ^ 2 := ⟨hn, ⟨1, (one_pow 2).symm⟩⟩
state_before: n : ℕ
hn : 0 < n
S : Finset ℕ := Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))
⊢ 1 ∈ S

tactic: simp [h1]
state_before: n : ℕ
hn : 0 < n
S : Finset ℕ := Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))
h1 : 0 < n ∧ ∃ x, 1 = x ^ 2
⊢ 1 ∈ S

tactic: convert lt_mul_of_one_lt_right hlts
  (one_lt_pow 2 x zero_lt_two (one_lt_iff_ne_zero_and_ne_one.mpr ⟨fun h => by simp_all, hx⟩))
  using 1
state_before: case intro.intro.intro.intro.intro.intro.refine'_1
n : ℕ
S : Finset ℕ := Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))
hSne : Finset.Nonempty S
s : ℕ := Finset.max' S hSne
a b : ℕ
hn : 0 < b ^ 2 * a
hsa : n = b ^ 2 * a
hsb : Finset.max' (Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))) hSne = b ^ 2
hlts : 0 < b ^ 2
hlta : 0 < a
x y : ℕ
hy : a = x * x * y
hx : ¬x = 1
⊢ Finset.max' S (_ : ∃ x, x ∈ S) < (b * x) ^ 2

tactic: rw [mul_pow]
state_before: case h.e'_4
n : ℕ
S : Finset ℕ := Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))
hSne : Finset.Nonempty S
s : ℕ := Finset.max' S hSne
a b : ℕ
hn : 0 < b ^ 2 * a
hsa : n = b ^ 2 * a
hsb : Finset.max' (Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))) hSne = b ^ 2
hlts : 0 < b ^ 2
hlta : 0 < a
x y : ℕ
hy : a = x * x * y
hx : ¬x = 1
⊢ (b * x) ^ 2 = b ^ 2 * x ^ 2

tactic: simp_all
state_before: n : ℕ
S : Finset ℕ := Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))
hSne : Finset.Nonempty S
s : ℕ := Finset.max' S hSne
a b : ℕ
hn : 0 < b ^ 2 * a
hsa : n = b ^ 2 * a
hsb : Finset.max' (Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))) hSne = b ^ 2
hlts : 0 < b ^ 2
hlta : 0 < a
x y : ℕ
hy : a = x * x * y
hx : ¬x = 1
h : x = 0
⊢ False

tactic: simp_rw [hsa, Finset.mem_filter, Finset.mem_range]
state_before: case intro.intro.intro.intro.intro.intro.refine'_2
n : ℕ
S : Finset ℕ := Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))
hSne : Finset.Nonempty S
s : ℕ := Finset.max' S hSne
a b : ℕ
hn : 0 < b ^ 2 * a
hsa : n = b ^ 2 * a
hsb : Finset.max' (Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))) hSne = b ^ 2
hlts : 0 < b ^ 2
hlta : 0 < a
x y : ℕ
hy : a = x * x * y
hx : ¬x = 1
⊢ (b * x) ^ 2 ∈ S

tactic: refine' ⟨lt_succ_iff.mpr (le_of_dvd hn _), _, ⟨b * x, rfl⟩⟩ <;> use y <;> rw [hy] <;> ring
state_before: case intro.intro.intro.intro.intro.intro.refine'_2
n : ℕ
S : Finset ℕ := Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))
hSne : Finset.Nonempty S
s : ℕ := Finset.max' S hSne
a b : ℕ
hn : 0 < b ^ 2 * a
hsa : n = b ^ 2 * a
hsb : Finset.max' (Finset.filter (fun s => s ∣ n ∧ ∃ x, s = x ^ 2) (Finset.range (n + 1))) hSne = b ^ 2
hlts : 0 < b ^ 2
hlta : 0 < a
x y : ℕ
hy : a = x * x * y
hx : ¬x = 1
⊢ (b * x) ^ 2 < b ^ 2 * a + 1 ∧ (b * x) ^ 2 ∣ b ^ 2 * a ∧ ∃ x_1, (b * x) ^ 2 = x_1 ^ 2