l3lab/ntp-mathlib huggingface dataset:
theorem splits_X_pow_sub_one_of_X_pow_sub_C {F : Type*} [Field F] {E : Type*} [Field E]
    (i : F →+* E) (n : ℕ) {a : F} (ha : a ≠ 0) (h : (X ^ n - C a).Splits i) :
    (X ^ n - 1 : F[X]).Splits i := by
  have ha' : i a ≠ 0 := mt ((injective_iff_map_eq_zero i).mp i.injective a) ha
  by_cases hn : n = 0
  · rw [hn, pow_zero, sub_self]
    exact splits_zero i
  have hn' : 0 < n := pos_iff_ne_zero.mpr hn
  have hn'' : (X ^ n - C a).degree ≠ 0 :=
    ne_of_eq_of_ne (degree_X_pow_sub_C hn' a) (mt WithBot.coe_eq_coe.mp hn)
  obtain ⟨b, hb⟩ := exists_root_of_splits i h hn''
  rw [eval₂_sub, eval₂_X_pow, eval₂_C, sub_eq_zero] at hb
  have hb' : b ≠ 0 := by
    intro hb'
    rw [hb', zero_pow hn'] at hb
    exact ha' hb.symm
  let s := ((X ^ n - C a).map i).roots
  have hs : _ = _ * (s.map _).prod := eq_prod_roots_of_splits h
  rw [leadingCoeff_X_pow_sub_C hn', RingHom.map_one, C_1, one_mul] at hs
  have hs' : Multiset.card s = n := (natDegree_eq_card_roots h).symm.trans natDegree_X_pow_sub_C
  apply @splits_of_exists_multiset F E _ _ i (X ^ n - 1) (s.map fun c : E => c / b)
  rw [leadingCoeff_X_pow_sub_one hn', RingHom.map_one, C_1, one_mul, Multiset.map_map]
  have C_mul_C : C (i a⁻¹) * C (i a) = 1 := by
    rw [← C_mul, ← i.map_mul, inv_mul_cancel ha, i.map_one, C_1]
  have key1 : (X ^ n - 1 : F[X]).map i = C (i a⁻¹) * ((X ^ n - C a).map i).comp (C b * X) := by
    rw [Polynomial.map_sub, Polynomial.map_sub, Polynomial.map_pow, map_X, map_C,
      Polynomial.map_one, sub_comp, pow_comp, X_comp, C_comp, mul_pow, ← C_pow, hb, mul_sub, ←
      mul_assoc, C_mul_C, one_mul]
  have key2 : ((fun q : E[X] => q.comp (C b * X)) ∘ fun c : E => X - C c) = fun c : E =>
      C b * (X - C (c / b)) := by
    ext1 c
    dsimp only [Function.comp_apply]
    rw [sub_comp, X_comp, C_comp, mul_sub, ← C_mul, mul_div_cancel' c hb']
  

Proof state:
case neg.intro
F✝ : Type u_1
inst✝⁴ : Field F✝
E✝ : Type u_2
inst✝³ : Field E✝
inst✝² : Algebra F✝ E✝
F : Type u_3
inst✝¹ : Field F
E : Type u_4
inst✝ : Field E
i : F →+* E
n : ℕ
a : F
ha : a ≠ 0
h : Splits i (X ^ n - C a)
ha' : i a ≠ 0
hn : ¬n = 0
hn' : 0 < n
hn'' : degree (X ^ n - C a) ≠ 0
b : E
hb : b ^ n = i a
hb' : b ≠ 0
s : Multiset E := roots (Polynomial.map i (X ^ n - C a))
hs : Polynomial.map i (X ^ n - C a) = Multiset.prod (Multiset.map (fun a => X - C a) s)
hs' : Multiset.card s = n
C_mul_C : C (i a⁻¹) * C (i a) = 1
key1 : Polynomial.map i (X ^ n - 1) = C (i a⁻¹) * comp (Polynomial.map i (X ^ n - C a)) (C b * X)
key2 : ((fun q => comp q (C b * X)) ∘ fun c => X - C c) = fun c => C b * (X - C (c / b))
⊢ Polynomial.map i (X ^ n - 1) = Multiset.prod (Multiset.map ((fun a => X - C a) ∘ fun c => c / b) s)

Next tactic:
rw [key1, hs, multiset_prod_comp, Multiset.map_map, key2, Multiset.prod_map_mul,
    -- Porting note: needed for `Multiset.map_const` to work
    show (fun (_ : E) => C b) = Function.const E (C b) by rfl,
    Multiset.map_const, Multiset.prod_replicate, hs', ← C_pow, hb, ← mul_assoc, C_mul_C, one_mul]
theorem splits_X_pow_sub_one_of_X_pow_sub_C {F : Type*} [Field F] {E : Type*} [Field E]
    (i : F →+* E) (n : ℕ) {a : F} (ha : a ≠ 0) (h : (X ^ n - C a).Splits i) :
    (X ^ n - 1 : F[X]).Splits i := by
  have ha' : i a ≠ 0 := mt ((injective_iff_map_eq_zero i).mp i.injective a) ha
  by_cases hn : n = 0
  · rw [hn, pow_zero, sub_self]
    exact splits_zero i
  have hn' : 0 < n := pos_iff_ne_zero.mpr hn
  have hn'' : (X ^ n - C a).degree ≠ 0 :=
    ne_of_eq_of_ne (degree_X_pow_sub_C hn' a) (mt WithBot.coe_eq_coe.mp hn)
  obtain ⟨b, hb⟩ := exists_root_of_splits i h hn''
  rw [eval₂_sub, eval₂_X_pow, eval₂_C, sub_eq_zero] at hb
  have hb' : b ≠ 0 := by
    intro hb'
    rw [hb', zero_pow hn'] at hb
    exact ha' hb.symm
  let s := ((X ^ n - C a).map i).roots
  have hs : _ = _ * (s.map _).prod := eq_prod_roots_of_splits h
  rw [leadingCoeff_X_pow_sub_C hn', RingHom.map_one, C_1, one_mul] at hs
  have hs' : Multiset.card s = n := (natDegree_eq_card_roots h).symm.trans natDegree_X_pow_sub_C
  apply @splits_of_exists_multiset F E _ _ i (X ^ n - 1) (s.map fun c : E => c / b)
  rw [leadingCoeff_X_pow_sub_one hn', RingHom.map_one, C_1, one_mul, Multiset.map_map]
  have C_mul_C : C (i a⁻¹) * C (i a) = 1 := by
    rw [← C_mul, ← i.map_mul, inv_mul_cancel ha, i.map_one, C_1]
  have key1 : (X ^ n - 1 : F[X]).map i = C (i a⁻¹) * ((X ^ n - C a).map i).comp (C b * X) := by
    rw [Polynomial.map_sub, Polynomial.map_sub, Polynomial.map_pow, map_X, map_C,
      Polynomial.map_one, sub_comp, pow_comp, X_comp, C_comp, mul_pow, ← C_pow, hb, mul_sub, ←
      mul_assoc, C_mul_C, one_mul]
  have key2 : ((fun q : E[X] => q.comp (C b * X)) ∘ fun c : E => X - C c) = fun c : E =>
      C b * (X - C (c / b)) := by
    ext1 c
    dsimp only [Function.comp_apply]
    rw [sub_comp, X_comp, C_comp, mul_sub, ← C_mul, mul_div_cancel' c hb']
  rw [key1, hs, multiset_prod_comp, Multiset.map_map, key2, Multiset.prod_map_mul,
    -- Porting note: needed for `Multiset.map_const` to work
    show (fun (_ : E) => C b) = Function.const E (C b) by 

Proof state:
F✝ : Type u_1
inst✝⁴ : Field F✝
E✝ : Type u_2
inst✝³ : Field E✝
inst✝² : Algebra F✝ E✝
F : Type u_3
inst✝¹ : Field F
E : Type u_4
inst✝ : Field E
i : F →+* E
n : ℕ
a : F
ha : a ≠ 0
h : Splits i (X ^ n - C a)
ha' : i a ≠ 0
hn : ¬n = 0
hn' : 0 < n
hn'' : degree (X ^ n - C a) ≠ 0
b : E
hb : b ^ n = i a
hb' : b ≠ 0
s : Multiset E := roots (Polynomial.map i (X ^ n - C a))
hs : Polynomial.map i (X ^ n - C a) = Multiset.prod (Multiset.map (fun a => X - C a) s)
hs' : Multiset.card s = n
C_mul_C : C (i a⁻¹) * C (i a) = 1
key1 : Polynomial.map i (X ^ n - 1) = C (i a⁻¹) * comp (Polynomial.map i (X ^ n - C a)) (C b * X)
key2 : ((fun q => comp q (C b * X)) ∘ fun c => X - C c) = fun c => C b * (X - C (c / b))
⊢ (fun x => C b) = Function.const E (C b)

Next tactic:
rfl
theorem splits_X_pow_sub_one_of_X_pow_sub_C {F : Type*} [Field F] {E : Type*} [Field E]
    (i : F →+* E) (n : ℕ) {a : F} (ha : a ≠ 0) (h : (X ^ n - C a).Splits i) :
    (X ^ n - 1 : F[X]).Splits i := by
  have ha' : i a ≠ 0 := mt ((injective_iff_map_eq_zero i).mp i.injective a) ha
  by_cases hn : n = 0
  · rw [hn, pow_zero, sub_self]
    exact splits_zero i
  have hn' : 0 < n := pos_iff_ne_zero.mpr hn
  have hn'' : (X ^ n - C a).degree ≠ 0 :=
    ne_of_eq_of_ne (degree_X_pow_sub_C hn' a) (mt WithBot.coe_eq_coe.mp hn)
  obtain ⟨b, hb⟩ := exists_root_of_splits i h hn''
  rw [eval₂_sub, eval₂_X_pow, eval₂_C, sub_eq_zero] at hb
  have hb' : b ≠ 0 := by
    intro hb'
    rw [hb', zero_pow hn'] at hb
    exact ha' hb.symm
  let s := ((X ^ n - C a).map i).roots
  have hs : _ = _ * (s.map _).prod := eq_prod_roots_of_splits h
  rw [leadingCoeff_X_pow_sub_C hn', RingHom.map_one, C_1, one_mul] at hs
  have hs' : Multiset.card s = n := (natDegree_eq_card_roots h).symm.trans natDegree_X_pow_sub_C
  apply @splits_of_exists_multiset F E _ _ i (X ^ n - 1) (s.map fun c : E => c / b)
  rw [leadingCoeff_X_pow_sub_one hn', RingHom.map_one, C_1, one_mul, Multiset.map_map]
  have C_mul_C : C (i a⁻¹) * C (i a) = 1 := by
    rw [← C_mul, ← i.map_mul, inv_mul_cancel ha, i.map_one, C_1]
  have key1 : (X ^ n - 1 : F[X]).map i = C (i a⁻¹) * ((X ^ n - C a).map i).comp (C b * X) := by
    rw [Polynomial.map_sub, Polynomial.map_sub, Polynomial.map_pow, map_X, map_C,
      Polynomial.map_one, sub_comp, pow_comp, X_comp, C_comp, mul_pow, ← C_pow, hb, mul_sub, ←
      mul_assoc, C_mul_C, one_mul]
  have key2 : ((fun q : E[X] => q.comp (C b * X)) ∘ fun c : E => X - C c) = fun c : E =>
      C b * (X - C (c / b)) := by
    ext1 c
    dsimp only [Function.comp_apply]
    rw [sub_comp, X_comp, C_comp, mul_sub, ← C_mul, mul_div_cancel' c hb']
  rw [key1, hs, multiset_prod_comp, Multiset.map_map, key2, Multiset.prod_map_mul,
    -- Porting note: needed for `Multiset.map_const` to work
    show (fun (_ : E) => C b) = Function.const E (C b) by rfl,
    Multiset.map_const, Multiset.prod_replicate, hs', ← C_pow, hb, ← mul_assoc, C_mul_C, one_mul]
  

Proof state:
case neg.intro
F✝ : Type u_1
inst✝⁴ : Field F✝
E✝ : Type u_2
inst✝³ : Field E✝
inst✝² : Algebra F✝ E✝
F : Type u_3
inst✝¹ : Field F
E : Type u_4
inst✝ : Field E
i : F →+* E
n : ℕ
a : F
ha : a ≠ 0
h : Splits i (X ^ n - C a)
ha' : i a ≠ 0
hn : ¬n = 0
hn' : 0 < n
hn'' : degree (X ^ n - C a) ≠ 0
b : E
hb : b ^ n = i a
hb' : b ≠ 0
s : Multiset E := roots (Polynomial.map i (X ^ n - C a))
hs : Polynomial.map i (X ^ n - C a) = Multiset.prod (Multiset.map (fun a => X - C a) s)
hs' : Multiset.card s = n
C_mul_C : C (i a⁻¹) * C (i a) = 1
key1 : Polynomial.map i (X ^ n - 1) = C (i a⁻¹) * comp (Polynomial.map i (X ^ n - C a)) (C b * X)
key2 : ((fun q => comp q (C b * X)) ∘ fun c => X - C c) = fun c => C b * (X - C (c / b))
⊢ Multiset.prod (Multiset.map (fun c => X - C (c / b)) s) =
    Multiset.prod (Multiset.map ((fun a => X - C a) ∘ fun c => c / b) s)

Next tactic:
rfl
theorem gal_X_pow_sub_C_isSolvable (n : ℕ) (x : F) : IsSolvable (X ^ n - C x).Gal := by
  

Proof state:
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
n : ℕ
x : F
⊢ IsSolvable (Gal (X ^ n - C x))

Next tactic:
by_cases hx : x = 0
theorem gal_X_pow_sub_C_isSolvable (n : ℕ) (x : F) : IsSolvable (X ^ n - C x).Gal := by
  by_cases hx : x = 0
  · 

Proof state:
case pos
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
n : ℕ
x : F
hx : x = 0
⊢ IsSolvable (Gal (X ^ n - C x))

Next tactic:
rw [hx, C_0, sub_zero]
theorem gal_X_pow_sub_C_isSolvable (n : ℕ) (x : F) : IsSolvable (X ^ n - C x).Gal := by
  by_cases hx : x = 0
  · rw [hx, C_0, sub_zero]
    

Proof state:
case pos
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
n : ℕ
x : F
hx : x = 0
⊢ IsSolvable (Gal (X ^ n))

Next tactic:
exact gal_X_pow_isSolvable n
theorem gal_X_pow_sub_C_isSolvable (n : ℕ) (x : F) : IsSolvable (X ^ n - C x).Gal := by
  by_cases hx : x = 0
  · rw [hx, C_0, sub_zero]
    exact gal_X_pow_isSolvable n
  

Proof state:
case neg
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
n : ℕ
x : F
hx : ¬x = 0
⊢ IsSolvable (Gal (X ^ n - C x))

Next tactic:
apply gal_isSolvable_tower (X ^ n - 1) (X ^ n - C x)
theorem gal_X_pow_sub_C_isSolvable (n : ℕ) (x : F) : IsSolvable (X ^ n - C x).Gal := by
  by_cases hx : x = 0
  · rw [hx, C_0, sub_zero]
    exact gal_X_pow_isSolvable n
  apply gal_isSolvable_tower (X ^ n - 1) (X ^ n - C x)
  · 

Proof state:
case neg.hpq
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
n : ℕ
x : F
hx : ¬x = 0
⊢ Splits (algebraMap F (SplittingField (X ^ n - C x))) (X ^ n - 1)

Next tactic:
exact splits_X_pow_sub_one_of_X_pow_sub_C _ n hx (SplittingField.splits _)
theorem gal_X_pow_sub_C_isSolvable (n : ℕ) (x : F) : IsSolvable (X ^ n - C x).Gal := by
  by_cases hx : x = 0
  · rw [hx, C_0, sub_zero]
    exact gal_X_pow_isSolvable n
  apply gal_isSolvable_tower (X ^ n - 1) (X ^ n - C x)
  · exact splits_X_pow_sub_one_of_X_pow_sub_C _ n hx (SplittingField.splits _)
  · 

Proof state:
case neg.hp
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
n : ℕ
x : F
hx : ¬x = 0
⊢ IsSolvable (Gal (X ^ n - 1))

Next tactic:
exact gal_X_pow_sub_one_isSolvable n
theorem gal_X_pow_sub_C_isSolvable (n : ℕ) (x : F) : IsSolvable (X ^ n - C x).Gal := by
  by_cases hx : x = 0
  · rw [hx, C_0, sub_zero]
    exact gal_X_pow_isSolvable n
  apply gal_isSolvable_tower (X ^ n - 1) (X ^ n - C x)
  · exact splits_X_pow_sub_one_of_X_pow_sub_C _ n hx (SplittingField.splits _)
  · exact gal_X_pow_sub_one_isSolvable n
  · 

Proof state:
case neg.hq
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
n : ℕ
x : F
hx : ¬x = 0
⊢ IsSolvable (Gal (Polynomial.map (algebraMap F (SplittingField (X ^ n - 1))) (X ^ n - C x)))

Next tactic:
rw [Polynomial.map_sub, Polynomial.map_pow, map_X, map_C]
theorem gal_X_pow_sub_C_isSolvable (n : ℕ) (x : F) : IsSolvable (X ^ n - C x).Gal := by
  by_cases hx : x = 0
  · rw [hx, C_0, sub_zero]
    exact gal_X_pow_isSolvable n
  apply gal_isSolvable_tower (X ^ n - 1) (X ^ n - C x)
  · exact splits_X_pow_sub_one_of_X_pow_sub_C _ n hx (SplittingField.splits _)
  · exact gal_X_pow_sub_one_isSolvable n
  · rw [Polynomial.map_sub, Polynomial.map_pow, map_X, map_C]
    

Proof state:
case neg.hq
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
n : ℕ
x : F
hx : ¬x = 0
⊢ IsSolvable (Gal (X ^ n - C ((algebraMap F (SplittingField (X ^ n - 1))) x)))

Next tactic:
apply gal_X_pow_sub_C_isSolvable_aux
theorem gal_X_pow_sub_C_isSolvable (n : ℕ) (x : F) : IsSolvable (X ^ n - C x).Gal := by
  by_cases hx : x = 0
  · rw [hx, C_0, sub_zero]
    exact gal_X_pow_isSolvable n
  apply gal_isSolvable_tower (X ^ n - 1) (X ^ n - C x)
  · exact splits_X_pow_sub_one_of_X_pow_sub_C _ n hx (SplittingField.splits _)
  · exact gal_X_pow_sub_one_isSolvable n
  · rw [Polynomial.map_sub, Polynomial.map_pow, map_X, map_C]
    apply gal_X_pow_sub_C_isSolvable_aux
    

Proof state:
case neg.hq.h
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
n : ℕ
x : F
hx : ¬x = 0
⊢ Splits (RingHom.id (SplittingField (X ^ n - 1))) (X ^ n - 1)

Next tactic:
have key := SplittingField.splits (X ^ n - 1 : F[X])
theorem gal_X_pow_sub_C_isSolvable (n : ℕ) (x : F) : IsSolvable (X ^ n - C x).Gal := by
  by_cases hx : x = 0
  · rw [hx, C_0, sub_zero]
    exact gal_X_pow_isSolvable n
  apply gal_isSolvable_tower (X ^ n - 1) (X ^ n - C x)
  · exact splits_X_pow_sub_one_of_X_pow_sub_C _ n hx (SplittingField.splits _)
  · exact gal_X_pow_sub_one_isSolvable n
  · rw [Polynomial.map_sub, Polynomial.map_pow, map_X, map_C]
    apply gal_X_pow_sub_C_isSolvable_aux
    have key := SplittingField.splits (X ^ n - 1 : F[X])
    

Proof state:
case neg.hq.h
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
n : ℕ
x : F
hx : ¬x = 0
key : Splits (algebraMap F (SplittingField (X ^ n - 1))) (X ^ n - 1)
⊢ Splits (RingHom.id (SplittingField (X ^ n - 1))) (X ^ n - 1)

Next tactic:
rwa [← splits_id_iff_splits, Polynomial.map_sub, Polynomial.map_pow, map_X,
      Polynomial.map_one] at key
/-- The intermediate field of solvable-by-radicals elements -/
def solvableByRad : IntermediateField F E where
  carrier := IsSolvableByRad F
  zero_mem' := by
    change IsSolvableByRad F 0
    convert IsSolvableByRad.base (E := E) (0 : F); rw [RingHom.map_zero]
  add_mem' := by apply IsSolvableByRad.add
  one_mem' := by
    change IsSolvableByRad F 1
    convert IsSolvableByRad.base (E := E) (1 : F); rw [RingHom.map_one]
  mul_mem' := by 

Proof state:
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
⊢ ∀ {a b : E}, a ∈ IsSolvableByRad F → b ∈ IsSolvableByRad F → a * b ∈ IsSolvableByRad F

Next tactic:
apply IsSolvableByRad.mul
/-- The intermediate field of solvable-by-radicals elements -/
def solvableByRad : IntermediateField F E where
  carrier := IsSolvableByRad F
  zero_mem' := by
    change IsSolvableByRad F 0
    convert IsSolvableByRad.base (E := E) (0 : F); rw [RingHom.map_zero]
  add_mem' := by apply IsSolvableByRad.add
  one_mem' := by
    

Proof state:
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
⊢ 1 ∈
    { carrier := IsSolvableByRad F,
        mul_mem' := (_ : ∀ (α β : E), IsSolvableByRad F α → IsSolvableByRad F β → IsSolvableByRad F (α * β)) }.carrier

Next tactic:
change IsSolvableByRad F 1
/-- The intermediate field of solvable-by-radicals elements -/
def solvableByRad : IntermediateField F E where
  carrier := IsSolvableByRad F
  zero_mem' := by
    change IsSolvableByRad F 0
    convert IsSolvableByRad.base (E := E) (0 : F); rw [RingHom.map_zero]
  add_mem' := by apply IsSolvableByRad.add
  one_mem' := by
    change IsSolvableByRad F 1
    

Proof state:
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
⊢ IsSolvableByRad F 1

Next tactic:
convert IsSolvableByRad.base (E := E) (1 : F)
/-- The intermediate field of solvable-by-radicals elements -/
def solvableByRad : IntermediateField F E where
  carrier := IsSolvableByRad F
  zero_mem' := by
    change IsSolvableByRad F 0
    convert IsSolvableByRad.base (E := E) (0 : F); rw [RingHom.map_zero]
  add_mem' := by apply IsSolvableByRad.add
  one_mem' := by
    change IsSolvableByRad F 1
    convert IsSolvableByRad.base (E := E) (1 : F); 

Proof state:
case h.e'_6
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
⊢ 1 = (algebraMap F E) 1

Next tactic:
rw [RingHom.map_one]
/-- The intermediate field of solvable-by-radicals elements -/
def solvableByRad : IntermediateField F E where
  carrier := IsSolvableByRad F
  zero_mem' := by
    change IsSolvableByRad F 0
    convert IsSolvableByRad.base (E := E) (0 : F); rw [RingHom.map_zero]
  add_mem' := by 

Proof state:
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
⊢ ∀ {a b : E},
    a ∈
        {
              toSubsemigroup :=
                { carrier := IsSolvableByRad F,
                  mul_mem' :=
                    (_ : ∀ (α β : E), IsSolvableByRad F α → IsSolvableByRad F β → IsSolvableByRad F (α * β)) },
              one_mem' := (_ : IsSolvableByRad F 1) }.toSubsemigroup.carrier →
      b ∈
          {
                toSubsemigroup :=
                  { carrier := IsSolvableByRad F,
                    mul_mem' :=
                      (_ : ∀ (α β : E), IsSolvableByRad F α → IsSolvableByRad F β → IsSolvableByRad F (α * β)) },
                one_mem' := (_ : IsSolvableByRad F 1) }.toSubsemigroup.carrier →
        a + b ∈
          {
                toSubsemigroup :=
                  { carrier := IsSolvableByRad F,
                    mul_mem' :=
                      (_ : ∀ (α β : E), IsSolvableByRad F α → IsSolvableByRad F β → IsSolvableByRad F (α * β)) },
                one_mem' := (_ : IsSolvableByRad F 1) }.toSubsemigroup.carrier

Next tactic:
apply IsSolvableByRad.add
/-- The intermediate field of solvable-by-radicals elements -/
def solvableByRad : IntermediateField F E where
  carrier := IsSolvableByRad F
  zero_mem' := by
    

Proof state:
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
⊢ 0 ∈
    {
          toSubsemigroup :=
            { carrier := IsSolvableByRad F,
              mul_mem' := (_ : ∀ (α β : E), IsSolvableByRad F α → IsSolvableByRad F β → IsSolvableByRad F (α * β)) },
          one_mem' := (_ : IsSolvableByRad F 1) }.toSubsemigroup.carrier

Next tactic:
change IsSolvableByRad F 0
/-- The intermediate field of solvable-by-radicals elements -/
def solvableByRad : IntermediateField F E where
  carrier := IsSolvableByRad F
  zero_mem' := by
    change IsSolvableByRad F 0
    

Proof state:
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
⊢ IsSolvableByRad F 0

Next tactic:
convert IsSolvableByRad.base (E := E) (0 : F)
/-- The intermediate field of solvable-by-radicals elements -/
def solvableByRad : IntermediateField F E where
  carrier := IsSolvableByRad F
  zero_mem' := by
    change IsSolvableByRad F 0
    convert IsSolvableByRad.base (E := E) (0 : F); 

Proof state:
case h.e'_6
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
⊢ 0 = (algebraMap F E) 0

Next tactic:
rw [RingHom.map_zero]
theorem induction (P : solvableByRad F E → Prop)
    (base : ∀ α : F, P (algebraMap F (solvableByRad F E) α))
    (add : ∀ α β : solvableByRad F E, P α → P β → P (α + β))
    (neg : ∀ α : solvableByRad F E, P α → P (-α))
    (mul : ∀ α β : solvableByRad F E, P α → P β → P (α * β))
    (inv : ∀ α : solvableByRad F E, P α → P α⁻¹)
    (rad : ∀ α : solvableByRad F E, ∀ n : ℕ, n ≠ 0 → P (α ^ n) → P α) (α : solvableByRad F E) :
    P α := by
  

Proof state:
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α✝ : E
P : ↥(solvableByRad F E) → Prop
base : ∀ (α : F), P ((algebraMap F ↥(solvableByRad F E)) α)
add : ∀ (α β : ↥(solvableByRad F E)), P α → P β → P (α + β)
neg : ∀ (α : ↥(solvableByRad F E)), P α → P (-α)
mul : ∀ (α β : ↥(solvableByRad F E)), P α → P β → P (α * β)
inv : ∀ (α : ↥(solvableByRad F E)), P α → P α⁻¹
rad : ∀ (α : ↥(solvableByRad F E)) (n : ℕ), n ≠ 0 → P (α ^ n) → P α
α : ↥(solvableByRad F E)
⊢ P α

Next tactic:
revert α
theorem induction (P : solvableByRad F E → Prop)
    (base : ∀ α : F, P (algebraMap F (solvableByRad F E) α))
    (add : ∀ α β : solvableByRad F E, P α → P β → P (α + β))
    (neg : ∀ α : solvableByRad F E, P α → P (-α))
    (mul : ∀ α β : solvableByRad F E, P α → P β → P (α * β))
    (inv : ∀ α : solvableByRad F E, P α → P α⁻¹)
    (rad : ∀ α : solvableByRad F E, ∀ n : ℕ, n ≠ 0 → P (α ^ n) → P α) (α : solvableByRad F E) :
    P α := by
  revert α
  

Proof state:
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α : E
P : ↥(solvableByRad F E) → Prop
base : ∀ (α : F), P ((algebraMap F ↥(solvableByRad F E)) α)
add : ∀ (α β : ↥(solvableByRad F E)), P α → P β → P (α + β)
neg : ∀ (α : ↥(solvableByRad F E)), P α → P (-α)
mul : ∀ (α β : ↥(solvableByRad F E)), P α → P β → P (α * β)
inv : ∀ (α : ↥(solvableByRad F E)), P α → P α⁻¹
rad : ∀ (α : ↥(solvableByRad F E)) (n : ℕ), n ≠ 0 → P (α ^ n) → P α
⊢ ∀ (α : ↥(solvableByRad F E)), P α

Next tactic:
suffices ∀ α : E, IsSolvableByRad F α → ∃ β : solvableByRad F E, ↑β = α ∧ P β by
    intro α
    obtain ⟨α₀, hα₀, Pα⟩ := this α (Subtype.mem α)
    convert Pα
    exact Subtype.ext hα₀.symm
theorem induction (P : solvableByRad F E → Prop)
    (base : ∀ α : F, P (algebraMap F (solvableByRad F E) α))
    (add : ∀ α β : solvableByRad F E, P α → P β → P (α + β))
    (neg : ∀ α : solvableByRad F E, P α → P (-α))
    (mul : ∀ α β : solvableByRad F E, P α → P β → P (α * β))
    (inv : ∀ α : solvableByRad F E, P α → P α⁻¹)
    (rad : ∀ α : solvableByRad F E, ∀ n : ℕ, n ≠ 0 → P (α ^ n) → P α) (α : solvableByRad F E) :
    P α := by
  revert α
  suffices ∀ α : E, IsSolvableByRad F α → ∃ β : solvableByRad F E, ↑β = α ∧ P β by
    

Proof state:
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α : E
P : ↥(solvableByRad F E) → Prop
base : ∀ (α : F), P ((algebraMap F ↥(solvableByRad F E)) α)
add : ∀ (α β : ↥(solvableByRad F E)), P α → P β → P (α + β)
neg : ∀ (α : ↥(solvableByRad F E)), P α → P (-α)
mul : ∀ (α β : ↥(solvableByRad F E)), P α → P β → P (α * β)
inv : ∀ (α : ↥(solvableByRad F E)), P α → P α⁻¹
rad : ∀ (α : ↥(solvableByRad F E)) (n : ℕ), n ≠ 0 → P (α ^ n) → P α
this : ∀ (α : E), IsSolvableByRad F α → ∃ β, ↑β = α ∧ P β
⊢ ∀ (α : ↥(solvableByRad F E)), P α

Next tactic:
intro α
theorem induction (P : solvableByRad F E → Prop)
    (base : ∀ α : F, P (algebraMap F (solvableByRad F E) α))
    (add : ∀ α β : solvableByRad F E, P α → P β → P (α + β))
    (neg : ∀ α : solvableByRad F E, P α → P (-α))
    (mul : ∀ α β : solvableByRad F E, P α → P β → P (α * β))
    (inv : ∀ α : solvableByRad F E, P α → P α⁻¹)
    (rad : ∀ α : solvableByRad F E, ∀ n : ℕ, n ≠ 0 → P (α ^ n) → P α) (α : solvableByRad F E) :
    P α := by
  revert α
  suffices ∀ α : E, IsSolvableByRad F α → ∃ β : solvableByRad F E, ↑β = α ∧ P β by
    intro α
    

Proof state:
F : Type u_1
inst✝² : Field F
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
α✝ : E
P : ↥(solvableByRad F E) → Prop
base : ∀ (α : F), P ((algebraMap F ↥(solvableByRad F E)) α)
add : ∀ (α β : ↥(solvableByRad F E)), P α → P β → P (α + β)
neg : ∀ (α : ↥(solvableByRad F E)), P α → P (-α)
mul : ∀ (α β : ↥(solvableByRad F E)), P α → P β → P (α * β)
inv : ∀ (α : ↥(solvableByRad F E)), P α → P α⁻¹
rad : ∀ (α : ↥(solvableByRad F E)) (n : ℕ), n ≠ 0 → P (α ^ n) → P α
this : ∀ (α : E), IsSolvableByRad F α → ∃ β, ↑β = α ∧ P β
α : ↥(solvableByRad F E)
⊢ P α

Next tactic:
obtain ⟨α₀, hα₀, Pα⟩ := this α (Subtype.mem α)