l3lab/ntp-mathlib huggingface dataset:
theorem isIntegral (α : solvableByRad F E) : IsIntegral F α := by
  revert α
  

Proof state:
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α : E
⊢ ∀ (α : ↥(solvableByRad F E)), IsIntegral F α

Next tactic:
apply solvableByRad.induction
theorem isIntegral (α : solvableByRad F E) : IsIntegral F α := by
  revert α
  apply solvableByRad.induction
  · 

Proof state:
case base
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α : E
⊢ ∀ (α : F), IsIntegral F ((algebraMap F ↥(solvableByRad F E)) α)

Next tactic:
exact fun _ => isIntegral_algebraMap
theorem isIntegral (α : solvableByRad F E) : IsIntegral F α := by
  revert α
  apply solvableByRad.induction
  · exact fun _ => isIntegral_algebraMap
  · 

Proof state:
case add
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α : E
⊢ ∀ (α β : ↥(solvableByRad F E)), IsIntegral F α → IsIntegral F β → IsIntegral F (α + β)

Next tactic:
exact fun _ _ => IsIntegral.add
theorem isIntegral (α : solvableByRad F E) : IsIntegral F α := by
  revert α
  apply solvableByRad.induction
  · exact fun _ => isIntegral_algebraMap
  · exact fun _ _ => IsIntegral.add
  · 

Proof state:
case neg
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α : E
⊢ ∀ (α : ↥(solvableByRad F E)), IsIntegral F α → IsIntegral F (-α)

Next tactic:
exact fun _ => IsIntegral.neg
theorem isIntegral (α : solvableByRad F E) : IsIntegral F α := by
  revert α
  apply solvableByRad.induction
  · exact fun _ => isIntegral_algebraMap
  · exact fun _ _ => IsIntegral.add
  · exact fun _ => IsIntegral.neg
  · 

Proof state:
case mul
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α : E
⊢ ∀ (α β : ↥(solvableByRad F E)), IsIntegral F α → IsIntegral F β → IsIntegral F (α * β)

Next tactic:
exact fun _ _ => IsIntegral.mul
theorem isIntegral (α : solvableByRad F E) : IsIntegral F α := by
  revert α
  apply solvableByRad.induction
  · exact fun _ => isIntegral_algebraMap
  · exact fun _ _ => IsIntegral.add
  · exact fun _ => IsIntegral.neg
  · exact fun _ _ => IsIntegral.mul
  · 

Proof state:
case inv
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α : E
⊢ ∀ (α : ↥(solvableByRad F E)), IsIntegral F α → IsIntegral F α⁻¹

Next tactic:
intro α hα
theorem isIntegral (α : solvableByRad F E) : IsIntegral F α := by
  revert α
  apply solvableByRad.induction
  · exact fun _ => isIntegral_algebraMap
  · exact fun _ _ => IsIntegral.add
  · exact fun _ => IsIntegral.neg
  · exact fun _ _ => IsIntegral.mul
  · intro α hα
    

Proof state:
case inv
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α✝ : E
α : ↥(solvableByRad F E)
hα : IsIntegral F α
⊢ IsIntegral F α⁻¹

Next tactic:
exact Subalgebra.inv_mem_of_algebraic (integralClosure F (solvableByRad F E))
      (show IsAlgebraic F ↑(⟨α, hα⟩ : integralClosure F (solvableByRad F E)) from hα.isAlgebraic)
theorem isIntegral (α : solvableByRad F E) : IsIntegral F α := by
  revert α
  apply solvableByRad.induction
  · exact fun _ => isIntegral_algebraMap
  · exact fun _ _ => IsIntegral.add
  · exact fun _ => IsIntegral.neg
  · exact fun _ _ => IsIntegral.mul
  · intro α hα
    exact Subalgebra.inv_mem_of_algebraic (integralClosure F (solvableByRad F E))
      (show IsAlgebraic F ↑(⟨α, hα⟩ : integralClosure F (solvableByRad F E)) from hα.isAlgebraic)
  · 

Proof state:
case rad
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α : E
⊢ ∀ (α : ↥(solvableByRad F E)) (n : ℕ), n ≠ 0 → IsIntegral F (α ^ n) → IsIntegral F α

Next tactic:
intro α n hn hα
theorem isIntegral (α : solvableByRad F E) : IsIntegral F α := by
  revert α
  apply solvableByRad.induction
  · exact fun _ => isIntegral_algebraMap
  · exact fun _ _ => IsIntegral.add
  · exact fun _ => IsIntegral.neg
  · exact fun _ _ => IsIntegral.mul
  · intro α hα
    exact Subalgebra.inv_mem_of_algebraic (integralClosure F (solvableByRad F E))
      (show IsAlgebraic F ↑(⟨α, hα⟩ : integralClosure F (solvableByRad F E)) from hα.isAlgebraic)
  · intro α n hn hα
    

Proof state:
case rad
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α✝ : E
α : ↥(solvableByRad F E)
n : ℕ
hn : n ≠ 0
hα : IsIntegral F (α ^ n)
⊢ IsIntegral F α

Next tactic:
obtain ⟨p, h1, h2⟩ := hα.isAlgebraic
theorem isIntegral (α : solvableByRad F E) : IsIntegral F α := by
  revert α
  apply solvableByRad.induction
  · exact fun _ => isIntegral_algebraMap
  · exact fun _ _ => IsIntegral.add
  · exact fun _ => IsIntegral.neg
  · exact fun _ _ => IsIntegral.mul
  · intro α hα
    exact Subalgebra.inv_mem_of_algebraic (integralClosure F (solvableByRad F E))
      (show IsAlgebraic F ↑(⟨α, hα⟩ : integralClosure F (solvableByRad F E)) from hα.isAlgebraic)
  · intro α n hn hα
    obtain ⟨p, h1, h2⟩ := hα.isAlgebraic
    

Proof state:
case rad.intro.intro
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α✝ : E
α : ↥(solvableByRad F E)
n : ℕ
hn : n ≠ 0
hα : IsIntegral F (α ^ n)
p : F[X]
h1 : p ≠ 0
h2 : (aeval (α ^ n)) p = 0
⊢ IsIntegral F α

Next tactic:
refine' IsAlgebraic.isIntegral ⟨p.comp (X ^ n),
      ⟨fun h => h1 (leadingCoeff_eq_zero.mp _), by rw [aeval_comp, aeval_X_pow, h2]⟩⟩
theorem isIntegral (α : solvableByRad F E) : IsIntegral F α := by
  revert α
  apply solvableByRad.induction
  · exact fun _ => isIntegral_algebraMap
  · exact fun _ _ => IsIntegral.add
  · exact fun _ => IsIntegral.neg
  · exact fun _ _ => IsIntegral.mul
  · intro α hα
    exact Subalgebra.inv_mem_of_algebraic (integralClosure F (solvableByRad F E))
      (show IsAlgebraic F ↑(⟨α, hα⟩ : integralClosure F (solvableByRad F E)) from hα.isAlgebraic)
  · intro α n hn hα
    obtain ⟨p, h1, h2⟩ := hα.isAlgebraic
    refine' IsAlgebraic.isIntegral ⟨p.comp (X ^ n),
      ⟨fun h => h1 (leadingCoeff_eq_zero.mp _), by 

Proof state:
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α✝ : E
α : ↥(solvableByRad F E)
n : ℕ
hn : n ≠ 0
hα : IsIntegral F (α ^ n)
p : F[X]
h1 : p ≠ 0
h2 : (aeval (α ^ n)) p = 0
⊢ (aeval α) (comp p (X ^ n)) = 0

Next tactic:
rw [aeval_comp, aeval_X_pow, h2]
theorem isIntegral (α : solvableByRad F E) : IsIntegral F α := by
  revert α
  apply solvableByRad.induction
  · exact fun _ => isIntegral_algebraMap
  · exact fun _ _ => IsIntegral.add
  · exact fun _ => IsIntegral.neg
  · exact fun _ _ => IsIntegral.mul
  · intro α hα
    exact Subalgebra.inv_mem_of_algebraic (integralClosure F (solvableByRad F E))
      (show IsAlgebraic F ↑(⟨α, hα⟩ : integralClosure F (solvableByRad F E)) from hα.isAlgebraic)
  · intro α n hn hα
    obtain ⟨p, h1, h2⟩ := hα.isAlgebraic
    refine' IsAlgebraic.isIntegral ⟨p.comp (X ^ n),
      ⟨fun h => h1 (leadingCoeff_eq_zero.mp _), by rw [aeval_comp, aeval_X_pow, h2]⟩⟩
    

Proof state:
case rad.intro.intro
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α✝ : E
α : ↥(solvableByRad F E)
n : ℕ
hn : n ≠ 0
hα : IsIntegral F (α ^ n)
p : F[X]
h1 : p ≠ 0
h2 : (aeval (α ^ n)) p = 0
h : comp p (X ^ n) = 0
⊢ leadingCoeff p = 0

Next tactic:
rwa [← leadingCoeff_eq_zero, leadingCoeff_comp, leadingCoeff_X_pow, one_pow, mul_one] at h
theorem isIntegral (α : solvableByRad F E) : IsIntegral F α := by
  revert α
  apply solvableByRad.induction
  · exact fun _ => isIntegral_algebraMap
  · exact fun _ _ => IsIntegral.add
  · exact fun _ => IsIntegral.neg
  · exact fun _ _ => IsIntegral.mul
  · intro α hα
    exact Subalgebra.inv_mem_of_algebraic (integralClosure F (solvableByRad F E))
      (show IsAlgebraic F ↑(⟨α, hα⟩ : integralClosure F (solvableByRad F E)) from hα.isAlgebraic)
  · intro α n hn hα
    obtain ⟨p, h1, h2⟩ := hα.isAlgebraic
    refine' IsAlgebraic.isIntegral ⟨p.comp (X ^ n),
      ⟨fun h => h1 (leadingCoeff_eq_zero.mp _), by rw [aeval_comp, aeval_X_pow, h2]⟩⟩
    rwa [← leadingCoeff_eq_zero, leadingCoeff_comp, leadingCoeff_X_pow, one_pow, mul_one] at h
    

Proof state:
case rad.intro.intro
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α✝ : E
α : ↥(solvableByRad F E)
n : ℕ
hn : n ≠ 0
hα : IsIntegral F (α ^ n)
p : F[X]
h1 : p ≠ 0
h2 : (aeval (α ^ n)) p = 0
h : leadingCoeff (comp p (X ^ n)) = 0
⊢ natDegree (X ^ n) ≠ 0

Next tactic:
rwa [natDegree_X_pow]
/-- An auxiliary induction lemma, which is generalized by `solvableByRad.isSolvable`. -/
theorem induction3 {α : solvableByRad F E} {n : ℕ} (hn : n ≠ 0) (hα : P (α ^ n)) : P α := by
  

Proof state:
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α✝ : E
α : ↥(solvableByRad F E)
n : ℕ
hn : n ≠ 0
hα : P (α ^ n)
⊢ P α

Next tactic:
let p := minpoly F (α ^ n)
/-- An auxiliary induction lemma, which is generalized by `solvableByRad.isSolvable`. -/
theorem induction3 {α : solvableByRad F E} {n : ℕ} (hn : n ≠ 0) (hα : P (α ^ n)) : P α := by
  let p := minpoly F (α ^ n)
  

Proof state:
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α✝ : E
α : ↥(solvableByRad F E)
n : ℕ
hn : n ≠ 0
hα : P (α ^ n)
p : F[X] := minpoly F (α ^ n)
⊢ P α

Next tactic:
have hp : p.comp (X ^ n) ≠ 0 := by
    intro h
    cases' comp_eq_zero_iff.mp h with h' h'
    · exact minpoly.ne_zero (isIntegral (α ^ n)) h'
    · exact hn (by rw [← @natDegree_C F, ← h'.2, natDegree_X_pow])
/-- An auxiliary induction lemma, which is generalized by `solvableByRad.isSolvable`. -/
theorem induction3 {α : solvableByRad F E} {n : ℕ} (hn : n ≠ 0) (hα : P (α ^ n)) : P α := by
  let p := minpoly F (α ^ n)
  have hp : p.comp (X ^ n) ≠ 0 := by
    

Proof state:
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α✝ : E
α : ↥(solvableByRad F E)
n : ℕ
hn : n ≠ 0
hα : P (α ^ n)
p : F[X] := minpoly F (α ^ n)
⊢ comp p (X ^ n) ≠ 0

Next tactic:
intro h
/-- An auxiliary induction lemma, which is generalized by `solvableByRad.isSolvable`. -/
theorem induction3 {α : solvableByRad F E} {n : ℕ} (hn : n ≠ 0) (hα : P (α ^ n)) : P α := by
  let p := minpoly F (α ^ n)
  have hp : p.comp (X ^ n) ≠ 0 := by
    intro h
    

Proof state:
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α✝ : E
α : ↥(solvableByRad F E)
n : ℕ
hn : n ≠ 0
hα : P (α ^ n)
p : F[X] := minpoly F (α ^ n)
h : comp p (X ^ n) = 0
⊢ False

Next tactic:
cases' comp_eq_zero_iff.mp h with h' h'
/-- An auxiliary induction lemma, which is generalized by `solvableByRad.isSolvable`. -/
theorem induction3 {α : solvableByRad F E} {n : ℕ} (hn : n ≠ 0) (hα : P (α ^ n)) : P α := by
  let p := minpoly F (α ^ n)
  have hp : p.comp (X ^ n) ≠ 0 := by
    intro h
    cases' comp_eq_zero_iff.mp h with h' h'
    · 

Proof state:
case inl
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α✝ : E
α : ↥(solvableByRad F E)
n : ℕ
hn : n ≠ 0
hα : P (α ^ n)
p : F[X] := minpoly F (α ^ n)
h : comp p (X ^ n) = 0
h' : p = 0
⊢ False

Next tactic:
exact minpoly.ne_zero (isIntegral (α ^ n)) h'
/-- An auxiliary induction lemma, which is generalized by `solvableByRad.isSolvable`. -/
theorem induction3 {α : solvableByRad F E} {n : ℕ} (hn : n ≠ 0) (hα : P (α ^ n)) : P α := by
  let p := minpoly F (α ^ n)
  have hp : p.comp (X ^ n) ≠ 0 := by
    intro h
    cases' comp_eq_zero_iff.mp h with h' h'
    · exact minpoly.ne_zero (isIntegral (α ^ n)) h'
    · 

Proof state:
case inr
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α✝ : E
α : ↥(solvableByRad F E)
n : ℕ
hn : n ≠ 0
hα : P (α ^ n)
p : F[X] := minpoly F (α ^ n)
h : comp p (X ^ n) = 0
h' : eval (coeff (X ^ n) 0) p = 0 ∧ X ^ n = C (coeff (X ^ n) 0)
⊢ False

Next tactic:
exact hn (by rw [← @natDegree_C F, ← h'.2, natDegree_X_pow])
/-- An auxiliary induction lemma, which is generalized by `solvableByRad.isSolvable`. -/
theorem induction3 {α : solvableByRad F E} {n : ℕ} (hn : n ≠ 0) (hα : P (α ^ n)) : P α := by
  let p := minpoly F (α ^ n)
  have hp : p.comp (X ^ n) ≠ 0 := by
    intro h
    cases' comp_eq_zero_iff.mp h with h' h'
    · exact minpoly.ne_zero (isIntegral (α ^ n)) h'
    · exact hn (by 

Proof state:
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α✝ : E
α : ↥(solvableByRad F E)
n : ℕ
hn : n ≠ 0
hα : P (α ^ n)
p : F[X] := minpoly F (α ^ n)
h : comp p (X ^ n) = 0
h' : eval (coeff (X ^ n) 0) p = 0 ∧ X ^ n = C (coeff (X ^ n) 0)
⊢ n = 0

Next tactic:
rw [← @natDegree_C F, ← h'.2, natDegree_X_pow]
/-- An auxiliary induction lemma, which is generalized by `solvableByRad.isSolvable`. -/
theorem induction3 {α : solvableByRad F E} {n : ℕ} (hn : n ≠ 0) (hα : P (α ^ n)) : P α := by
  let p := minpoly F (α ^ n)
  have hp : p.comp (X ^ n) ≠ 0 := by
    intro h
    cases' comp_eq_zero_iff.mp h with h' h'
    · exact minpoly.ne_zero (isIntegral (α ^ n)) h'
    · exact hn (by rw [← @natDegree_C F, ← h'.2, natDegree_X_pow])
  

Proof state:
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α✝ : E
α : ↥(solvableByRad F E)
n : ℕ
hn : n ≠ 0
hα : P (α ^ n)
p : F[X] := minpoly F (α ^ n)
hp : comp p (X ^ n) ≠ 0
⊢ P α

Next tactic:
apply gal_isSolvable_of_splits
/-- An auxiliary induction lemma, which is generalized by `solvableByRad.isSolvable`. -/
theorem induction3 {α : solvableByRad F E} {n : ℕ} (hn : n ≠ 0) (hα : P (α ^ n)) : P α := by
  let p := minpoly F (α ^ n)
  have hp : p.comp (X ^ n) ≠ 0 := by
    intro h
    cases' comp_eq_zero_iff.mp h with h' h'
    · exact minpoly.ne_zero (isIntegral (α ^ n)) h'
    · exact hn (by rw [← @natDegree_C F, ← h'.2, natDegree_X_pow])
  apply gal_isSolvable_of_splits
  · 

Proof state:
case x
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α✝ : E
α : ↥(solvableByRad F E)
n : ℕ
hn : n ≠ 0
hα : P (α ^ n)
p : F[X] := minpoly F (α ^ n)
hp : comp p (X ^ n) ≠ 0
⊢ Fact (Splits (algebraMap F (SplittingField ?q)) (minpoly F α))

Next tactic:
exact ⟨splits_of_splits_of_dvd _ hp (SplittingField.splits (p.comp (X ^ n)))
      (minpoly.dvd F α (by rw [aeval_comp, aeval_X_pow, minpoly.aeval]))⟩
/-- An auxiliary induction lemma, which is generalized by `solvableByRad.isSolvable`. -/
theorem induction3 {α : solvableByRad F E} {n : ℕ} (hn : n ≠ 0) (hα : P (α ^ n)) : P α := by
  let p := minpoly F (α ^ n)
  have hp : p.comp (X ^ n) ≠ 0 := by
    intro h
    cases' comp_eq_zero_iff.mp h with h' h'
    · exact minpoly.ne_zero (isIntegral (α ^ n)) h'
    · exact hn (by rw [← @natDegree_C F, ← h'.2, natDegree_X_pow])
  apply gal_isSolvable_of_splits
  · exact ⟨splits_of_splits_of_dvd _ hp (SplittingField.splits (p.comp (X ^ n)))
      (minpoly.dvd F α (by 

Proof state:
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α✝ : E
α : ↥(solvableByRad F E)
n : ℕ
hn : n ≠ 0
hα : P (α ^ n)
p : F[X] := minpoly F (α ^ n)
hp : comp p (X ^ n) ≠ 0
⊢ (aeval α) (comp p (X ^ n)) = 0

Next tactic:
rw [aeval_comp, aeval_X_pow, minpoly.aeval]
/-- An auxiliary induction lemma, which is generalized by `solvableByRad.isSolvable`. -/
theorem induction3 {α : solvableByRad F E} {n : ℕ} (hn : n ≠ 0) (hα : P (α ^ n)) : P α := by
  let p := minpoly F (α ^ n)
  have hp : p.comp (X ^ n) ≠ 0 := by
    intro h
    cases' comp_eq_zero_iff.mp h with h' h'
    · exact minpoly.ne_zero (isIntegral (α ^ n)) h'
    · exact hn (by rw [← @natDegree_C F, ← h'.2, natDegree_X_pow])
  apply gal_isSolvable_of_splits
  · exact ⟨splits_of_splits_of_dvd _ hp (SplittingField.splits (p.comp (X ^ n)))
      (minpoly.dvd F α (by rw [aeval_comp, aeval_X_pow, minpoly.aeval]))⟩
  · 

Proof state:
case hq
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α✝ : E
α : ↥(solvableByRad F E)
n : ℕ
hn : n ≠ 0
hα : P (α ^ n)
p : F[X] := minpoly F (α ^ n)
hp : comp p (X ^ n) ≠ 0
⊢ IsSolvable (Gal (comp p (X ^ n)))

Next tactic:
refine' gal_isSolvable_tower p (p.comp (X ^ n)) _ hα _
/-- An auxiliary induction lemma, which is generalized by `solvableByRad.isSolvable`. -/
theorem induction3 {α : solvableByRad F E} {n : ℕ} (hn : n ≠ 0) (hα : P (α ^ n)) : P α := by
  let p := minpoly F (α ^ n)
  have hp : p.comp (X ^ n) ≠ 0 := by
    intro h
    cases' comp_eq_zero_iff.mp h with h' h'
    · exact minpoly.ne_zero (isIntegral (α ^ n)) h'
    · exact hn (by rw [← @natDegree_C F, ← h'.2, natDegree_X_pow])
  apply gal_isSolvable_of_splits
  · exact ⟨splits_of_splits_of_dvd _ hp (SplittingField.splits (p.comp (X ^ n)))
      (minpoly.dvd F α (by rw [aeval_comp, aeval_X_pow, minpoly.aeval]))⟩
  · refine' gal_isSolvable_tower p (p.comp (X ^ n)) _ hα _
    · 

Proof state:
case hq.refine'_1
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α✝ : E
α : ↥(solvableByRad F E)
n : ℕ
hn : n ≠ 0
hα : P (α ^ n)
p : F[X] := minpoly F (α ^ n)
hp : comp p (X ^ n) ≠ 0
⊢ Splits (algebraMap F (SplittingField (comp p (X ^ n)))) p

Next tactic:
exact Gal.splits_in_splittingField_of_comp _ _ (by rwa [natDegree_X_pow])
/-- An auxiliary induction lemma, which is generalized by `solvableByRad.isSolvable`. -/
theorem induction3 {α : solvableByRad F E} {n : ℕ} (hn : n ≠ 0) (hα : P (α ^ n)) : P α := by
  let p := minpoly F (α ^ n)
  have hp : p.comp (X ^ n) ≠ 0 := by
    intro h
    cases' comp_eq_zero_iff.mp h with h' h'
    · exact minpoly.ne_zero (isIntegral (α ^ n)) h'
    · exact hn (by rw [← @natDegree_C F, ← h'.2, natDegree_X_pow])
  apply gal_isSolvable_of_splits
  · exact ⟨splits_of_splits_of_dvd _ hp (SplittingField.splits (p.comp (X ^ n)))
      (minpoly.dvd F α (by rw [aeval_comp, aeval_X_pow, minpoly.aeval]))⟩
  · refine' gal_isSolvable_tower p (p.comp (X ^ n)) _ hα _
    · exact Gal.splits_in_splittingField_of_comp _ _ (by 

Proof state:
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α✝ : E
α : ↥(solvableByRad F E)
n : ℕ
hn : n ≠ 0
hα : P (α ^ n)
p : F[X] := minpoly F (α ^ n)
hp : comp p (X ^ n) ≠ 0
⊢ natDegree (X ^ n) ≠ 0

Next tactic:
rwa [natDegree_X_pow]
/-- An auxiliary induction lemma, which is generalized by `solvableByRad.isSolvable`. -/
theorem induction3 {α : solvableByRad F E} {n : ℕ} (hn : n ≠ 0) (hα : P (α ^ n)) : P α := by
  let p := minpoly F (α ^ n)
  have hp : p.comp (X ^ n) ≠ 0 := by
    intro h
    cases' comp_eq_zero_iff.mp h with h' h'
    · exact minpoly.ne_zero (isIntegral (α ^ n)) h'
    · exact hn (by rw [← @natDegree_C F, ← h'.2, natDegree_X_pow])
  apply gal_isSolvable_of_splits
  · exact ⟨splits_of_splits_of_dvd _ hp (SplittingField.splits (p.comp (X ^ n)))
      (minpoly.dvd F α (by rw [aeval_comp, aeval_X_pow, minpoly.aeval]))⟩
  · refine' gal_isSolvable_tower p (p.comp (X ^ n)) _ hα _
    · exact Gal.splits_in_splittingField_of_comp _ _ (by rwa [natDegree_X_pow])
    · 

Proof state:
case hq.refine'_2
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α✝ : E
α : ↥(solvableByRad F E)
n : ℕ
hn : n ≠ 0
hα : P (α ^ n)
p : F[X] := minpoly F (α ^ n)
hp : comp p (X ^ n) ≠ 0
⊢ IsSolvable (Gal (Polynomial.map (algebraMap F (SplittingField p)) (comp p (X ^ n))))

Next tactic:
obtain ⟨s, hs⟩ := (splits_iff_exists_multiset _).1 (SplittingField.splits p)
/-- An auxiliary induction lemma, which is generalized by `solvableByRad.isSolvable`. -/
theorem induction3 {α : solvableByRad F E} {n : ℕ} (hn : n ≠ 0) (hα : P (α ^ n)) : P α := by
  let p := minpoly F (α ^ n)
  have hp : p.comp (X ^ n) ≠ 0 := by
    intro h
    cases' comp_eq_zero_iff.mp h with h' h'
    · exact minpoly.ne_zero (isIntegral (α ^ n)) h'
    · exact hn (by rw [← @natDegree_C F, ← h'.2, natDegree_X_pow])
  apply gal_isSolvable_of_splits
  · exact ⟨splits_of_splits_of_dvd _ hp (SplittingField.splits (p.comp (X ^ n)))
      (minpoly.dvd F α (by rw [aeval_comp, aeval_X_pow, minpoly.aeval]))⟩
  · refine' gal_isSolvable_tower p (p.comp (X ^ n)) _ hα _
    · exact Gal.splits_in_splittingField_of_comp _ _ (by rwa [natDegree_X_pow])
    · obtain ⟨s, hs⟩ := (splits_iff_exists_multiset _).1 (SplittingField.splits p)
      

Proof state:
case hq.refine'_2.intro
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α✝ : E
α : ↥(solvableByRad F E)
n : ℕ
hn : n ≠ 0
hα : P (α ^ n)
p : F[X] := minpoly F (α ^ n)
hp : comp p (X ^ n) ≠ 0
s : Multiset (SplittingField p)
hs :
  Polynomial.map (algebraMap F (SplittingField p)) p =
    C ((algebraMap F (SplittingField p)) (leadingCoeff p)) * Multiset.prod (Multiset.map (fun a => X - C a) s)
⊢ IsSolvable (Gal (Polynomial.map (algebraMap F (SplittingField p)) (comp p (X ^ n))))

Next tactic:
rw [map_comp, Polynomial.map_pow, map_X, hs, mul_comp, C_comp]
/-- An auxiliary induction lemma, which is generalized by `solvableByRad.isSolvable`. -/
theorem induction3 {α : solvableByRad F E} {n : ℕ} (hn : n ≠ 0) (hα : P (α ^ n)) : P α := by
  let p := minpoly F (α ^ n)
  have hp : p.comp (X ^ n) ≠ 0 := by
    intro h
    cases' comp_eq_zero_iff.mp h with h' h'
    · exact minpoly.ne_zero (isIntegral (α ^ n)) h'
    · exact hn (by rw [← @natDegree_C F, ← h'.2, natDegree_X_pow])
  apply gal_isSolvable_of_splits
  · exact ⟨splits_of_splits_of_dvd _ hp (SplittingField.splits (p.comp (X ^ n)))
      (minpoly.dvd F α (by rw [aeval_comp, aeval_X_pow, minpoly.aeval]))⟩
  · refine' gal_isSolvable_tower p (p.comp (X ^ n)) _ hα _
    · exact Gal.splits_in_splittingField_of_comp _ _ (by rwa [natDegree_X_pow])
    · obtain ⟨s, hs⟩ := (splits_iff_exists_multiset _).1 (SplittingField.splits p)
      rw [map_comp, Polynomial.map_pow, map_X, hs, mul_comp, C_comp]
      

Proof state:
case hq.refine'_2.intro
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α✝ : E
α : ↥(solvableByRad F E)
n : ℕ
hn : n ≠ 0
hα : P (α ^ n)
p : F[X] := minpoly F (α ^ n)
hp : comp p (X ^ n) ≠ 0
s : Multiset (SplittingField p)
hs :
  Polynomial.map (algebraMap F (SplittingField p)) p =
    C ((algebraMap F (SplittingField p)) (leadingCoeff p)) * Multiset.prod (Multiset.map (fun a => X - C a) s)
⊢ IsSolvable
    (Gal
      (C ((algebraMap F (SplittingField p)) (leadingCoeff p)) *
        comp (Multiset.prod (Multiset.map (fun a => X - C a) s)) (X ^ n)))

Next tactic:
apply gal_mul_isSolvable (gal_C_isSolvable _)
/-- An auxiliary induction lemma, which is generalized by `solvableByRad.isSolvable`. -/
theorem induction3 {α : solvableByRad F E} {n : ℕ} (hn : n ≠ 0) (hα : P (α ^ n)) : P α := by
  let p := minpoly F (α ^ n)
  have hp : p.comp (X ^ n) ≠ 0 := by
    intro h
    cases' comp_eq_zero_iff.mp h with h' h'
    · exact minpoly.ne_zero (isIntegral (α ^ n)) h'
    · exact hn (by rw [← @natDegree_C F, ← h'.2, natDegree_X_pow])
  apply gal_isSolvable_of_splits
  · exact ⟨splits_of_splits_of_dvd _ hp (SplittingField.splits (p.comp (X ^ n)))
      (minpoly.dvd F α (by rw [aeval_comp, aeval_X_pow, minpoly.aeval]))⟩
  · refine' gal_isSolvable_tower p (p.comp (X ^ n)) _ hα _
    · exact Gal.splits_in_splittingField_of_comp _ _ (by rwa [natDegree_X_pow])
    · obtain ⟨s, hs⟩ := (splits_iff_exists_multiset _).1 (SplittingField.splits p)
      rw [map_comp, Polynomial.map_pow, map_X, hs, mul_comp, C_comp]
      apply gal_mul_isSolvable (gal_C_isSolvable _)
      

Proof state:
case hq.refine'_2.intro
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α✝ : E
α : ↥(solvableByRad F E)
n : ℕ
hn : n ≠ 0
hα : P (α ^ n)
p : F[X] := minpoly F (α ^ n)
hp : comp p (X ^ n) ≠ 0
s : Multiset (SplittingField p)
hs :
  Polynomial.map (algebraMap F (SplittingField p)) p =
    C ((algebraMap F (SplittingField p)) (leadingCoeff p)) * Multiset.prod (Multiset.map (fun a => X - C a) s)
⊢ IsSolvable (Gal (comp (Multiset.prod (Multiset.map (fun a => X - C a) s)) (X ^ n)))

Next tactic:
rw [multiset_prod_comp]