l3lab/ntp-mathlib huggingface dataset:
/-- algebra isomorphism between `AdjoinRoot` and `F⟮α⟯` -/
noncomputable def adjoinRootEquivAdjoin (h : IsIntegral F α) :
    AdjoinRoot (minpoly F α) ≃ₐ[F] F⟮α⟯ :=
  AlgEquiv.ofBijective
    (AdjoinRoot.liftHom (minpoly F α) (AdjoinSimple.gen F α) (aeval_gen_minpoly F α))
    (by
      set f := AdjoinRoot.lift _ _ (aeval_gen_minpoly F α : _)
      haveI := Fact.mk (minpoly.irreducible h)
      constructor
      · exact RingHom.injective f
      · 

Proof state:
case right
F : Type u_1
inst✝⁴ : Field F
E : Type u_2
inst✝³ : Field E
inst✝² : Algebra F E
α : E
K : Type u_3
inst✝¹ : Field K
inst✝ : Algebra F K
h : IsIntegral F α
f : AdjoinRoot (minpoly F α) →+* ↥F⟮α⟯ :=
  AdjoinRoot.lift (↑(Algebra.ofId F ↥F⟮α⟯)) (AdjoinSimple.gen F α)
    (_ : (aeval (AdjoinSimple.gen F α)) (minpoly F α) = 0)
this : Fact (Irreducible (minpoly F α))
⊢ Function.Surjective
    ⇑(AdjoinRoot.liftHom (minpoly F α) (AdjoinSimple.gen F α) (_ : (aeval (AdjoinSimple.gen F α)) (minpoly F α) = 0))

Next tactic:
suffices F⟮α⟯.toSubfield ≤ RingHom.fieldRange (F⟮α⟯.toSubfield.subtype.comp f) by
          intro x
          obtain ⟨y, hy⟩ := (this (Subtype.mem x))
          exact ⟨y, Subtype.ext hy⟩
/-- algebra isomorphism between `AdjoinRoot` and `F⟮α⟯` -/
noncomputable def adjoinRootEquivAdjoin (h : IsIntegral F α) :
    AdjoinRoot (minpoly F α) ≃ₐ[F] F⟮α⟯ :=
  AlgEquiv.ofBijective
    (AdjoinRoot.liftHom (minpoly F α) (AdjoinSimple.gen F α) (aeval_gen_minpoly F α))
    (by
      set f := AdjoinRoot.lift _ _ (aeval_gen_minpoly F α : _)
      haveI := Fact.mk (minpoly.irreducible h)
      constructor
      · exact RingHom.injective f
      · suffices F⟮α⟯.toSubfield ≤ RingHom.fieldRange (F⟮α⟯.toSubfield.subtype.comp f) by
          

Proof state:
F : Type u_1
inst✝⁴ : Field F
E : Type u_2
inst✝³ : Field E
inst✝² : Algebra F E
α : E
K : Type u_3
inst✝¹ : Field K
inst✝ : Algebra F K
h : IsIntegral F α
f : AdjoinRoot (minpoly F α) →+* ↥F⟮α⟯ :=
  AdjoinRoot.lift (↑(Algebra.ofId F ↥F⟮α⟯)) (AdjoinSimple.gen F α)
    (_ : (aeval (AdjoinSimple.gen F α)) (minpoly F α) = 0)
this✝ : Fact (Irreducible (minpoly F α))
this : toSubfield F⟮α⟯ ≤ RingHom.fieldRange (RingHom.comp (Subfield.subtype (toSubfield F⟮α⟯)) f)
⊢ Function.Surjective
    ⇑(AdjoinRoot.liftHom (minpoly F α) (AdjoinSimple.gen F α) (_ : (aeval (AdjoinSimple.gen F α)) (minpoly F α) = 0))

Next tactic:
intro x
/-- algebra isomorphism between `AdjoinRoot` and `F⟮α⟯` -/
noncomputable def adjoinRootEquivAdjoin (h : IsIntegral F α) :
    AdjoinRoot (minpoly F α) ≃ₐ[F] F⟮α⟯ :=
  AlgEquiv.ofBijective
    (AdjoinRoot.liftHom (minpoly F α) (AdjoinSimple.gen F α) (aeval_gen_minpoly F α))
    (by
      set f := AdjoinRoot.lift _ _ (aeval_gen_minpoly F α : _)
      haveI := Fact.mk (minpoly.irreducible h)
      constructor
      · exact RingHom.injective f
      · suffices F⟮α⟯.toSubfield ≤ RingHom.fieldRange (F⟮α⟯.toSubfield.subtype.comp f) by
          intro x
          

Proof state:
F : Type u_1
inst✝⁴ : Field F
E : Type u_2
inst✝³ : Field E
inst✝² : Algebra F E
α : E
K : Type u_3
inst✝¹ : Field K
inst✝ : Algebra F K
h : IsIntegral F α
f : AdjoinRoot (minpoly F α) →+* ↥F⟮α⟯ :=
  AdjoinRoot.lift (↑(Algebra.ofId F ↥F⟮α⟯)) (AdjoinSimple.gen F α)
    (_ : (aeval (AdjoinSimple.gen F α)) (minpoly F α) = 0)
this✝ : Fact (Irreducible (minpoly F α))
this : toSubfield F⟮α⟯ ≤ RingHom.fieldRange (RingHom.comp (Subfield.subtype (toSubfield F⟮α⟯)) f)
x : ↥F⟮α⟯
⊢ ∃ a,
    (AdjoinRoot.liftHom (minpoly F α) (AdjoinSimple.gen F α) (_ : (aeval (AdjoinSimple.gen F α)) (minpoly F α) = 0)) a =
      x

Next tactic:
obtain ⟨y, hy⟩ := (this (Subtype.mem x))
/-- algebra isomorphism between `AdjoinRoot` and `F⟮α⟯` -/
noncomputable def adjoinRootEquivAdjoin (h : IsIntegral F α) :
    AdjoinRoot (minpoly F α) ≃ₐ[F] F⟮α⟯ :=
  AlgEquiv.ofBijective
    (AdjoinRoot.liftHom (minpoly F α) (AdjoinSimple.gen F α) (aeval_gen_minpoly F α))
    (by
      set f := AdjoinRoot.lift _ _ (aeval_gen_minpoly F α : _)
      haveI := Fact.mk (minpoly.irreducible h)
      constructor
      · exact RingHom.injective f
      · suffices F⟮α⟯.toSubfield ≤ RingHom.fieldRange (F⟮α⟯.toSubfield.subtype.comp f) by
          intro x
          obtain ⟨y, hy⟩ := (this (Subtype.mem x))
          

Proof state:
case intro
F : Type u_1
inst✝⁴ : Field F
E : Type u_2
inst✝³ : Field E
inst✝² : Algebra F E
α : E
K : Type u_3
inst✝¹ : Field K
inst✝ : Algebra F K
h : IsIntegral F α
f : AdjoinRoot (minpoly F α) →+* ↥F⟮α⟯ :=
  AdjoinRoot.lift (↑(Algebra.ofId F ↥F⟮α⟯)) (AdjoinSimple.gen F α)
    (_ : (aeval (AdjoinSimple.gen F α)) (minpoly F α) = 0)
this✝ : Fact (Irreducible (minpoly F α))
this : toSubfield F⟮α⟯ ≤ RingHom.fieldRange (RingHom.comp (Subfield.subtype (toSubfield F⟮α⟯)) f)
x : ↥F⟮α⟯
y : AdjoinRoot (minpoly F α)
hy : (RingHom.comp (Subfield.subtype (toSubfield F⟮α⟯)) f) y = ↑x
⊢ ∃ a,
    (AdjoinRoot.liftHom (minpoly F α) (AdjoinSimple.gen F α) (_ : (aeval (AdjoinSimple.gen F α)) (minpoly F α) = 0)) a =
      x

Next tactic:
exact ⟨y, Subtype.ext hy⟩
/-- algebra isomorphism between `AdjoinRoot` and `F⟮α⟯` -/
noncomputable def adjoinRootEquivAdjoin (h : IsIntegral F α) :
    AdjoinRoot (minpoly F α) ≃ₐ[F] F⟮α⟯ :=
  AlgEquiv.ofBijective
    (AdjoinRoot.liftHom (minpoly F α) (AdjoinSimple.gen F α) (aeval_gen_minpoly F α))
    (by
      set f := AdjoinRoot.lift _ _ (aeval_gen_minpoly F α : _)
      haveI := Fact.mk (minpoly.irreducible h)
      constructor
      · exact RingHom.injective f
      · suffices F⟮α⟯.toSubfield ≤ RingHom.fieldRange (F⟮α⟯.toSubfield.subtype.comp f) by
          intro x
          obtain ⟨y, hy⟩ := (this (Subtype.mem x))
          exact ⟨y, Subtype.ext hy⟩
        

Proof state:
case right
F : Type u_1
inst✝⁴ : Field F
E : Type u_2
inst✝³ : Field E
inst✝² : Algebra F E
α : E
K : Type u_3
inst✝¹ : Field K
inst✝ : Algebra F K
h : IsIntegral F α
f : AdjoinRoot (minpoly F α) →+* ↥F⟮α⟯ :=
  AdjoinRoot.lift (↑(Algebra.ofId F ↥F⟮α⟯)) (AdjoinSimple.gen F α)
    (_ : (aeval (AdjoinSimple.gen F α)) (minpoly F α) = 0)
this : Fact (Irreducible (minpoly F α))
⊢ toSubfield F⟮α⟯ ≤ RingHom.fieldRange (RingHom.comp (Subfield.subtype (toSubfield F⟮α⟯)) f)

Next tactic:
refine' Subfield.closure_le.mpr (Set.union_subset (fun x hx => _) _)
/-- algebra isomorphism between `AdjoinRoot` and `F⟮α⟯` -/
noncomputable def adjoinRootEquivAdjoin (h : IsIntegral F α) :
    AdjoinRoot (minpoly F α) ≃ₐ[F] F⟮α⟯ :=
  AlgEquiv.ofBijective
    (AdjoinRoot.liftHom (minpoly F α) (AdjoinSimple.gen F α) (aeval_gen_minpoly F α))
    (by
      set f := AdjoinRoot.lift _ _ (aeval_gen_minpoly F α : _)
      haveI := Fact.mk (minpoly.irreducible h)
      constructor
      · exact RingHom.injective f
      · suffices F⟮α⟯.toSubfield ≤ RingHom.fieldRange (F⟮α⟯.toSubfield.subtype.comp f) by
          intro x
          obtain ⟨y, hy⟩ := (this (Subtype.mem x))
          exact ⟨y, Subtype.ext hy⟩
        refine' Subfield.closure_le.mpr (Set.union_subset (fun x hx => _) _)
        · 

Proof state:
case right.refine'_1
F : Type u_1
inst✝⁴ : Field F
E : Type u_2
inst✝³ : Field E
inst✝² : Algebra F E
α : E
K : Type u_3
inst✝¹ : Field K
inst✝ : Algebra F K
h : IsIntegral F α
f : AdjoinRoot (minpoly F α) →+* ↥F⟮α⟯ :=
  AdjoinRoot.lift (↑(Algebra.ofId F ↥F⟮α⟯)) (AdjoinSimple.gen F α)
    (_ : (aeval (AdjoinSimple.gen F α)) (minpoly F α) = 0)
this : Fact (Irreducible (minpoly F α))
x : E
hx : x ∈ Set.range ⇑(algebraMap F E)
⊢ x ∈ ↑(RingHom.fieldRange (RingHom.comp (Subfield.subtype (toSubfield F⟮α⟯)) f))

Next tactic:
obtain ⟨y, hy⟩ := hx
/-- algebra isomorphism between `AdjoinRoot` and `F⟮α⟯` -/
noncomputable def adjoinRootEquivAdjoin (h : IsIntegral F α) :
    AdjoinRoot (minpoly F α) ≃ₐ[F] F⟮α⟯ :=
  AlgEquiv.ofBijective
    (AdjoinRoot.liftHom (minpoly F α) (AdjoinSimple.gen F α) (aeval_gen_minpoly F α))
    (by
      set f := AdjoinRoot.lift _ _ (aeval_gen_minpoly F α : _)
      haveI := Fact.mk (minpoly.irreducible h)
      constructor
      · exact RingHom.injective f
      · suffices F⟮α⟯.toSubfield ≤ RingHom.fieldRange (F⟮α⟯.toSubfield.subtype.comp f) by
          intro x
          obtain ⟨y, hy⟩ := (this (Subtype.mem x))
          exact ⟨y, Subtype.ext hy⟩
        refine' Subfield.closure_le.mpr (Set.union_subset (fun x hx => _) _)
        · obtain ⟨y, hy⟩ := hx
          

Proof state:
case right.refine'_1.intro
F : Type u_1
inst✝⁴ : Field F
E : Type u_2
inst✝³ : Field E
inst✝² : Algebra F E
α : E
K : Type u_3
inst✝¹ : Field K
inst✝ : Algebra F K
h : IsIntegral F α
f : AdjoinRoot (minpoly F α) →+* ↥F⟮α⟯ :=
  AdjoinRoot.lift (↑(Algebra.ofId F ↥F⟮α⟯)) (AdjoinSimple.gen F α)
    (_ : (aeval (AdjoinSimple.gen F α)) (minpoly F α) = 0)
this : Fact (Irreducible (minpoly F α))
x : E
y : F
hy : (algebraMap F E) y = x
⊢ x ∈ ↑(RingHom.fieldRange (RingHom.comp (Subfield.subtype (toSubfield F⟮α⟯)) f))

Next tactic:
refine' ⟨y, _⟩
/-- algebra isomorphism between `AdjoinRoot` and `F⟮α⟯` -/
noncomputable def adjoinRootEquivAdjoin (h : IsIntegral F α) :
    AdjoinRoot (minpoly F α) ≃ₐ[F] F⟮α⟯ :=
  AlgEquiv.ofBijective
    (AdjoinRoot.liftHom (minpoly F α) (AdjoinSimple.gen F α) (aeval_gen_minpoly F α))
    (by
      set f := AdjoinRoot.lift _ _ (aeval_gen_minpoly F α : _)
      haveI := Fact.mk (minpoly.irreducible h)
      constructor
      · exact RingHom.injective f
      · suffices F⟮α⟯.toSubfield ≤ RingHom.fieldRange (F⟮α⟯.toSubfield.subtype.comp f) by
          intro x
          obtain ⟨y, hy⟩ := (this (Subtype.mem x))
          exact ⟨y, Subtype.ext hy⟩
        refine' Subfield.closure_le.mpr (Set.union_subset (fun x hx => _) _)
        · obtain ⟨y, hy⟩ := hx
          refine' ⟨y, _⟩
          -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
          

Proof state:
case right.refine'_1.intro
F : Type u_1
inst✝⁴ : Field F
E : Type u_2
inst✝³ : Field E
inst✝² : Algebra F E
α : E
K : Type u_3
inst✝¹ : Field K
inst✝ : Algebra F K
h : IsIntegral F α
f : AdjoinRoot (minpoly F α) →+* ↥F⟮α⟯ :=
  AdjoinRoot.lift (↑(Algebra.ofId F ↥F⟮α⟯)) (AdjoinSimple.gen F α)
    (_ : (aeval (AdjoinSimple.gen F α)) (minpoly F α) = 0)
this : Fact (Irreducible (minpoly F α))
x : E
y : F
hy : (algebraMap F E) y = x
⊢ (RingHom.comp (Subfield.subtype (toSubfield F⟮α⟯)) f) ((AdjoinRoot.of (minpoly F α)) y) = x

Next tactic:
erw [RingHom.comp_apply, AdjoinRoot.lift_of (aeval_gen_minpoly F α)]
/-- algebra isomorphism between `AdjoinRoot` and `F⟮α⟯` -/
noncomputable def adjoinRootEquivAdjoin (h : IsIntegral F α) :
    AdjoinRoot (minpoly F α) ≃ₐ[F] F⟮α⟯ :=
  AlgEquiv.ofBijective
    (AdjoinRoot.liftHom (minpoly F α) (AdjoinSimple.gen F α) (aeval_gen_minpoly F α))
    (by
      set f := AdjoinRoot.lift _ _ (aeval_gen_minpoly F α : _)
      haveI := Fact.mk (minpoly.irreducible h)
      constructor
      · exact RingHom.injective f
      · suffices F⟮α⟯.toSubfield ≤ RingHom.fieldRange (F⟮α⟯.toSubfield.subtype.comp f) by
          intro x
          obtain ⟨y, hy⟩ := (this (Subtype.mem x))
          exact ⟨y, Subtype.ext hy⟩
        refine' Subfield.closure_le.mpr (Set.union_subset (fun x hx => _) _)
        · obtain ⟨y, hy⟩ := hx
          refine' ⟨y, _⟩
          -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
          erw [RingHom.comp_apply, AdjoinRoot.lift_of (aeval_gen_minpoly F α)]
          

Proof state:
case right.refine'_1.intro
F : Type u_1
inst✝⁴ : Field F
E : Type u_2
inst✝³ : Field E
inst✝² : Algebra F E
α : E
K : Type u_3
inst✝¹ : Field K
inst✝ : Algebra F K
h : IsIntegral F α
f : AdjoinRoot (minpoly F α) →+* ↥F⟮α⟯ :=
  AdjoinRoot.lift (↑(Algebra.ofId F ↥F⟮α⟯)) (AdjoinSimple.gen F α)
    (_ : (aeval (AdjoinSimple.gen F α)) (minpoly F α) = 0)
this : Fact (Irreducible (minpoly F α))
x : E
y : F
hy : (algebraMap F E) y = x
⊢ (Subfield.subtype (toSubfield F⟮α⟯)) (↑(Algebra.ofId F ↥F⟮α⟯) y) = x

Next tactic:
exact hy
/-- algebra isomorphism between `AdjoinRoot` and `F⟮α⟯` -/
noncomputable def adjoinRootEquivAdjoin (h : IsIntegral F α) :
    AdjoinRoot (minpoly F α) ≃ₐ[F] F⟮α⟯ :=
  AlgEquiv.ofBijective
    (AdjoinRoot.liftHom (minpoly F α) (AdjoinSimple.gen F α) (aeval_gen_minpoly F α))
    (by
      set f := AdjoinRoot.lift _ _ (aeval_gen_minpoly F α : _)
      haveI := Fact.mk (minpoly.irreducible h)
      constructor
      · exact RingHom.injective f
      · suffices F⟮α⟯.toSubfield ≤ RingHom.fieldRange (F⟮α⟯.toSubfield.subtype.comp f) by
          intro x
          obtain ⟨y, hy⟩ := (this (Subtype.mem x))
          exact ⟨y, Subtype.ext hy⟩
        refine' Subfield.closure_le.mpr (Set.union_subset (fun x hx => _) _)
        · obtain ⟨y, hy⟩ := hx
          refine' ⟨y, _⟩
          -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
          erw [RingHom.comp_apply, AdjoinRoot.lift_of (aeval_gen_minpoly F α)]
          exact hy
        · 

Proof state:
case right.refine'_2
F : Type u_1
inst✝⁴ : Field F
E : Type u_2
inst✝³ : Field E
inst✝² : Algebra F E
α : E
K : Type u_3
inst✝¹ : Field K
inst✝ : Algebra F K
h : IsIntegral F α
f : AdjoinRoot (minpoly F α) →+* ↥F⟮α⟯ :=
  AdjoinRoot.lift (↑(Algebra.ofId F ↥F⟮α⟯)) (AdjoinSimple.gen F α)
    (_ : (aeval (AdjoinSimple.gen F α)) (minpoly F α) = 0)
this : Fact (Irreducible (minpoly F α))
⊢ {α} ⊆ ↑(RingHom.fieldRange (RingHom.comp (Subfield.subtype (toSubfield F⟮α⟯)) f))

Next tactic:
refine' Set.singleton_subset_iff.mpr ⟨AdjoinRoot.root (minpoly F α), _⟩
/-- algebra isomorphism between `AdjoinRoot` and `F⟮α⟯` -/
noncomputable def adjoinRootEquivAdjoin (h : IsIntegral F α) :
    AdjoinRoot (minpoly F α) ≃ₐ[F] F⟮α⟯ :=
  AlgEquiv.ofBijective
    (AdjoinRoot.liftHom (minpoly F α) (AdjoinSimple.gen F α) (aeval_gen_minpoly F α))
    (by
      set f := AdjoinRoot.lift _ _ (aeval_gen_minpoly F α : _)
      haveI := Fact.mk (minpoly.irreducible h)
      constructor
      · exact RingHom.injective f
      · suffices F⟮α⟯.toSubfield ≤ RingHom.fieldRange (F⟮α⟯.toSubfield.subtype.comp f) by
          intro x
          obtain ⟨y, hy⟩ := (this (Subtype.mem x))
          exact ⟨y, Subtype.ext hy⟩
        refine' Subfield.closure_le.mpr (Set.union_subset (fun x hx => _) _)
        · obtain ⟨y, hy⟩ := hx
          refine' ⟨y, _⟩
          -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
          erw [RingHom.comp_apply, AdjoinRoot.lift_of (aeval_gen_minpoly F α)]
          exact hy
        · refine' Set.singleton_subset_iff.mpr ⟨AdjoinRoot.root (minpoly F α), _⟩
          -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
          

Proof state:
case right.refine'_2
F : Type u_1
inst✝⁴ : Field F
E : Type u_2
inst✝³ : Field E
inst✝² : Algebra F E
α : E
K : Type u_3
inst✝¹ : Field K
inst✝ : Algebra F K
h : IsIntegral F α
f : AdjoinRoot (minpoly F α) →+* ↥F⟮α⟯ :=
  AdjoinRoot.lift (↑(Algebra.ofId F ↥F⟮α⟯)) (AdjoinSimple.gen F α)
    (_ : (aeval (AdjoinSimple.gen F α)) (minpoly F α) = 0)
this : Fact (Irreducible (minpoly F α))
⊢ (RingHom.comp (Subfield.subtype (toSubfield F⟮α⟯)) f) (AdjoinRoot.root (minpoly F α)) = α

Next tactic:
erw [RingHom.comp_apply, AdjoinRoot.lift_root (aeval_gen_minpoly F α)]
/-- algebra isomorphism between `AdjoinRoot` and `F⟮α⟯` -/
noncomputable def adjoinRootEquivAdjoin (h : IsIntegral F α) :
    AdjoinRoot (minpoly F α) ≃ₐ[F] F⟮α⟯ :=
  AlgEquiv.ofBijective
    (AdjoinRoot.liftHom (minpoly F α) (AdjoinSimple.gen F α) (aeval_gen_minpoly F α))
    (by
      set f := AdjoinRoot.lift _ _ (aeval_gen_minpoly F α : _)
      haveI := Fact.mk (minpoly.irreducible h)
      constructor
      · exact RingHom.injective f
      · suffices F⟮α⟯.toSubfield ≤ RingHom.fieldRange (F⟮α⟯.toSubfield.subtype.comp f) by
          intro x
          obtain ⟨y, hy⟩ := (this (Subtype.mem x))
          exact ⟨y, Subtype.ext hy⟩
        refine' Subfield.closure_le.mpr (Set.union_subset (fun x hx => _) _)
        · obtain ⟨y, hy⟩ := hx
          refine' ⟨y, _⟩
          -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
          erw [RingHom.comp_apply, AdjoinRoot.lift_of (aeval_gen_minpoly F α)]
          exact hy
        · refine' Set.singleton_subset_iff.mpr ⟨AdjoinRoot.root (minpoly F α), _⟩
          -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
          erw [RingHom.comp_apply, AdjoinRoot.lift_root (aeval_gen_minpoly F α)]
          

Proof state:
case right.refine'_2
F : Type u_1
inst✝⁴ : Field F
E : Type u_2
inst✝³ : Field E
inst✝² : Algebra F E
α : E
K : Type u_3
inst✝¹ : Field K
inst✝ : Algebra F K
h : IsIntegral F α
f : AdjoinRoot (minpoly F α) →+* ↥F⟮α⟯ :=
  AdjoinRoot.lift (↑(Algebra.ofId F ↥F⟮α⟯)) (AdjoinSimple.gen F α)
    (_ : (aeval (AdjoinSimple.gen F α)) (minpoly F α) = 0)
this : Fact (Irreducible (minpoly F α))
⊢ (Subfield.subtype (toSubfield F⟮α⟯)) (AdjoinSimple.gen F α) = α

Next tactic:
rfl
/-- The power basis `1, x, ..., x ^ (d - 1)` for `K⟮x⟯`,
where `d` is the degree of the minimal polynomial of `x`. -/
@[simps]
noncomputable def adjoin.powerBasis {x : L} (hx : IsIntegral K x) : PowerBasis K K⟮x⟯ where
  gen := AdjoinSimple.gen K x
  dim := (minpoly K x).natDegree
  basis := powerBasisAux hx
  basis_eq_pow i := by
    -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
    

Proof state:
F : Type u_1
inst✝⁶ : Field F
E : Type u_2
inst✝⁵ : Field E
inst✝⁴ : Algebra F E
α : E
K : Type u_3
inst✝³ : Field K
inst✝² : Algebra F K
L : Type u_4
inst✝¹ : Field L
inst✝ : Algebra K L
x : L
hx : IsIntegral K x
i : Fin (natDegree (minpoly K x))
⊢ (powerBasisAux hx) i = AdjoinSimple.gen K x ^ ↑i

Next tactic:
erw [powerBasisAux, Basis.map_apply, PowerBasis.basis_eq_pow, AlgEquiv.toLinearEquiv_apply,
      AlgEquiv.map_pow, AdjoinRoot.powerBasis_gen, adjoinRootEquivAdjoin_apply_root]
theorem adjoin.finrank {x : L} (hx : IsIntegral K x) :
    FiniteDimensional.finrank K K⟮x⟯ = (minpoly K x).natDegree := by
  

Proof state:
F : Type u_1
inst✝⁶ : Field F
E : Type u_2
inst✝⁵ : Field E
inst✝⁴ : Algebra F E
α : E
K : Type u_3
inst✝³ : Field K
inst✝² : Algebra F K
L : Type u_4
inst✝¹ : Field L
inst✝ : Algebra K L
x : L
hx : IsIntegral K x
⊢ FiniteDimensional.finrank K ↥K⟮x⟯ = natDegree (minpoly K x)

Next tactic:
rw [PowerBasis.finrank (adjoin.powerBasis hx : _)]
theorem adjoin.finrank {x : L} (hx : IsIntegral K x) :
    FiniteDimensional.finrank K K⟮x⟯ = (minpoly K x).natDegree := by
  rw [PowerBasis.finrank (adjoin.powerBasis hx : _)]
  

Proof state:
F : Type u_1
inst✝⁶ : Field F
E : Type u_2
inst✝⁵ : Field E
inst✝⁴ : Algebra F E
α : E
K : Type u_3
inst✝³ : Field K
inst✝² : Algebra F K
L : Type u_4
inst✝¹ : Field L
inst✝ : Algebra K L
x : L
hx : IsIntegral K x
⊢ (powerBasis hx).dim = natDegree (minpoly K x)

Next tactic:
rfl
/-- If `K / E / F` is a field extension tower, `S ⊂ K` is such that `F(S) = K`,
then `E(S) = K`. -/
theorem adjoin_eq_top_of_adjoin_eq_top [Algebra E K] [IsScalarTower F E K]
    {S : Set K} (hprim : adjoin F S = ⊤) : adjoin E S = ⊤ :=
  restrictScalars_injective F <| by
    

Proof state:
F : Type u_1
inst✝⁸ : Field F
E : Type u_2
inst✝⁷ : Field E
inst✝⁶ : Algebra F E
α : E
K : Type u_3
inst✝⁵ : Field K
inst✝⁴ : Algebra F K
L : Type u_4
inst✝³ : Field L
inst✝² : Algebra K L
inst✝¹ : Algebra E K
inst✝ : IsScalarTower F E K
S : Set K
hprim : adjoin F S = ⊤
⊢ restrictScalars F (adjoin E S) = restrictScalars F ⊤

Next tactic:
rw [restrictScalars_top, ← top_le_iff, ← hprim, adjoin_le_iff,
      coe_restrictScalars, ← adjoin_le_iff]
/-- If `E / F` is a finite extension such that `E = F(α)`, then for any intermediate field `K`, the
`F` adjoin the coefficients of `minpoly K α` is equal to `K` itself. -/
theorem adjoin_minpoly_coeff_of_exists_primitive_element
    [FiniteDimensional F E] (hprim : adjoin F {α} = ⊤) (K : IntermediateField F E) :
    adjoin F ((minpoly K α).map (algebraMap K E)).frange = K := by
  

Proof state:
F : Type u_1
inst✝⁷ : Field F
E : Type u_2
inst✝⁶ : Field E
inst✝⁵ : Algebra F E
α : E
K✝ : Type u_3
inst✝⁴ : Field K✝
inst✝³ : Algebra F K✝
L : Type u_4
inst✝² : Field L
inst✝¹ : Algebra K✝ L
inst✝ : FiniteDimensional F E
hprim : F⟮α⟯ = ⊤
K : IntermediateField F E
⊢ adjoin F ↑(frange (Polynomial.map (algebraMap (↥K) E) (minpoly (↥K) α))) = K

Next tactic:
set g := (minpoly K α).map (algebraMap K E)
/-- If `E / F` is a finite extension such that `E = F(α)`, then for any intermediate field `K`, the
`F` adjoin the coefficients of `minpoly K α` is equal to `K` itself. -/
theorem adjoin_minpoly_coeff_of_exists_primitive_element
    [FiniteDimensional F E] (hprim : adjoin F {α} = ⊤) (K : IntermediateField F E) :
    adjoin F ((minpoly K α).map (algebraMap K E)).frange = K := by
  set g := (minpoly K α).map (algebraMap K E)
  

Proof state:
F : Type u_1
inst✝⁷ : Field F
E : Type u_2
inst✝⁶ : Field E
inst✝⁵ : Algebra F E
α : E
K✝ : Type u_3
inst✝⁴ : Field K✝
inst✝³ : Algebra F K✝
L : Type u_4
inst✝² : Field L
inst✝¹ : Algebra K✝ L
inst✝ : FiniteDimensional F E
hprim : F⟮α⟯ = ⊤
K : IntermediateField F E
g : E[X] := Polynomial.map (algebraMap (↥K) E) (minpoly (↥K) α)
⊢ adjoin F ↑(frange g) = K

Next tactic:
set K' : IntermediateField F E := adjoin F g.frange
/-- If `E / F` is a finite extension such that `E = F(α)`, then for any intermediate field `K`, the
`F` adjoin the coefficients of `minpoly K α` is equal to `K` itself. -/
theorem adjoin_minpoly_coeff_of_exists_primitive_element
    [FiniteDimensional F E] (hprim : adjoin F {α} = ⊤) (K : IntermediateField F E) :
    adjoin F ((minpoly K α).map (algebraMap K E)).frange = K := by
  set g := (minpoly K α).map (algebraMap K E)
  set K' : IntermediateField F E := adjoin F g.frange
  

Proof state:
F : Type u_1
inst✝⁷ : Field F
E : Type u_2
inst✝⁶ : Field E
inst✝⁵ : Algebra F E
α : E
K✝ : Type u_3
inst✝⁴ : Field K✝
inst✝³ : Algebra F K✝
L : Type u_4
inst✝² : Field L
inst✝¹ : Algebra K✝ L
inst✝ : FiniteDimensional F E
hprim : F⟮α⟯ = ⊤
K : IntermediateField F E
g : E[X] := Polynomial.map (algebraMap (↥K) E) (minpoly (↥K) α)
K' : IntermediateField F E := adjoin F ↑(frange g)
⊢ K' = K

Next tactic:
have hsub : K' ≤ K := by
    refine adjoin_le_iff.mpr fun x ↦ ?_
    rw [Finset.mem_coe, mem_frange_iff]
    rintro ⟨n, -, rfl⟩
    rw [coeff_map]
    apply Subtype.mem
/-- If `E / F` is a finite extension such that `E = F(α)`, then for any intermediate field `K`, the
`F` adjoin the coefficients of `minpoly K α` is equal to `K` itself. -/
theorem adjoin_minpoly_coeff_of_exists_primitive_element
    [FiniteDimensional F E] (hprim : adjoin F {α} = ⊤) (K : IntermediateField F E) :
    adjoin F ((minpoly K α).map (algebraMap K E)).frange = K := by
  set g := (minpoly K α).map (algebraMap K E)
  set K' : IntermediateField F E := adjoin F g.frange
  have hsub : K' ≤ K := by
    

Proof state:
F : Type u_1
inst✝⁷ : Field F
E : Type u_2
inst✝⁶ : Field E
inst✝⁵ : Algebra F E
α : E
K✝ : Type u_3
inst✝⁴ : Field K✝
inst✝³ : Algebra F K✝
L : Type u_4
inst✝² : Field L
inst✝¹ : Algebra K✝ L
inst✝ : FiniteDimensional F E
hprim : F⟮α⟯ = ⊤
K : IntermediateField F E
g : E[X] := Polynomial.map (algebraMap (↥K) E) (minpoly (↥K) α)
K' : IntermediateField F E := adjoin F ↑(frange g)
⊢ K' ≤ K

Next tactic:
refine adjoin_le_iff.mpr fun x ↦ ?_
/-- If `E / F` is a finite extension such that `E = F(α)`, then for any intermediate field `K`, the
`F` adjoin the coefficients of `minpoly K α` is equal to `K` itself. -/
theorem adjoin_minpoly_coeff_of_exists_primitive_element
    [FiniteDimensional F E] (hprim : adjoin F {α} = ⊤) (K : IntermediateField F E) :
    adjoin F ((minpoly K α).map (algebraMap K E)).frange = K := by
  set g := (minpoly K α).map (algebraMap K E)
  set K' : IntermediateField F E := adjoin F g.frange
  have hsub : K' ≤ K := by
    refine adjoin_le_iff.mpr fun x ↦ ?_
    

Proof state:
F : Type u_1
inst✝⁷ : Field F
E : Type u_2
inst✝⁶ : Field E
inst✝⁵ : Algebra F E
α : E
K✝ : Type u_3
inst✝⁴ : Field K✝
inst✝³ : Algebra F K✝
L : Type u_4
inst✝² : Field L
inst✝¹ : Algebra K✝ L
inst✝ : FiniteDimensional F E
hprim : F⟮α⟯ = ⊤
K : IntermediateField F E
g : E[X] := Polynomial.map (algebraMap (↥K) E) (minpoly (↥K) α)
K' : IntermediateField F E := adjoin F ↑(frange g)
x : E
⊢ x ∈ ↑(frange g) → x ∈ ↑K

Next tactic:
rw [Finset.mem_coe, mem_frange_iff]