l3lab/ntp-mathlib huggingface dataset:
theorem adjoin_rootSet (n : ℕ) :
    ∀ {K : Type u} [Field K],
      ∀ (f : K[X]) (_hfn : f.natDegree = n),
        Algebra.adjoin K (f.rootSet (SplittingFieldAux n f)) = ⊤ :=
  Nat.recOn (motive := fun n =>
    ∀ {K : Type u} [Field K],
      ∀ (f : K[X]) (_hfn : f.natDegree = n),
        Algebra.adjoin K (f.rootSet (SplittingFieldAux n f)) = ⊤)
    n (fun {K} _ f _hf => Algebra.eq_top_iff.2 fun x => Subalgebra.range_le _ ⟨x, rfl⟩)
    fun n ih {K} _ f hfn => by
    have hndf : f.natDegree ≠ 0 := by intro h; rw [h] at hfn; cases hfn
    

Proof state:
F : Type u
K✝¹ : Type v
L : Type w
inst✝³ : Field K✝¹
inst✝² : Field L
inst✝¹ : Field F
n✝ : ℕ
K✝ : Type u
inst✝ : Field K✝
n : ℕ
ih :
  (fun n =>
      ∀ {K : Type u} [inst : Field K] (f : K[X]),
        natDegree f = n → Algebra.adjoin K (rootSet f (SplittingFieldAux n f)) = ⊤)
    n
K : Type u
x✝ : Field K
f : K[X]
hfn : natDegree f = Nat.succ n
hndf : natDegree f ≠ 0
⊢ Algebra.adjoin K (rootSet f (SplittingFieldAux (Nat.succ n) f)) = ⊤

Next tactic:
have hfn0 : f ≠ 0 := by intro h; rw [h] at hndf; exact hndf rfl
theorem adjoin_rootSet (n : ℕ) :
    ∀ {K : Type u} [Field K],
      ∀ (f : K[X]) (_hfn : f.natDegree = n),
        Algebra.adjoin K (f.rootSet (SplittingFieldAux n f)) = ⊤ :=
  Nat.recOn (motive := fun n =>
    ∀ {K : Type u} [Field K],
      ∀ (f : K[X]) (_hfn : f.natDegree = n),
        Algebra.adjoin K (f.rootSet (SplittingFieldAux n f)) = ⊤)
    n (fun {K} _ f _hf => Algebra.eq_top_iff.2 fun x => Subalgebra.range_le _ ⟨x, rfl⟩)
    fun n ih {K} _ f hfn => by
    have hndf : f.natDegree ≠ 0 := by intro h; rw [h] at hfn; cases hfn
    have hfn0 : f ≠ 0 := by 

Proof state:
F : Type u
K✝¹ : Type v
L : Type w
inst✝³ : Field K✝¹
inst✝² : Field L
inst✝¹ : Field F
n✝ : ℕ
K✝ : Type u
inst✝ : Field K✝
n : ℕ
ih :
  (fun n =>
      ∀ {K : Type u} [inst : Field K] (f : K[X]),
        natDegree f = n → Algebra.adjoin K (rootSet f (SplittingFieldAux n f)) = ⊤)
    n
K : Type u
x✝ : Field K
f : K[X]
hfn : natDegree f = Nat.succ n
hndf : natDegree f ≠ 0
⊢ f ≠ 0

Next tactic:
intro h
theorem adjoin_rootSet (n : ℕ) :
    ∀ {K : Type u} [Field K],
      ∀ (f : K[X]) (_hfn : f.natDegree = n),
        Algebra.adjoin K (f.rootSet (SplittingFieldAux n f)) = ⊤ :=
  Nat.recOn (motive := fun n =>
    ∀ {K : Type u} [Field K],
      ∀ (f : K[X]) (_hfn : f.natDegree = n),
        Algebra.adjoin K (f.rootSet (SplittingFieldAux n f)) = ⊤)
    n (fun {K} _ f _hf => Algebra.eq_top_iff.2 fun x => Subalgebra.range_le _ ⟨x, rfl⟩)
    fun n ih {K} _ f hfn => by
    have hndf : f.natDegree ≠ 0 := by intro h; rw [h] at hfn; cases hfn
    have hfn0 : f ≠ 0 := by intro h; 

Proof state:
F : Type u
K✝¹ : Type v
L : Type w
inst✝³ : Field K✝¹
inst✝² : Field L
inst✝¹ : Field F
n✝ : ℕ
K✝ : Type u
inst✝ : Field K✝
n : ℕ
ih :
  (fun n =>
      ∀ {K : Type u} [inst : Field K] (f : K[X]),
        natDegree f = n → Algebra.adjoin K (rootSet f (SplittingFieldAux n f)) = ⊤)
    n
K : Type u
x✝ : Field K
f : K[X]
hfn : natDegree f = Nat.succ n
hndf : natDegree f ≠ 0
h : f = 0
⊢ False

Next tactic:
rw [h] at hndf
theorem adjoin_rootSet (n : ℕ) :
    ∀ {K : Type u} [Field K],
      ∀ (f : K[X]) (_hfn : f.natDegree = n),
        Algebra.adjoin K (f.rootSet (SplittingFieldAux n f)) = ⊤ :=
  Nat.recOn (motive := fun n =>
    ∀ {K : Type u} [Field K],
      ∀ (f : K[X]) (_hfn : f.natDegree = n),
        Algebra.adjoin K (f.rootSet (SplittingFieldAux n f)) = ⊤)
    n (fun {K} _ f _hf => Algebra.eq_top_iff.2 fun x => Subalgebra.range_le _ ⟨x, rfl⟩)
    fun n ih {K} _ f hfn => by
    have hndf : f.natDegree ≠ 0 := by intro h; rw [h] at hfn; cases hfn
    have hfn0 : f ≠ 0 := by intro h; rw [h] at hndf; 

Proof state:
F : Type u
K✝¹ : Type v
L : Type w
inst✝³ : Field K✝¹
inst✝² : Field L
inst✝¹ : Field F
n✝ : ℕ
K✝ : Type u
inst✝ : Field K✝
n : ℕ
ih :
  (fun n =>
      ∀ {K : Type u} [inst : Field K] (f : K[X]),
        natDegree f = n → Algebra.adjoin K (rootSet f (SplittingFieldAux n f)) = ⊤)
    n
K : Type u
x✝ : Field K
f : K[X]
hfn : natDegree f = Nat.succ n
hndf : natDegree 0 ≠ 0
h : f = 0
⊢ False

Next tactic:
exact hndf rfl
theorem adjoin_rootSet (n : ℕ) :
    ∀ {K : Type u} [Field K],
      ∀ (f : K[X]) (_hfn : f.natDegree = n),
        Algebra.adjoin K (f.rootSet (SplittingFieldAux n f)) = ⊤ :=
  Nat.recOn (motive := fun n =>
    ∀ {K : Type u} [Field K],
      ∀ (f : K[X]) (_hfn : f.natDegree = n),
        Algebra.adjoin K (f.rootSet (SplittingFieldAux n f)) = ⊤)
    n (fun {K} _ f _hf => Algebra.eq_top_iff.2 fun x => Subalgebra.range_le _ ⟨x, rfl⟩)
    fun n ih {K} _ f hfn => by
    have hndf : f.natDegree ≠ 0 := by intro h; rw [h] at hfn; cases hfn
    have hfn0 : f ≠ 0 := by intro h; rw [h] at hndf; exact hndf rfl
    

Proof state:
F : Type u
K✝¹ : Type v
L : Type w
inst✝³ : Field K✝¹
inst✝² : Field L
inst✝¹ : Field F
n✝ : ℕ
K✝ : Type u
inst✝ : Field K✝
n : ℕ
ih :
  (fun n =>
      ∀ {K : Type u} [inst : Field K] (f : K[X]),
        natDegree f = n → Algebra.adjoin K (rootSet f (SplittingFieldAux n f)) = ⊤)
    n
K : Type u
x✝ : Field K
f : K[X]
hfn : natDegree f = Nat.succ n
hndf : natDegree f ≠ 0
hfn0 : f ≠ 0
⊢ Algebra.adjoin K (rootSet f (SplittingFieldAux (Nat.succ n) f)) = ⊤

Next tactic:
have hmf0 : map (algebraMap K (SplittingFieldAux n.succ f)) f ≠ 0 := map_ne_zero hfn0
theorem adjoin_rootSet (n : ℕ) :
    ∀ {K : Type u} [Field K],
      ∀ (f : K[X]) (_hfn : f.natDegree = n),
        Algebra.adjoin K (f.rootSet (SplittingFieldAux n f)) = ⊤ :=
  Nat.recOn (motive := fun n =>
    ∀ {K : Type u} [Field K],
      ∀ (f : K[X]) (_hfn : f.natDegree = n),
        Algebra.adjoin K (f.rootSet (SplittingFieldAux n f)) = ⊤)
    n (fun {K} _ f _hf => Algebra.eq_top_iff.2 fun x => Subalgebra.range_le _ ⟨x, rfl⟩)
    fun n ih {K} _ f hfn => by
    have hndf : f.natDegree ≠ 0 := by intro h; rw [h] at hfn; cases hfn
    have hfn0 : f ≠ 0 := by intro h; rw [h] at hndf; exact hndf rfl
    have hmf0 : map (algebraMap K (SplittingFieldAux n.succ f)) f ≠ 0 := map_ne_zero hfn0
    

Proof state:
F : Type u
K✝¹ : Type v
L : Type w
inst✝³ : Field K✝¹
inst✝² : Field L
inst✝¹ : Field F
n✝ : ℕ
K✝ : Type u
inst✝ : Field K✝
n : ℕ
ih :
  (fun n =>
      ∀ {K : Type u} [inst : Field K] (f : K[X]),
        natDegree f = n → Algebra.adjoin K (rootSet f (SplittingFieldAux n f)) = ⊤)
    n
K : Type u
x✝ : Field K
f : K[X]
hfn : natDegree f = Nat.succ n
hndf : natDegree f ≠ 0
hfn0 : f ≠ 0
hmf0 : map (algebraMap K (SplittingFieldAux (Nat.succ n) f)) f ≠ 0
⊢ Algebra.adjoin K (rootSet f (SplittingFieldAux (Nat.succ n) f)) = ⊤

Next tactic:
rw [rootSet_def, aroots_def]
theorem adjoin_rootSet (n : ℕ) :
    ∀ {K : Type u} [Field K],
      ∀ (f : K[X]) (_hfn : f.natDegree = n),
        Algebra.adjoin K (f.rootSet (SplittingFieldAux n f)) = ⊤ :=
  Nat.recOn (motive := fun n =>
    ∀ {K : Type u} [Field K],
      ∀ (f : K[X]) (_hfn : f.natDegree = n),
        Algebra.adjoin K (f.rootSet (SplittingFieldAux n f)) = ⊤)
    n (fun {K} _ f _hf => Algebra.eq_top_iff.2 fun x => Subalgebra.range_le _ ⟨x, rfl⟩)
    fun n ih {K} _ f hfn => by
    have hndf : f.natDegree ≠ 0 := by intro h; rw [h] at hfn; cases hfn
    have hfn0 : f ≠ 0 := by intro h; rw [h] at hndf; exact hndf rfl
    have hmf0 : map (algebraMap K (SplittingFieldAux n.succ f)) f ≠ 0 := map_ne_zero hfn0
    rw [rootSet_def, aroots_def]
    

Proof state:
F : Type u
K✝¹ : Type v
L : Type w
inst✝³ : Field K✝¹
inst✝² : Field L
inst✝¹ : Field F
n✝ : ℕ
K✝ : Type u
inst✝ : Field K✝
n : ℕ
ih :
  (fun n =>
      ∀ {K : Type u} [inst : Field K] (f : K[X]),
        natDegree f = n → Algebra.adjoin K (rootSet f (SplittingFieldAux n f)) = ⊤)
    n
K : Type u
x✝ : Field K
f : K[X]
hfn : natDegree f = Nat.succ n
hndf : natDegree f ≠ 0
hfn0 : f ≠ 0
hmf0 : map (algebraMap K (SplittingFieldAux (Nat.succ n) f)) f ≠ 0
⊢ Algebra.adjoin K ↑(Multiset.toFinset (roots (map (algebraMap K (SplittingFieldAux (Nat.succ n) f)) f))) = ⊤

Next tactic:
rw [algebraMap_succ, ← map_map, ← X_sub_C_mul_removeFactor _ hndf, Polynomial.map_mul] at hmf0 ⊢
theorem adjoin_rootSet (n : ℕ) :
    ∀ {K : Type u} [Field K],
      ∀ (f : K[X]) (_hfn : f.natDegree = n),
        Algebra.adjoin K (f.rootSet (SplittingFieldAux n f)) = ⊤ :=
  Nat.recOn (motive := fun n =>
    ∀ {K : Type u} [Field K],
      ∀ (f : K[X]) (_hfn : f.natDegree = n),
        Algebra.adjoin K (f.rootSet (SplittingFieldAux n f)) = ⊤)
    n (fun {K} _ f _hf => Algebra.eq_top_iff.2 fun x => Subalgebra.range_le _ ⟨x, rfl⟩)
    fun n ih {K} _ f hfn => by
    have hndf : f.natDegree ≠ 0 := by intro h; rw [h] at hfn; cases hfn
    have hfn0 : f ≠ 0 := by intro h; rw [h] at hndf; exact hndf rfl
    have hmf0 : map (algebraMap K (SplittingFieldAux n.succ f)) f ≠ 0 := map_ne_zero hfn0
    rw [rootSet_def, aroots_def]
    rw [algebraMap_succ, ← map_map, ← X_sub_C_mul_removeFactor _ hndf, Polynomial.map_mul] at hmf0 ⊢
    -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
    

Proof state:
F : Type u
K✝¹ : Type v
L : Type w
inst✝³ : Field K✝¹
inst✝² : Field L
inst✝¹ : Field F
n✝ : ℕ
K✝ : Type u
inst✝ : Field K✝
n : ℕ
ih :
  (fun n =>
      ∀ {K : Type u} [inst : Field K] (f : K[X]),
        natDegree f = n → Algebra.adjoin K (rootSet f (SplittingFieldAux n f)) = ⊤)
    n
K : Type u
x✝ : Field K
f : K[X]
hfn : natDegree f = Nat.succ n
hndf : natDegree f ≠ 0
hfn0 : f ≠ 0
hmf0 :
  map (algebraMap (AdjoinRoot (factor f)) (SplittingFieldAux n (removeFactor f))) (X - C (AdjoinRoot.root (factor f))) *
      map (algebraMap (AdjoinRoot (factor f)) (SplittingFieldAux n (removeFactor f))) (removeFactor f) ≠
    0
⊢ Algebra.adjoin K
      ↑(Multiset.toFinset
          (roots
            (map (algebraMap (AdjoinRoot (factor f)) (SplittingFieldAux n (removeFactor f)))
                (X - C (AdjoinRoot.root (factor f))) *
              map (algebraMap (AdjoinRoot (factor f)) (SplittingFieldAux n (removeFactor f))) (removeFactor f)))) =
    ⊤

Next tactic:
erw [roots_mul hmf0, Polynomial.map_sub, map_X, map_C, roots_X_sub_C, Multiset.toFinset_add,
      Finset.coe_union, Multiset.toFinset_singleton, Finset.coe_singleton,
      Algebra.adjoin_union_eq_adjoin_adjoin, ← Set.image_singleton,
      Algebra.adjoin_algebraMap K (SplittingFieldAux n f.removeFactor),
      AdjoinRoot.adjoinRoot_eq_top, Algebra.map_top]
theorem adjoin_rootSet (n : ℕ) :
    ∀ {K : Type u} [Field K],
      ∀ (f : K[X]) (_hfn : f.natDegree = n),
        Algebra.adjoin K (f.rootSet (SplittingFieldAux n f)) = ⊤ :=
  Nat.recOn (motive := fun n =>
    ∀ {K : Type u} [Field K],
      ∀ (f : K[X]) (_hfn : f.natDegree = n),
        Algebra.adjoin K (f.rootSet (SplittingFieldAux n f)) = ⊤)
    n (fun {K} _ f _hf => Algebra.eq_top_iff.2 fun x => Subalgebra.range_le _ ⟨x, rfl⟩)
    fun n ih {K} _ f hfn => by
    have hndf : f.natDegree ≠ 0 := by intro h; rw [h] at hfn; cases hfn
    have hfn0 : f ≠ 0 := by intro h; rw [h] at hndf; exact hndf rfl
    have hmf0 : map (algebraMap K (SplittingFieldAux n.succ f)) f ≠ 0 := map_ne_zero hfn0
    rw [rootSet_def, aroots_def]
    rw [algebraMap_succ, ← map_map, ← X_sub_C_mul_removeFactor _ hndf, Polynomial.map_mul] at hmf0 ⊢
    -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
    erw [roots_mul hmf0, Polynomial.map_sub, map_X, map_C, roots_X_sub_C, Multiset.toFinset_add,
      Finset.coe_union, Multiset.toFinset_singleton, Finset.coe_singleton,
      Algebra.adjoin_union_eq_adjoin_adjoin, ← Set.image_singleton,
      Algebra.adjoin_algebraMap K (SplittingFieldAux n f.removeFactor),
      AdjoinRoot.adjoinRoot_eq_top, Algebra.map_top]
    /- Porting note: was `rw [IsScalarTower.adjoin_range_toAlgHom K (AdjoinRoot f.factor)
        (SplittingFieldAux n f.removeFactor)]` -/
    

Proof state:
F : Type u
K✝¹ : Type v
L : Type w
inst✝³ : Field K✝¹
inst✝² : Field L
inst✝¹ : Field F
n✝ : ℕ
K✝ : Type u
inst✝ : Field K✝
n : ℕ
ih :
  (fun n =>
      ∀ {K : Type u} [inst : Field K] (f : K[X]),
        natDegree f = n → Algebra.adjoin K (rootSet f (SplittingFieldAux n f)) = ⊤)
    n
K : Type u
x✝ : Field K
f : K[X]
hfn : natDegree f = Nat.succ n
hndf : natDegree f ≠ 0
hfn0 : f ≠ 0
hmf0 :
  map (algebraMap (AdjoinRoot (factor f)) (SplittingFieldAux n (removeFactor f))) (X - C (AdjoinRoot.root (factor f))) *
      map (algebraMap (AdjoinRoot (factor f)) (SplittingFieldAux n (removeFactor f))) (removeFactor f) ≠
    0
⊢ Subalgebra.restrictScalars K
      (Algebra.adjoin
        ↥(AlgHom.range (IsScalarTower.toAlgHom K (AdjoinRoot (factor f)) (SplittingFieldAux n (removeFactor f))))
        ↑(Multiset.toFinset
            (roots
              (map (algebraMap (AdjoinRoot (factor f)) (SplittingFieldAux n (removeFactor f))) (removeFactor f))))) =
    ⊤

Next tactic:
have := IsScalarTower.adjoin_range_toAlgHom K (AdjoinRoot f.factor)
        (SplittingFieldAux n f.removeFactor)
        (f.removeFactor.rootSet (SplittingFieldAux n f.removeFactor))
theorem adjoin_rootSet (n : ℕ) :
    ∀ {K : Type u} [Field K],
      ∀ (f : K[X]) (_hfn : f.natDegree = n),
        Algebra.adjoin K (f.rootSet (SplittingFieldAux n f)) = ⊤ :=
  Nat.recOn (motive := fun n =>
    ∀ {K : Type u} [Field K],
      ∀ (f : K[X]) (_hfn : f.natDegree = n),
        Algebra.adjoin K (f.rootSet (SplittingFieldAux n f)) = ⊤)
    n (fun {K} _ f _hf => Algebra.eq_top_iff.2 fun x => Subalgebra.range_le _ ⟨x, rfl⟩)
    fun n ih {K} _ f hfn => by
    have hndf : f.natDegree ≠ 0 := by intro h; rw [h] at hfn; cases hfn
    have hfn0 : f ≠ 0 := by intro h; rw [h] at hndf; exact hndf rfl
    have hmf0 : map (algebraMap K (SplittingFieldAux n.succ f)) f ≠ 0 := map_ne_zero hfn0
    rw [rootSet_def, aroots_def]
    rw [algebraMap_succ, ← map_map, ← X_sub_C_mul_removeFactor _ hndf, Polynomial.map_mul] at hmf0 ⊢
    -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
    erw [roots_mul hmf0, Polynomial.map_sub, map_X, map_C, roots_X_sub_C, Multiset.toFinset_add,
      Finset.coe_union, Multiset.toFinset_singleton, Finset.coe_singleton,
      Algebra.adjoin_union_eq_adjoin_adjoin, ← Set.image_singleton,
      Algebra.adjoin_algebraMap K (SplittingFieldAux n f.removeFactor),
      AdjoinRoot.adjoinRoot_eq_top, Algebra.map_top]
    /- Porting note: was `rw [IsScalarTower.adjoin_range_toAlgHom K (AdjoinRoot f.factor)
        (SplittingFieldAux n f.removeFactor)]` -/
    have := IsScalarTower.adjoin_range_toAlgHom K (AdjoinRoot f.factor)
        (SplittingFieldAux n f.removeFactor)
        (f.removeFactor.rootSet (SplittingFieldAux n f.removeFactor))
    

Proof state:
F : Type u
K✝¹ : Type v
L : Type w
inst✝³ : Field K✝¹
inst✝² : Field L
inst✝¹ : Field F
n✝ : ℕ
K✝ : Type u
inst✝ : Field K✝
n : ℕ
ih :
  (fun n =>
      ∀ {K : Type u} [inst : Field K] (f : K[X]),
        natDegree f = n → Algebra.adjoin K (rootSet f (SplittingFieldAux n f)) = ⊤)
    n
K : Type u
x✝ : Field K
f : K[X]
hfn : natDegree f = Nat.succ n
hndf : natDegree f ≠ 0
hfn0 : f ≠ 0
hmf0 :
  map (algebraMap (AdjoinRoot (factor f)) (SplittingFieldAux n (removeFactor f))) (X - C (AdjoinRoot.root (factor f))) *
      map (algebraMap (AdjoinRoot (factor f)) (SplittingFieldAux n (removeFactor f))) (removeFactor f) ≠
    0
this :
  Subalgebra.restrictScalars K
      (Algebra.adjoin
        (↥(AlgHom.range (IsScalarTower.toAlgHom K (AdjoinRoot (factor f)) (SplittingFieldAux n (removeFactor f)))))
        (rootSet (removeFactor f) (SplittingFieldAux n (removeFactor f)))) =
    Subalgebra.restrictScalars K
      (Algebra.adjoin (AdjoinRoot (factor f)) (rootSet (removeFactor f) (SplittingFieldAux n (removeFactor f))))
⊢ Subalgebra.restrictScalars K
      (Algebra.adjoin
        ↥(AlgHom.range (IsScalarTower.toAlgHom K (AdjoinRoot (factor f)) (SplittingFieldAux n (removeFactor f))))
        ↑(Multiset.toFinset
            (roots
              (map (algebraMap (AdjoinRoot (factor f)) (SplittingFieldAux n (removeFactor f))) (removeFactor f))))) =
    ⊤

Next tactic:
refine this.trans ?_
theorem adjoin_rootSet (n : ℕ) :
    ∀ {K : Type u} [Field K],
      ∀ (f : K[X]) (_hfn : f.natDegree = n),
        Algebra.adjoin K (f.rootSet (SplittingFieldAux n f)) = ⊤ :=
  Nat.recOn (motive := fun n =>
    ∀ {K : Type u} [Field K],
      ∀ (f : K[X]) (_hfn : f.natDegree = n),
        Algebra.adjoin K (f.rootSet (SplittingFieldAux n f)) = ⊤)
    n (fun {K} _ f _hf => Algebra.eq_top_iff.2 fun x => Subalgebra.range_le _ ⟨x, rfl⟩)
    fun n ih {K} _ f hfn => by
    have hndf : f.natDegree ≠ 0 := by intro h; rw [h] at hfn; cases hfn
    have hfn0 : f ≠ 0 := by intro h; rw [h] at hndf; exact hndf rfl
    have hmf0 : map (algebraMap K (SplittingFieldAux n.succ f)) f ≠ 0 := map_ne_zero hfn0
    rw [rootSet_def, aroots_def]
    rw [algebraMap_succ, ← map_map, ← X_sub_C_mul_removeFactor _ hndf, Polynomial.map_mul] at hmf0 ⊢
    -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
    erw [roots_mul hmf0, Polynomial.map_sub, map_X, map_C, roots_X_sub_C, Multiset.toFinset_add,
      Finset.coe_union, Multiset.toFinset_singleton, Finset.coe_singleton,
      Algebra.adjoin_union_eq_adjoin_adjoin, ← Set.image_singleton,
      Algebra.adjoin_algebraMap K (SplittingFieldAux n f.removeFactor),
      AdjoinRoot.adjoinRoot_eq_top, Algebra.map_top]
    /- Porting note: was `rw [IsScalarTower.adjoin_range_toAlgHom K (AdjoinRoot f.factor)
        (SplittingFieldAux n f.removeFactor)]` -/
    have := IsScalarTower.adjoin_range_toAlgHom K (AdjoinRoot f.factor)
        (SplittingFieldAux n f.removeFactor)
        (f.removeFactor.rootSet (SplittingFieldAux n f.removeFactor))
    refine this.trans ?_
    

Proof state:
F : Type u
K✝¹ : Type v
L : Type w
inst✝³ : Field K✝¹
inst✝² : Field L
inst✝¹ : Field F
n✝ : ℕ
K✝ : Type u
inst✝ : Field K✝
n : ℕ
ih :
  (fun n =>
      ∀ {K : Type u} [inst : Field K] (f : K[X]),
        natDegree f = n → Algebra.adjoin K (rootSet f (SplittingFieldAux n f)) = ⊤)
    n
K : Type u
x✝ : Field K
f : K[X]
hfn : natDegree f = Nat.succ n
hndf : natDegree f ≠ 0
hfn0 : f ≠ 0
hmf0 :
  map (algebraMap (AdjoinRoot (factor f)) (SplittingFieldAux n (removeFactor f))) (X - C (AdjoinRoot.root (factor f))) *
      map (algebraMap (AdjoinRoot (factor f)) (SplittingFieldAux n (removeFactor f))) (removeFactor f) ≠
    0
this :
  Subalgebra.restrictScalars K
      (Algebra.adjoin
        (↥(AlgHom.range (IsScalarTower.toAlgHom K (AdjoinRoot (factor f)) (SplittingFieldAux n (removeFactor f)))))
        (rootSet (removeFactor f) (SplittingFieldAux n (removeFactor f)))) =
    Subalgebra.restrictScalars K
      (Algebra.adjoin (AdjoinRoot (factor f)) (rootSet (removeFactor f) (SplittingFieldAux n (removeFactor f))))
⊢ Subalgebra.restrictScalars K
      (Algebra.adjoin (AdjoinRoot (factor f)) (rootSet (removeFactor f) (SplittingFieldAux n (removeFactor f)))) =
    ⊤

Next tactic:
rw [ih _ (natDegree_removeFactor' hfn), Subalgebra.restrictScalars_top]
/-- The algebra equivalence with `SplittingFieldAux`,
which we will use to construct the field structure. -/
def algEquivSplittingFieldAux (f : K[X]) : SplittingField f ≃ₐ[K] SplittingFieldAux f.natDegree f :=
  Ideal.quotientKerAlgEquivOfSurjective fun x => ⟨MvPolynomial.X x, by 

Proof state:
F : Type u
K : Type v
L : Type w
inst✝² : Field K
inst✝¹ : Field L
inst✝ : Field F
f✝ f : K[X]
x : SplittingFieldAux (natDegree f) f
⊢ (MvPolynomial.aeval id) (MvPolynomial.X x) = x

Next tactic:
simp
instance : Field (SplittingField f) :=
  let e := algEquivSplittingFieldAux f
  { toCommRing := SplittingField.commRing f
    ratCast := fun a => algebraMap K _ (a : K)
    inv := fun a => e.symm (e a)⁻¹
    qsmul := (· • ·)
    qsmul_eq_mul' := fun a x =>
      Quotient.inductionOn x (fun p => congr_arg Quotient.mk''
        (by ext; simp [MvPolynomial.algebraMap_eq, Rat.smul_def]))
    ratCast_mk := fun a b h1 h2 => by
      apply_fun e
      change e (algebraMap K _ _) = _
      simp only [map_ratCast, map_natCast, map_mul, map_intCast, AlgEquiv.commutes,
        AlgEquiv.apply_symm_apply]
      apply Field.ratCast_mk
    exists_pair_ne := ⟨e.symm 0, e.symm 1, fun w => zero_ne_one ((e.symm).injective w)⟩
    mul_inv_cancel := fun a w => by
      -- This could surely be golfed.
      

Proof state:
F : Type u
K : Type v
L : Type w
inst✝² : Field K
inst✝¹ : Field L
inst✝ : Field F
f : K[X]
e : SplittingField f ≃ₐ[K] SplittingFieldAux (natDegree f) f := algEquivSplittingFieldAux f
a : SplittingField f
w : a ≠ 0
⊢ a * a⁻¹ = 1

Next tactic:
apply_fun e
instance : Field (SplittingField f) :=
  let e := algEquivSplittingFieldAux f
  { toCommRing := SplittingField.commRing f
    ratCast := fun a => algebraMap K _ (a : K)
    inv := fun a => e.symm (e a)⁻¹
    qsmul := (· • ·)
    qsmul_eq_mul' := fun a x =>
      Quotient.inductionOn x (fun p => congr_arg Quotient.mk''
        (by ext; simp [MvPolynomial.algebraMap_eq, Rat.smul_def]))
    ratCast_mk := fun a b h1 h2 => by
      apply_fun e
      change e (algebraMap K _ _) = _
      simp only [map_ratCast, map_natCast, map_mul, map_intCast, AlgEquiv.commutes,
        AlgEquiv.apply_symm_apply]
      apply Field.ratCast_mk
    exists_pair_ne := ⟨e.symm 0, e.symm 1, fun w => zero_ne_one ((e.symm).injective w)⟩
    mul_inv_cancel := fun a w => by
      -- This could surely be golfed.
      apply_fun e
      

Proof state:
F : Type u
K : Type v
L : Type w
inst✝² : Field K
inst✝¹ : Field L
inst✝ : Field F
f : K[X]
e : SplittingField f ≃ₐ[K] SplittingFieldAux (natDegree f) f := algEquivSplittingFieldAux f
a : SplittingField f
w : a ≠ 0
⊢ e (a * a⁻¹) = e 1

Next tactic:
have : e a ≠ 0 := fun w' => by
        apply w
        simp? at w' says
          simp only [AddEquivClass.map_eq_zero_iff] at w'
        exact w'
instance : Field (SplittingField f) :=
  let e := algEquivSplittingFieldAux f
  { toCommRing := SplittingField.commRing f
    ratCast := fun a => algebraMap K _ (a : K)
    inv := fun a => e.symm (e a)⁻¹
    qsmul := (· • ·)
    qsmul_eq_mul' := fun a x =>
      Quotient.inductionOn x (fun p => congr_arg Quotient.mk''
        (by ext; simp [MvPolynomial.algebraMap_eq, Rat.smul_def]))
    ratCast_mk := fun a b h1 h2 => by
      apply_fun e
      change e (algebraMap K _ _) = _
      simp only [map_ratCast, map_natCast, map_mul, map_intCast, AlgEquiv.commutes,
        AlgEquiv.apply_symm_apply]
      apply Field.ratCast_mk
    exists_pair_ne := ⟨e.symm 0, e.symm 1, fun w => zero_ne_one ((e.symm).injective w)⟩
    mul_inv_cancel := fun a w => by
      -- This could surely be golfed.
      apply_fun e
      have : e a ≠ 0 := fun w' => by
        

Proof state:
F : Type u
K : Type v
L : Type w
inst✝² : Field K
inst✝¹ : Field L
inst✝ : Field F
f : K[X]
e : SplittingField f ≃ₐ[K] SplittingFieldAux (natDegree f) f := algEquivSplittingFieldAux f
a : SplittingField f
w : a ≠ 0
w' : e a = 0
⊢ False

Next tactic:
apply w
instance : Field (SplittingField f) :=
  let e := algEquivSplittingFieldAux f
  { toCommRing := SplittingField.commRing f
    ratCast := fun a => algebraMap K _ (a : K)
    inv := fun a => e.symm (e a)⁻¹
    qsmul := (· • ·)
    qsmul_eq_mul' := fun a x =>
      Quotient.inductionOn x (fun p => congr_arg Quotient.mk''
        (by ext; simp [MvPolynomial.algebraMap_eq, Rat.smul_def]))
    ratCast_mk := fun a b h1 h2 => by
      apply_fun e
      change e (algebraMap K _ _) = _
      simp only [map_ratCast, map_natCast, map_mul, map_intCast, AlgEquiv.commutes,
        AlgEquiv.apply_symm_apply]
      apply Field.ratCast_mk
    exists_pair_ne := ⟨e.symm 0, e.symm 1, fun w => zero_ne_one ((e.symm).injective w)⟩
    mul_inv_cancel := fun a w => by
      -- This could surely be golfed.
      apply_fun e
      have : e a ≠ 0 := fun w' => by
        apply w
        

Proof state:
F : Type u
K : Type v
L : Type w
inst✝² : Field K
inst✝¹ : Field L
inst✝ : Field F
f : K[X]
e : SplittingField f ≃ₐ[K] SplittingFieldAux (natDegree f) f := algEquivSplittingFieldAux f
a : SplittingField f
w : a ≠ 0
w' : e a = 0
⊢ a = 0

Next tactic:
simp? at w' says
          simp only [AddEquivClass.map_eq_zero_iff] at w'