l3lab/ntp-mathlib huggingface dataset:
theorem coeff_root_pow (h : IsAdjoinRootMonic S f) {n} (hn : n < natDegree f) :
    h.coeff (h.root ^ n) = Pi.single n 1 := by
  ext i
  rw [coeff_apply]
  split_ifs with hi
  · calc
      h.basis.repr (h.root ^ n) ⟨i, _⟩ = h.basis.repr (h.basis ⟨n, hn⟩) ⟨i, hi⟩ := by
        rw [h.basis_apply, Fin.val_mk]
      _ = Pi.single (f := fun _ => R) ((⟨n, hn⟩ : Fin _) : ℕ) (1 : (fun _ => R) n)
        ↑(⟨i, _⟩ : Fin _) := by
        rw [h.basis.repr_self, ← Finsupp.single_eq_pi_single,
          Finsupp.single_apply_left Fin.val_injective]
      _ = Pi.single (f := fun _ => R) n 1 i := by rw [Fin.val_mk, Fin.val_mk]
  · refine (Pi.single_eq_of_ne (f := fun _ => R) ?_ (1 : (fun _ => R) n)).symm
    rintro rfl
    

Proof state:
case neg
R : Type u
S : Type v
inst✝² : CommRing R
inst✝¹ : Ring S
f : R[X]
inst✝ : Algebra R S
h : IsAdjoinRootMonic S f
i : ℕ
hi : ¬i < natDegree f
hn : i < natDegree f
⊢ False

Next tactic:
simp [hi] at hn
theorem coeff_one [Nontrivial S] (h : IsAdjoinRootMonic S f) : h.coeff 1 = Pi.single 0 1 := by
  

Proof state:
R : Type u
S : Type v
inst✝³ : CommRing R
inst✝² : Ring S
f : R[X]
inst✝¹ : Algebra R S
inst✝ : Nontrivial S
h : IsAdjoinRootMonic S f
⊢ (coeff h) 1 = Pi.single 0 1

Next tactic:
rw [← h.coeff_root_pow h.deg_pos, pow_zero]
theorem coeff_root (h : IsAdjoinRootMonic S f) (hdeg : 1 < natDegree f) :
    h.coeff h.root = Pi.single 1 1 := by 

Proof state:
R : Type u
S : Type v
inst✝² : CommRing R
inst✝¹ : Ring S
f : R[X]
inst✝ : Algebra R S
h : IsAdjoinRootMonic S f
hdeg : 1 < natDegree f
⊢ (coeff h) (root h.toIsAdjoinRoot) = Pi.single 1 1

Next tactic:
rw [← h.coeff_root_pow hdeg, pow_one]
theorem coeff_algebraMap [Nontrivial S] (h : IsAdjoinRootMonic S f) (x : R) :
    h.coeff (algebraMap R S x) = Pi.single 0 x := by
  

Proof state:
R : Type u
S : Type v
inst✝³ : CommRing R
inst✝² : Ring S
f : R[X]
inst✝¹ : Algebra R S
inst✝ : Nontrivial S
h : IsAdjoinRootMonic S f
x : R
⊢ (coeff h) ((algebraMap R S) x) = Pi.single 0 x

Next tactic:
ext i
theorem coeff_algebraMap [Nontrivial S] (h : IsAdjoinRootMonic S f) (x : R) :
    h.coeff (algebraMap R S x) = Pi.single 0 x := by
  ext i
  

Proof state:
case h
R : Type u
S : Type v
inst✝³ : CommRing R
inst✝² : Ring S
f : R[X]
inst✝¹ : Algebra R S
inst✝ : Nontrivial S
h : IsAdjoinRootMonic S f
x : R
i : ℕ
⊢ (coeff h) ((algebraMap R S) x) i = Pi.single 0 x i

Next tactic:
rw [Algebra.algebraMap_eq_smul_one, map_smul, coeff_one, Pi.smul_apply, smul_eq_mul]
theorem coeff_algebraMap [Nontrivial S] (h : IsAdjoinRootMonic S f) (x : R) :
    h.coeff (algebraMap R S x) = Pi.single 0 x := by
  ext i
  rw [Algebra.algebraMap_eq_smul_one, map_smul, coeff_one, Pi.smul_apply, smul_eq_mul]
  

Proof state:
case h
R : Type u
S : Type v
inst✝³ : CommRing R
inst✝² : Ring S
f : R[X]
inst✝¹ : Algebra R S
inst✝ : Nontrivial S
h : IsAdjoinRootMonic S f
x : R
i : ℕ
⊢ x * Pi.single 0 1 i = Pi.single 0 x i

Next tactic:
refine' (Pi.apply_single (fun _ y => x * y) _ 0 1 i).trans (by simp)
theorem coeff_algebraMap [Nontrivial S] (h : IsAdjoinRootMonic S f) (x : R) :
    h.coeff (algebraMap R S x) = Pi.single 0 x := by
  ext i
  rw [Algebra.algebraMap_eq_smul_one, map_smul, coeff_one, Pi.smul_apply, smul_eq_mul]
  refine' (Pi.apply_single (fun _ y => x * y) _ 0 1 i).trans (by 

Proof state:
R : Type u
S : Type v
inst✝³ : CommRing R
inst✝² : Ring S
f : R[X]
inst✝¹ : Algebra R S
inst✝ : Nontrivial S
h : IsAdjoinRootMonic S f
x : R
i : ℕ
⊢ Pi.single 0 (x * 1) i = Pi.single 0 x i

Next tactic:
simp
theorem coeff_algebraMap [Nontrivial S] (h : IsAdjoinRootMonic S f) (x : R) :
    h.coeff (algebraMap R S x) = Pi.single 0 x := by
  ext i
  rw [Algebra.algebraMap_eq_smul_one, map_smul, coeff_one, Pi.smul_apply, smul_eq_mul]
  refine' (Pi.apply_single (fun _ y => x * y) _ 0 1 i).trans (by simp)
  

Proof state:
case h
R : Type u
S : Type v
inst✝³ : CommRing R
inst✝² : Ring S
f : R[X]
inst✝¹ : Algebra R S
inst✝ : Nontrivial S
h : IsAdjoinRootMonic S f
x : R
i : ℕ
⊢ ∀ (i : ℕ), (fun x_1 y => x * y) i 0 = 0

Next tactic:
intros
theorem coeff_algebraMap [Nontrivial S] (h : IsAdjoinRootMonic S f) (x : R) :
    h.coeff (algebraMap R S x) = Pi.single 0 x := by
  ext i
  rw [Algebra.algebraMap_eq_smul_one, map_smul, coeff_one, Pi.smul_apply, smul_eq_mul]
  refine' (Pi.apply_single (fun _ y => x * y) _ 0 1 i).trans (by simp)
  intros
  

Proof state:
case h
R : Type u
S : Type v
inst✝³ : CommRing R
inst✝² : Ring S
f : R[X]
inst✝¹ : Algebra R S
inst✝ : Nontrivial S
h : IsAdjoinRootMonic S f
x : R
i i✝ : ℕ
⊢ (fun x_1 y => x * y) i✝ 0 = 0

Next tactic:
simp
theorem ext_elem (h : IsAdjoinRootMonic S f) ⦃x y : S⦄
    (hxy : ∀ i < natDegree f, h.coeff x i = h.coeff y i) : x = y :=
  EquivLike.injective h.basis.equivFun <|
    funext fun i => by
      

Proof state:
R : Type u
S : Type v
inst✝² : CommRing R
inst✝¹ : Ring S
f : R[X]
inst✝ : Algebra R S
h : IsAdjoinRootMonic S f
x y : S
hxy : ∀ i < natDegree f, (coeff h) x i = (coeff h) y i
i : Fin (natDegree f)
⊢ (Basis.equivFun (basis h)) x i = (Basis.equivFun (basis h)) y i

Next tactic:
rw [Basis.equivFun_apply, ← h.coeff_apply_coe, Basis.equivFun_apply, ← h.coeff_apply_coe,
        hxy i i.prop]
@[simp]
theorem lift_self_apply (h : IsAdjoinRoot S f) (x : S) :
    h.lift (algebraMap R S) h.root h.aeval_root x = x := by
  

Proof state:
R : Type u
S : Type v
inst✝² : CommRing R
inst✝¹ : CommRing S
inst✝ : Algebra R S
f : R[X]
h : IsAdjoinRoot S f
x : S
⊢ (lift (algebraMap R S) (root h) (_ : (aeval (root h)) f = 0) h) x = x

Next tactic:
rw [← h.map_repr x, lift_map, ← aeval_def, h.aeval_eq]
/-- Adjoining a root gives a unique ring up to algebra isomorphism.

This is the converse of `IsAdjoinRoot.ofEquiv`: this turns an `IsAdjoinRoot` into an
`AlgEquiv`, and `IsAdjoinRoot.ofEquiv` turns an `AlgEquiv` into an `IsAdjoinRoot`.
-/
def aequiv (h : IsAdjoinRoot S f) (h' : IsAdjoinRoot T f) : S ≃ₐ[R] T :=
  { h.liftHom h'.root h'.aeval_root with
    toFun := h.liftHom h'.root h'.aeval_root
    invFun := h'.liftHom h.root h.aeval_root
    left_inv := fun x => by 

Proof state:
R : Type u
S : Type v
inst✝⁴ : CommRing R
inst✝³ : CommRing S
inst✝² : Algebra R S
f : R[X]
T : Type u_1
inst✝¹ : CommRing T
inst✝ : Algebra R T
h : IsAdjoinRoot S f
h' : IsAdjoinRoot T f
src✝ : S →ₐ[R] T := liftHom (root h') (_ : (aeval (root h')) f = 0) h
x : S
⊢ (liftHom (root h) (_ : (aeval (root h)) f = 0) h') ((liftHom (root h') (_ : (aeval (root h')) f = 0) h) x) = x

Next tactic:
rw [← h.map_repr x, liftHom_map, aeval_eq, liftHom_map, aeval_eq]
/-- Adjoining a root gives a unique ring up to algebra isomorphism.

This is the converse of `IsAdjoinRoot.ofEquiv`: this turns an `IsAdjoinRoot` into an
`AlgEquiv`, and `IsAdjoinRoot.ofEquiv` turns an `AlgEquiv` into an `IsAdjoinRoot`.
-/
def aequiv (h : IsAdjoinRoot S f) (h' : IsAdjoinRoot T f) : S ≃ₐ[R] T :=
  { h.liftHom h'.root h'.aeval_root with
    toFun := h.liftHom h'.root h'.aeval_root
    invFun := h'.liftHom h.root h.aeval_root
    left_inv := fun x => by rw [← h.map_repr x, liftHom_map, aeval_eq, liftHom_map, aeval_eq]
    right_inv := fun x => by 

Proof state:
R : Type u
S : Type v
inst✝⁴ : CommRing R
inst✝³ : CommRing S
inst✝² : Algebra R S
f : R[X]
T : Type u_1
inst✝¹ : CommRing T
inst✝ : Algebra R T
h : IsAdjoinRoot S f
h' : IsAdjoinRoot T f
src✝ : S →ₐ[R] T := liftHom (root h') (_ : (aeval (root h')) f = 0) h
x : T
⊢ (liftHom (root h') (_ : (aeval (root h')) f = 0) h) ((liftHom (root h) (_ : (aeval (root h)) f = 0) h') x) = x

Next tactic:
rw [← h'.map_repr x, liftHom_map, aeval_eq, liftHom_map, aeval_eq]
@[simp]
theorem aequiv_map (h : IsAdjoinRoot S f) (h' : IsAdjoinRoot T f) (z : R[X]) :
    h.aequiv h' (h.map z) = h'.map z := by 

Proof state:
R : Type u
S : Type v
inst✝⁴ : CommRing R
inst✝³ : CommRing S
inst✝² : Algebra R S
f : R[X]
T : Type u_1
inst✝¹ : CommRing T
inst✝ : Algebra R T
h : IsAdjoinRoot S f
h' : IsAdjoinRoot T f
z : R[X]
⊢ (aequiv h h') (h.map z) = h'.map z

Next tactic:
rw [aequiv, AlgEquiv.coe_mk, liftHom_map, aeval_eq]
@[simp]
theorem aequiv_root (h : IsAdjoinRoot S f) (h' : IsAdjoinRoot T f) : h.aequiv h' h.root = h'.root :=
  by 

Proof state:
R : Type u
S : Type v
inst✝⁴ : CommRing R
inst✝³ : CommRing S
inst✝² : Algebra R S
f : R[X]
T : Type u_1
inst✝¹ : CommRing T
inst✝ : Algebra R T
h : IsAdjoinRoot S f
h' : IsAdjoinRoot T f
⊢ (aequiv h h') (root h) = root h'

Next tactic:
rw [aequiv, AlgEquiv.coe_mk, liftHom_root]
@[simp]
theorem aequiv_self (h : IsAdjoinRoot S f) : h.aequiv h = AlgEquiv.refl := by
  

Proof state:
R : Type u
S : Type v
inst✝⁴ : CommRing R
inst✝³ : CommRing S
inst✝² : Algebra R S
f : R[X]
T : Type u_1
inst✝¹ : CommRing T
inst✝ : Algebra R T
h : IsAdjoinRoot S f
⊢ aequiv h h = AlgEquiv.refl

Next tactic:
ext a
@[simp]
theorem aequiv_self (h : IsAdjoinRoot S f) : h.aequiv h = AlgEquiv.refl := by
  ext a; 

Proof state:
case h
R : Type u
S : Type v
inst✝⁴ : CommRing R
inst✝³ : CommRing S
inst✝² : Algebra R S
f : R[X]
T : Type u_1
inst✝¹ : CommRing T
inst✝ : Algebra R T
h : IsAdjoinRoot S f
a : S
⊢ (aequiv h h) a = AlgEquiv.refl a

Next tactic:
exact h.lift_self_apply a
@[simp]
theorem aequiv_symm (h : IsAdjoinRoot S f) (h' : IsAdjoinRoot T f) :
    (h.aequiv h').symm = h'.aequiv h := by 

Proof state:
R : Type u
S : Type v
inst✝⁴ : CommRing R
inst✝³ : CommRing S
inst✝² : Algebra R S
f : R[X]
T : Type u_1
inst✝¹ : CommRing T
inst✝ : Algebra R T
h : IsAdjoinRoot S f
h' : IsAdjoinRoot T f
⊢ AlgEquiv.symm (aequiv h h') = aequiv h' h

Next tactic:
ext
@[simp]
theorem aequiv_symm (h : IsAdjoinRoot S f) (h' : IsAdjoinRoot T f) :
    (h.aequiv h').symm = h'.aequiv h := by ext; 

Proof state:
case h
R : Type u
S : Type v
inst✝⁴ : CommRing R
inst✝³ : CommRing S
inst✝² : Algebra R S
f : R[X]
T : Type u_1
inst✝¹ : CommRing T
inst✝ : Algebra R T
h : IsAdjoinRoot S f
h' : IsAdjoinRoot T f
a✝ : T
⊢ (AlgEquiv.symm (aequiv h h')) a✝ = (aequiv h' h) a✝

Next tactic:
rfl
@[simp]
theorem lift_aequiv {U : Type*} [CommRing U] (h : IsAdjoinRoot S f) (h' : IsAdjoinRoot T f)
    (i : R →+* U) (x hx z) : h'.lift i x hx (h.aequiv h' z) = h.lift i x hx z := by
  

Proof state:
R : Type u
S : Type v
inst✝⁵ : CommRing R
inst✝⁴ : CommRing S
inst✝³ : Algebra R S
f : R[X]
T : Type u_1
inst✝² : CommRing T
inst✝¹ : Algebra R T
U : Type u_2
inst✝ : CommRing U
h : IsAdjoinRoot S f
h' : IsAdjoinRoot T f
i : R →+* U
x : U
hx : eval₂ i x f = 0
z : S
⊢ (lift i x hx h') ((aequiv h h') z) = (lift i x hx h) z

Next tactic:
rw [← h.map_repr z, aequiv_map, lift_map, lift_map]
@[simp]
theorem aequiv_trans {U : Type*} [CommRing U] [Algebra R U] (h : IsAdjoinRoot S f)
    (h' : IsAdjoinRoot T f) (h'' : IsAdjoinRoot U f) :
    (h.aequiv h').trans (h'.aequiv h'') = h.aequiv h'' := by 

Proof state:
R : Type u
S : Type v
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
f : R[X]
T : Type u_1
inst✝³ : CommRing T
inst✝² : Algebra R T
U : Type u_2
inst✝¹ : CommRing U
inst✝ : Algebra R U
h : IsAdjoinRoot S f
h' : IsAdjoinRoot T f
h'' : IsAdjoinRoot U f
⊢ AlgEquiv.trans (aequiv h h') (aequiv h' h'') = aequiv h h''

Next tactic:
ext z
@[simp]
theorem aequiv_trans {U : Type*} [CommRing U] [Algebra R U] (h : IsAdjoinRoot S f)
    (h' : IsAdjoinRoot T f) (h'' : IsAdjoinRoot U f) :
    (h.aequiv h').trans (h'.aequiv h'') = h.aequiv h'' := by ext z; 

Proof state:
case h
R : Type u
S : Type v
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
f : R[X]
T : Type u_1
inst✝³ : CommRing T
inst✝² : Algebra R T
U : Type u_2
inst✝¹ : CommRing U
inst✝ : Algebra R U
h : IsAdjoinRoot S f
h' : IsAdjoinRoot T f
h'' : IsAdjoinRoot U f
z : S
⊢ (AlgEquiv.trans (aequiv h h') (aequiv h' h'')) z = (aequiv h h'') z

Next tactic:
exact h.aequiv_aequiv h' h'' z
/-- Transfer `IsAdjoinRoot` across an algebra isomorphism.

This is the converse of `IsAdjoinRoot.aequiv`: this turns an `AlgEquiv` into an `IsAdjoinRoot`,
and `IsAdjoinRoot.aequiv` turns an `IsAdjoinRoot` into an `AlgEquiv`.
-/
@[simps! map_apply]
def ofEquiv (h : IsAdjoinRoot S f) (e : S ≃ₐ[R] T) : IsAdjoinRoot T f where
  map := ((e : S ≃+* T) : S →+* T).comp h.map
  map_surjective := e.surjective.comp h.map_surjective
  ker_map := by
    

Proof state:
R : Type u
S : Type v
inst✝⁴ : CommRing R
inst✝³ : CommRing S
inst✝² : Algebra R S
f : R[X]
T : Type u_1
inst✝¹ : CommRing T
inst✝ : Algebra R T
h : IsAdjoinRoot S f
e : S ≃ₐ[R] T
⊢ RingHom.ker (RingHom.comp (↑↑e) h.map) = Ideal.span {f}

Next tactic:
rw [← RingHom.comap_ker, RingHom.ker_coe_equiv, ← RingHom.ker_eq_comap_bot, h.ker_map]
/-- Transfer `IsAdjoinRoot` across an algebra isomorphism.

This is the converse of `IsAdjoinRoot.aequiv`: this turns an `AlgEquiv` into an `IsAdjoinRoot`,
and `IsAdjoinRoot.aequiv` turns an `IsAdjoinRoot` into an `AlgEquiv`.
-/
@[simps! map_apply]
def ofEquiv (h : IsAdjoinRoot S f) (e : S ≃ₐ[R] T) : IsAdjoinRoot T f where
  map := ((e : S ≃+* T) : S →+* T).comp h.map
  map_surjective := e.surjective.comp h.map_surjective
  ker_map := by
    rw [← RingHom.comap_ker, RingHom.ker_coe_equiv, ← RingHom.ker_eq_comap_bot, h.ker_map]
  algebraMap_eq := by
    

Proof state:
R : Type u
S : Type v
inst✝⁴ : CommRing R
inst✝³ : CommRing S
inst✝² : Algebra R S
f : R[X]
T : Type u_1
inst✝¹ : CommRing T
inst✝ : Algebra R T
h : IsAdjoinRoot S f
e : S ≃ₐ[R] T
⊢ algebraMap R T = RingHom.comp (RingHom.comp (↑↑e) h.map) C

Next tactic:
ext
/-- Transfer `IsAdjoinRoot` across an algebra isomorphism.

This is the converse of `IsAdjoinRoot.aequiv`: this turns an `AlgEquiv` into an `IsAdjoinRoot`,
and `IsAdjoinRoot.aequiv` turns an `IsAdjoinRoot` into an `AlgEquiv`.
-/
@[simps! map_apply]
def ofEquiv (h : IsAdjoinRoot S f) (e : S ≃ₐ[R] T) : IsAdjoinRoot T f where
  map := ((e : S ≃+* T) : S →+* T).comp h.map
  map_surjective := e.surjective.comp h.map_surjective
  ker_map := by
    rw [← RingHom.comap_ker, RingHom.ker_coe_equiv, ← RingHom.ker_eq_comap_bot, h.ker_map]
  algebraMap_eq := by
    ext
    

Proof state:
case a
R : Type u
S : Type v
inst✝⁴ : CommRing R
inst✝³ : CommRing S
inst✝² : Algebra R S
f : R[X]
T : Type u_1
inst✝¹ : CommRing T
inst✝ : Algebra R T
h : IsAdjoinRoot S f
e : S ≃ₐ[R] T
x✝ : R
⊢ (algebraMap R T) x✝ = (RingHom.comp (RingHom.comp (↑↑e) h.map) C) x✝

Next tactic:
simp only [AlgEquiv.commutes, RingHom.comp_apply, AlgEquiv.coe_ringEquiv,
      RingEquiv.coe_toRingHom, ← h.algebraMap_apply]
@[simp]
theorem aequiv_ofEquiv {U : Type*} [CommRing U] [Algebra R U] (h : IsAdjoinRoot S f)
    (h' : IsAdjoinRoot T f) (e : T ≃ₐ[R] U) : h.aequiv (h'.ofEquiv e) = (h.aequiv h').trans e := by
  

Proof state:
R : Type u
S : Type v
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
f : R[X]
T : Type u_1
inst✝³ : CommRing T
inst✝² : Algebra R T
U : Type u_2
inst✝¹ : CommRing U
inst✝ : Algebra R U
h : IsAdjoinRoot S f
h' : IsAdjoinRoot T f
e : T ≃ₐ[R] U
⊢ aequiv h (ofEquiv h' e) = AlgEquiv.trans (aequiv h h') e

Next tactic:
ext a
@[simp]
theorem aequiv_ofEquiv {U : Type*} [CommRing U] [Algebra R U] (h : IsAdjoinRoot S f)
    (h' : IsAdjoinRoot T f) (e : T ≃ₐ[R] U) : h.aequiv (h'.ofEquiv e) = (h.aequiv h').trans e := by
  ext a; 

Proof state:
case h
R : Type u
S : Type v
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
f : R[X]
T : Type u_1
inst✝³ : CommRing T
inst✝² : Algebra R T
U : Type u_2
inst✝¹ : CommRing U
inst✝ : Algebra R U
h : IsAdjoinRoot S f
h' : IsAdjoinRoot T f
e : T ≃ₐ[R] U
a : S
⊢ (aequiv h (ofEquiv h' e)) a = (AlgEquiv.trans (aequiv h h') e) a

Next tactic:
rw [← h.map_repr a, aequiv_map, AlgEquiv.trans_apply, aequiv_map, ofEquiv_map_apply]
@[simp]
theorem ofEquiv_aequiv {U : Type*} [CommRing U] [Algebra R U] (h : IsAdjoinRoot S f)
    (h' : IsAdjoinRoot U f) (e : S ≃ₐ[R] T) :
    (h.ofEquiv e).aequiv h' = e.symm.trans (h.aequiv h') := by
  

Proof state:
R : Type u
S : Type v
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
f : R[X]
T : Type u_1
inst✝³ : CommRing T
inst✝² : Algebra R T
U : Type u_2
inst✝¹ : CommRing U
inst✝ : Algebra R U
h : IsAdjoinRoot S f
h' : IsAdjoinRoot U f
e : S ≃ₐ[R] T
⊢ aequiv (ofEquiv h e) h' = AlgEquiv.trans (AlgEquiv.symm e) (aequiv h h')

Next tactic:
ext a
@[simp]
theorem ofEquiv_aequiv {U : Type*} [CommRing U] [Algebra R U] (h : IsAdjoinRoot S f)
    (h' : IsAdjoinRoot U f) (e : S ≃ₐ[R] T) :
    (h.ofEquiv e).aequiv h' = e.symm.trans (h.aequiv h') := by
  ext a
  

Proof state:
case h
R : Type u
S : Type v
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
f : R[X]
T : Type u_1
inst✝³ : CommRing T
inst✝² : Algebra R T
U : Type u_2
inst✝¹ : CommRing U
inst✝ : Algebra R U
h : IsAdjoinRoot S f
h' : IsAdjoinRoot U f
e : S ≃ₐ[R] T
a : T
⊢ (aequiv (ofEquiv h e) h') a = (AlgEquiv.trans (AlgEquiv.symm e) (aequiv h h')) a

Next tactic:
rw [← (h.ofEquiv e).map_repr a, aequiv_map, AlgEquiv.trans_apply, ofEquiv_map_apply,
    e.symm_apply_apply, aequiv_map]
theorem minpoly_eq [IsDomain R] [IsDomain S] [NoZeroSMulDivisors R S] [IsIntegrallyClosed R]
    (h : IsAdjoinRootMonic S f) (hirr : Irreducible f) : minpoly R h.root = f :=
  let ⟨q, hq⟩ := minpoly.isIntegrallyClosed_dvd h.isIntegral_root h.aeval_root
  symm <|
    eq_of_monic_of_associated h.Monic (minpoly.monic h.isIntegral_root) <| by
      

Proof state:
R : Type u
S : Type v
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
f : R[X]
inst✝³ : IsDomain R
inst✝² : IsDomain S
inst✝¹ : NoZeroSMulDivisors R S
inst✝ : IsIntegrallyClosed R
h : IsAdjoinRootMonic S f
hirr : Irreducible f
q : R[X]
hq : f = minpoly R (IsAdjoinRoot.root h.toIsAdjoinRoot) * q
⊢ Associated f (minpoly R (IsAdjoinRoot.root h.toIsAdjoinRoot))

Next tactic:
convert
        Associated.mul_left (minpoly R h.root) <|
          associated_one_iff_isUnit.2 <|
            (hirr.isUnit_or_isUnit hq).resolve_left <| minpoly.not_isUnit R h.root
theorem minpoly_eq [IsDomain R] [IsDomain S] [NoZeroSMulDivisors R S] [IsIntegrallyClosed R]
    (h : IsAdjoinRootMonic S f) (hirr : Irreducible f) : minpoly R h.root = f :=
  let ⟨q, hq⟩ := minpoly.isIntegrallyClosed_dvd h.isIntegral_root h.aeval_root
  symm <|
    eq_of_monic_of_associated h.Monic (minpoly.monic h.isIntegral_root) <| by
      convert
        Associated.mul_left (minpoly R h.root) <|
          associated_one_iff_isUnit.2 <|
            (hirr.isUnit_or_isUnit hq).resolve_left <| minpoly.not_isUnit R h.root
      

Proof state:
case h.e'_4
R : Type u
S : Type v
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
f : R[X]
inst✝³ : IsDomain R
inst✝² : IsDomain S
inst✝¹ : NoZeroSMulDivisors R S
inst✝ : IsIntegrallyClosed R
h : IsAdjoinRootMonic S f
hirr : Irreducible f
q : R[X]
hq : f = minpoly R (IsAdjoinRoot.root h.toIsAdjoinRoot) * q
⊢ minpoly R (IsAdjoinRoot.root h.toIsAdjoinRoot) = minpoly R (IsAdjoinRoot.root h.toIsAdjoinRoot) * 1

Next tactic:
rw [mul_one]
theorem Algebra.adjoin.powerBasis'_minpoly_gen [IsDomain R] [IsDomain S] [NoZeroSMulDivisors R S]
    [IsIntegrallyClosed R] {x : S} (hx' : IsIntegral R x) :
    minpoly R x = minpoly R (Algebra.adjoin.powerBasis' hx').gen := by
  

Proof state:
R : Type u
S : Type v
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
f : R[X]
inst✝³ : IsDomain R
inst✝² : IsDomain S
inst✝¹ : NoZeroSMulDivisors R S
inst✝ : IsIntegrallyClosed R
x : S
hx' : IsIntegral R x
⊢ minpoly R x = minpoly R (powerBasis' hx').gen

Next tactic:
haveI := isDomain_of_prime (prime_of_isIntegrallyClosed hx')
theorem Algebra.adjoin.powerBasis'_minpoly_gen [IsDomain R] [IsDomain S] [NoZeroSMulDivisors R S]
    [IsIntegrallyClosed R] {x : S} (hx' : IsIntegral R x) :
    minpoly R x = minpoly R (Algebra.adjoin.powerBasis' hx').gen := by
  haveI := isDomain_of_prime (prime_of_isIntegrallyClosed hx')
  

Proof state:
R : Type u
S : Type v
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
f : R[X]
inst✝³ : IsDomain R
inst✝² : IsDomain S
inst✝¹ : NoZeroSMulDivisors R S
inst✝ : IsIntegrallyClosed R
x : S
hx' : IsIntegral R x
this : IsDomain (AdjoinRoot (minpoly R x))
⊢ minpoly R x = minpoly R (powerBasis' hx').gen

Next tactic:
haveI :=
    noZeroSMulDivisors_of_prime_of_degree_ne_zero (prime_of_isIntegrallyClosed hx')
      (ne_of_lt (degree_pos hx')).symm
theorem Algebra.adjoin.powerBasis'_minpoly_gen [IsDomain R] [IsDomain S] [NoZeroSMulDivisors R S]
    [IsIntegrallyClosed R] {x : S} (hx' : IsIntegral R x) :
    minpoly R x = minpoly R (Algebra.adjoin.powerBasis' hx').gen := by
  haveI := isDomain_of_prime (prime_of_isIntegrallyClosed hx')
  haveI :=
    noZeroSMulDivisors_of_prime_of_degree_ne_zero (prime_of_isIntegrallyClosed hx')
      (ne_of_lt (degree_pos hx')).symm
  

Proof state:
R : Type u
S : Type v
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
f : R[X]
inst✝³ : IsDomain R
inst✝² : IsDomain S
inst✝¹ : NoZeroSMulDivisors R S
inst✝ : IsIntegrallyClosed R
x : S
hx' : IsIntegral R x
this✝ : IsDomain (AdjoinRoot (minpoly R x))
this : NoZeroSMulDivisors R (AdjoinRoot (minpoly R x))
⊢ minpoly R x = minpoly R (powerBasis' hx').gen

Next tactic:
rw [← minpolyGen_eq, adjoin.powerBasis', minpolyGen_map, minpolyGen_eq,
    AdjoinRoot.powerBasis'_gen, ← isAdjoinRootMonic_root_eq_root _ (monic hx'), minpoly_eq]
theorem Algebra.adjoin.powerBasis'_minpoly_gen [IsDomain R] [IsDomain S] [NoZeroSMulDivisors R S]
    [IsIntegrallyClosed R] {x : S} (hx' : IsIntegral R x) :
    minpoly R x = minpoly R (Algebra.adjoin.powerBasis' hx').gen := by
  haveI := isDomain_of_prime (prime_of_isIntegrallyClosed hx')
  haveI :=
    noZeroSMulDivisors_of_prime_of_degree_ne_zero (prime_of_isIntegrallyClosed hx')
      (ne_of_lt (degree_pos hx')).symm
  rw [← minpolyGen_eq, adjoin.powerBasis', minpolyGen_map, minpolyGen_eq,
    AdjoinRoot.powerBasis'_gen, ← isAdjoinRootMonic_root_eq_root _ (monic hx'), minpoly_eq]
  

Proof state:
case hirr
R : Type u
S : Type v
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
f : R[X]
inst✝³ : IsDomain R
inst✝² : IsDomain S
inst✝¹ : NoZeroSMulDivisors R S
inst✝ : IsIntegrallyClosed R
x : S
hx' : IsIntegral R x
this✝ : IsDomain (AdjoinRoot (minpoly R x))
this : NoZeroSMulDivisors R (AdjoinRoot (minpoly R x))
⊢ Irreducible (minpoly R x)

Next tactic:
exact irreducible hx'
theorem aemeasurable_withDensity_iff {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E]
    [SecondCountableTopology E] [MeasurableSpace E] [BorelSpace E] {f : α → ℝ≥0}
    (hf : Measurable f) {g : α → E} :
    AEMeasurable g (μ.withDensity fun x => (f x : ℝ≥0∞)) ↔
      AEMeasurable (fun x => (f x : ℝ) • g x) μ := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ : Measure α
E : Type u_5
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : SecondCountableTopology E
inst✝¹ : MeasurableSpace E
inst✝ : BorelSpace E
f : α → ℝ≥0
hf : Measurable f
g : α → E
⊢ AEMeasurable g ↔ AEMeasurable fun x => ↑(f x) • g x

Next tactic:
constructor
theorem aemeasurable_withDensity_iff {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E]
    [SecondCountableTopology E] [MeasurableSpace E] [BorelSpace E] {f : α → ℝ≥0}
    (hf : Measurable f) {g : α → E} :
    AEMeasurable g (μ.withDensity fun x => (f x : ℝ≥0∞)) ↔
      AEMeasurable (fun x => (f x : ℝ) • g x) μ := by
  constructor
  · 

Proof state:
case mp
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ : Measure α
E : Type u_5
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : SecondCountableTopology E
inst✝¹ : MeasurableSpace E
inst✝ : BorelSpace E
f : α → ℝ≥0
hf : Measurable f
g : α → E
⊢ AEMeasurable g → AEMeasurable fun x => ↑(f x) • g x

Next tactic:
rintro ⟨g', g'meas, hg'⟩
theorem aemeasurable_withDensity_iff {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E]
    [SecondCountableTopology E] [MeasurableSpace E] [BorelSpace E] {f : α → ℝ≥0}
    (hf : Measurable f) {g : α → E} :
    AEMeasurable g (μ.withDensity fun x => (f x : ℝ≥0∞)) ↔
      AEMeasurable (fun x => (f x : ℝ) • g x) μ := by
  constructor
  · rintro ⟨g', g'meas, hg'⟩
    

Proof state:
case mp.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ : Measure α
E : Type u_5
inst✝⁴ : NormedAddCommGroup E
inst✝³ : NormedSpace ℝ E
inst✝² : SecondCountableTopology E
inst✝¹ : MeasurableSpace E
inst✝ : BorelSpace E
f : α → ℝ≥0
hf : Measurable f
g g' : α → E
g'meas : Measurable g'
hg' : g =ᵐ[Measure.withDensity μ fun x => ↑(f x)] g'
⊢ AEMeasurable fun x => ↑(f x) • g x

Next tactic:
have A : MeasurableSet { x : α | f x ≠ 0 } := (hf (measurableSet_singleton 0)).compl