Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - feat: roots in an algebra #6740

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions Mathlib/Data/Polynomial/FieldDivision.lean
Expand Up @@ -373,7 +373,7 @@ theorem mem_roots_map [CommRing k] [IsDomain k] {f : R →+* k} {x : k} (hp : p
theorem rootSet_monomial [CommRing S] [IsDomain S] [Algebra R S] {n : ℕ} (hn : n ≠ 0) {a : R}
(ha : a ≠ 0) : (monomial n a).rootSet S = {0} := by
classical
rw [rootSet, map_monomial, roots_monomial ((_root_.map_ne_zero (algebraMap R S)).2 ha),
rw [rootSet, aroots, map_monomial, roots_monomial ((_root_.map_ne_zero (algebraMap R S)).2 ha),
Multiset.toFinset_nsmul _ _ hn, Multiset.toFinset_singleton, Finset.coe_singleton]
#align polynomial.root_set_monomial Polynomial.rootSet_monomial

Expand All @@ -393,7 +393,7 @@ set_option linter.uppercaseLean3 false in
theorem rootSet_prod [CommRing S] [IsDomain S] [Algebra R S] {ι : Type*} (f : ι → R[X])
(s : Finset ι) (h : s.prod f ≠ 0) : (s.prod f).rootSet S = ⋃ i ∈ s, (f i).rootSet S := by
classical
simp only [rootSet, ← Finset.mem_coe]
simp only [rootSet, aroots, ← Finset.mem_coe]
rw [Polynomial.map_prod, roots_prod, Finset.bind_toFinset, s.val_toFinset, Finset.coe_biUnion]
rwa [← Polynomial.map_prod, Ne, map_eq_zero]
#align polynomial.root_set_prod Polynomial.rootSet_prod
Expand Down
35 changes: 26 additions & 9 deletions Mathlib/Data/Polynomial/RingDivision.lean
Expand Up @@ -914,25 +914,43 @@ theorem funext [Infinite R] {p q : R[X]} (ext : ∀ r : R, p.eval r = q.eval r)

variable [CommRing T]

/-- The set of distinct roots of `p` in `E`.
/-- `aroots p A` gives the multiset of the roots of `p` in an algebra `A`,
including their multiplicities. -/
negiizhao marked this conversation as resolved.
Show resolved Hide resolved
noncomputable abbrev aroots (p : T[X]) (S) [CommRing S] [IsDomain S] [Algebra T S] : Multiset S :=
(p.map (algebraMap T S)).roots

theorem aroots_def (p : T[X]) (S) [CommRing S] [IsDomain S] [Algebra T S] :
p.aroots S = (p.map (algebraMap T S)).roots :=
rfl

theorem mem_aroots' {p : T[X]} {S : Type*} [CommRing S] [IsDomain S] [Algebra T S] {a : S} :
a ∈ p.aroots S ↔ p.map (algebraMap T S) ≠ 0 ∧ aeval a p = 0 := by
rw [mem_roots', IsRoot.def, ← eval₂_eq_eval_map, aeval_def]

theorem mem_aroots {p : T[X]} {S : Type*} [CommRing S] [IsDomain S] [Algebra T S]
[NoZeroSMulDivisors T S] {a : S} : a ∈ p.aroots S ↔ p ≠ 0 ∧ aeval a p = 0 := by
rw [mem_aroots', Polynomial.map_ne_zero_iff]
exact NoZeroSMulDivisors.algebraMap_injective T S

/-- The set of distinct roots of `p` in `S`.

If you have a non-separable polynomial, use `Polynomial.roots` for the multiset
If you have a non-separable polynomial, use `Polynomial.aroots` for the multiset
where multiple roots have the appropriate multiplicity. -/
def rootSet (p : T[X]) (S) [CommRing S] [IsDomain S] [Algebra T S] : Set S :=
haveI := Classical.decEq S
(p.map (algebraMap T S)).roots.toFinset
(p.aroots S).toFinset
#align polynomial.root_set Polynomial.rootSet

theorem rootSet_def (p : T[X]) (S) [CommRing S] [IsDomain S] [Algebra T S] [DecidableEq S] :
p.rootSet S = (p.map (algebraMap T S)).roots.toFinset := by
p.rootSet S = (p.aroots S).toFinset := by
rw [rootSet]
convert rfl
#align polynomial.root_set_def Polynomial.rootSet_def

@[simp]
theorem rootSet_C [CommRing S] [IsDomain S] [Algebra T S] (a : T) : (C a).rootSet S = ∅ := by
classical
rw [rootSet_def, map_C, roots_C, Multiset.toFinset_zero, Finset.coe_empty]
rw [rootSet_def, aroots_def, map_C, roots_C, Multiset.toFinset_zero, Finset.coe_empty]
negiizhao marked this conversation as resolved.
Show resolved Hide resolved
set_option linter.uppercaseLean3 false in
#align polynomial.root_set_C Polynomial.rootSet_C

Expand Down Expand Up @@ -972,14 +990,13 @@ theorem bUnion_roots_finite {R S : Type*} [Semiring R] [CommRing S] [IsDomain S]
theorem mem_rootSet' {p : T[X]} {S : Type*} [CommRing S] [IsDomain S] [Algebra T S] {a : S} :
a ∈ p.rootSet S ↔ p.map (algebraMap T S) ≠ 0 ∧ aeval a p = 0 := by
classical
rw [rootSet_def, Finset.mem_coe, mem_toFinset, mem_roots', IsRoot.def, ← eval₂_eq_eval_map,
aeval_def]
rw [rootSet_def, Finset.mem_coe, mem_toFinset, mem_aroots']
#align polynomial.mem_root_set' Polynomial.mem_rootSet'

theorem mem_rootSet {p : T[X]} {S : Type*} [CommRing S] [IsDomain S] [Algebra T S]
[NoZeroSMulDivisors T S] {a : S} : a ∈ p.rootSet S ↔ p ≠ 0 ∧ aeval a p = 0 := by
rw [mem_rootSet',
(map_injective _ (NoZeroSMulDivisors.algebraMap_injective T S)).ne_iff' (Polynomial.map_zero _)]
rw [mem_rootSet', Polynomial.map_ne_zero_iff]
exact NoZeroSMulDivisors.algebraMap_injective T S
negiizhao marked this conversation as resolved.
Show resolved Hide resolved
#align polynomial.mem_root_set Polynomial.mem_rootSet

theorem mem_rootSet_of_ne {p : T[X]} {S : Type*} [CommRing S] [IsDomain S] [Algebra T S]
Expand Down
4 changes: 2 additions & 2 deletions Mathlib/Data/Polynomial/Splits.lean
Expand Up @@ -446,9 +446,9 @@ theorem splits_iff_card_roots {p : K[X]} :
#align polynomial.splits_iff_card_roots Polynomial.splits_iff_card_roots

theorem aeval_root_derivative_of_splits [Algebra K L] {P : K[X]} (hmo : P.Monic)
(hP : P.Splits (algebraMap K L)) {r : L} (hr : r ∈ (P.map (algebraMap K L)).roots) :
(hP : P.Splits (algebraMap K L)) {r : L} (hr : r ∈ P.aroots L) :
aeval r (Polynomial.derivative P) =
(((P.map <| algebraMap K L).roots.erase r).map fun a => r - a).prod := by
(((P.aroots L).erase r).map fun a => r - a).prod := by
replace hmo := hmo.map (algebraMap K L)
replace hP := (splits_id_iff_splits (algebraMap K L)).2 hP
rw [aeval_def, ← eval_map, ← derivative_map]
Expand Down
4 changes: 2 additions & 2 deletions Mathlib/FieldTheory/Adjoin.lean
Expand Up @@ -896,7 +896,7 @@ end PowerBasis
/-- Algebra homomorphism `F⟮α⟯ →ₐ[F] K` are in bijection with the set of roots
of `minpoly α` in `K`. -/
noncomputable def algHomAdjoinIntegralEquiv (h : IsIntegral F α) :
(F⟮α⟯ →ₐ[F] K) ≃ { x // x ∈ ((minpoly F α).map (algebraMap F K)).roots } :=
(F⟮α⟯ →ₐ[F] K) ≃ { x // x ∈ (minpoly F α).aroots K } :=
(adjoin.powerBasis h).liftEquiv'.trans
((Equiv.refl _).subtypeEquiv fun x => by
rw [adjoin.powerBasis_gen, minpoly_gen h, Equiv.refl_apply])
Expand Down Expand Up @@ -1129,7 +1129,7 @@ theorem Lifts.le_lifts_of_splits (x : Lifts F E K) {s : E} (h1 : IsIntegral F s)
(minpoly.dvd_map_of_isScalarTower _ _ _)
have I2 := (ne_of_gt (minpoly.degree_pos I1))
have I3 : rootOfSplits (AlgHom.toRingHom x.2) key (ne_of_gt (minpoly.degree_pos I1)) ∈
(Polynomial.map (algebraMap x.1 K) (minpoly x.1 s)).roots := by
(minpoly x.1 s).aroots K := by
rw [mem_roots (map_ne_zero (minpoly.ne_zero I1)), IsRoot, ← eval₂_eq_eval_map]
exact map_rootOfSplits x.2.toRingHom key (ne_of_gt (minpoly.degree_pos I1))
let φ : x.1⟮s⟯ →ₐ[x.1] K := ((algHomAdjoinIntegralEquiv x.1 I1).invFun
Expand Down
2 changes: 1 addition & 1 deletion Mathlib/FieldTheory/Finite/GaloisField.lean
Expand Up @@ -48,7 +48,7 @@ instance FiniteField.isSplittingField_sub (K F : Type*) [Field K] [Fintype K]
adjoin_rootSet' := by
classical
trans Algebra.adjoin F ((roots (X ^ Fintype.card K - X : K[X])).toFinset : Set K)
· simp only [rootSet, Polynomial.map_pow, map_X, Polynomial.map_sub]
· simp only [rootSet, aroots, Polynomial.map_pow, map_X, Polynomial.map_sub]
· rw [FiniteField.roots_X_pow_card_sub_X, val_toFinset, coe_univ, Algebra.adjoin_univ]
#align finite_field.has_sub.sub.polynomial.is_splitting_field FiniteField.isSplittingField_sub

Expand Down
6 changes: 3 additions & 3 deletions Mathlib/FieldTheory/Galois.lean
Expand Up @@ -358,15 +358,15 @@ variable {p : F[X]}

theorem of_separable_splitting_field_aux [hFE : FiniteDimensional F E] [sp : p.IsSplittingField F E]
(hp : p.Separable) (K : Type*) [Field K] [Algebra F K] [Algebra K E] [IsScalarTower F K E]
{x : E} (hx : x ∈ (p.map (algebraMap F E)).roots)
{x : E} (hx : x ∈ p.aroots E)
-- these are both implied by `hFE`, but as they carry data this makes the lemma more general
[Fintype (K →ₐ[F] E)]
[Fintype (K⟮x⟯.restrictScalars F →ₐ[F] E)] :
Fintype.card (K⟮x⟯.restrictScalars F →ₐ[F] E) = Fintype.card (K →ₐ[F] E) * finrank K K⟮x⟯ := by
have h : IsIntegral K x :=
isIntegral_of_isScalarTower (isIntegral_of_noetherian (IsNoetherian.iff_fg.2 hFE) x)
have h1 : p ≠ 0 := fun hp => by
rw [hp, Polynomial.map_zero, Polynomial.roots_zero] at hx
rw [hp, Polynomial.aroots_def, Polynomial.map_zero, Polynomial.roots_zero] at hx
exact Multiset.not_mem_zero x hx
have h2 : minpoly K x ∣ p.map (algebraMap F K) := by
apply minpoly.dvd
Expand Down Expand Up @@ -396,7 +396,7 @@ theorem of_separable_splitting_field [sp : p.IsSplittingField F E] (hp : p.Separ
IsGalois F E := by
haveI hFE : FiniteDimensional F E := Polynomial.IsSplittingField.finiteDimensional E p
letI := Classical.decEq E
let s := (p.map (algebraMap F E)).roots.toFinset
let s := (p.aroots E).toFinset
negiizhao marked this conversation as resolved.
Show resolved Hide resolved
have adjoin_root : IntermediateField.adjoin F (s : Set E) = ⊤ := by
apply IntermediateField.toSubalgebra_injective
rw [IntermediateField.top_toSubalgebra, ← top_le_iff, ← sp.adjoin_rootSet]
Expand Down
8 changes: 4 additions & 4 deletions Mathlib/FieldTheory/IsAlgClosed/Classification.lean
Expand Up @@ -40,8 +40,8 @@ variable (R L : Type u) [CommRing R] [CommRing L] [IsDomain L] [Algebra R L]
variable [NoZeroSMulDivisors R L] (halg : Algebra.IsAlgebraic R L)

theorem cardinal_mk_le_sigma_polynomial :
#L ≤ #(Σ p : R[X], { x : L // x ∈ (p.map (algebraMap R L)).roots }) :=
@mk_le_of_injective L (Σ p : R[X], {x : L | x ∈ (p.map (algebraMap R L)).roots})
#L ≤ #(Σ p : R[X], { x : L // x ∈ p.aroots L }) :=
@mk_le_of_injective L (Σ p : R[X], {x : L | x ∈ p.aroots L})
(fun x : L =>
let p := Classical.indefiniteDescription _ (halg x)
⟨p.1, x, by
Expand All @@ -64,9 +64,9 @@ theorem cardinal_mk_le_sigma_polynomial :
of the base ring or `ℵ₀` -/
theorem cardinal_mk_le_max : #L ≤ max #R ℵ₀ :=
calc
#L ≤ #(Σ p : R[X], { x : L // x ∈ (p.map (algebraMap R L)).roots }) :=
#L ≤ #(Σ p : R[X], { x : L // x ∈ p.aroots L }) :=
cardinal_mk_le_sigma_polynomial R L halg
_ = Cardinal.sum fun p : R[X] => #{x : L | x ∈ (p.map (algebraMap R L)).roots} := by
_ = Cardinal.sum fun p : R[X] => #{x : L | x ∈ p.aroots L} := by
rw [← mk_sigma]; rfl
_ ≤ Cardinal.sum.{u, u} fun _ : R[X] => ℵ₀ :=
(sum_le_sum _ _ fun p => (Multiset.finite_toSet _).lt_aleph0.le)
Expand Down
4 changes: 2 additions & 2 deletions Mathlib/FieldTheory/Minpoly/Field.lean
Expand Up @@ -176,7 +176,7 @@ variable (F E K : Type*) [Field F] [Ring E] [CommRing K] [IsDomain K] [Algebra F
/-- Function from Hom_K(E,L) to pi type Π (x : basis), roots of min poly of x -/
def rootsOfMinPolyPiType (φ : E →ₐ[F] K)
(x : range (FiniteDimensional.finBasis F E : _ → E)) :
{ l : K // l ∈ (((minpoly F x.1).map (algebraMap F K)).roots : Multiset K) } :=
{ l : K // l ∈ (minpoly F x.1).aroots K } :=
⟨φ x, by
rw [mem_roots_map (minpoly.ne_zero_of_finite F x.val),
← aeval_def, aeval_algHom_apply, minpoly.aeval, map_zero]⟩
Expand All @@ -195,7 +195,7 @@ theorem aux_inj_roots_of_min_poly : Injective (rootsOfMinPolyPiType F E K) := by
noncomputable instance AlgHom.fintype : Fintype (E →ₐ[F] K) :=
@Fintype.ofInjective _ _
(Fintype.subtypeProd (finite_range (FiniteDimensional.finBasis F E)) fun e =>
((minpoly F e).map (algebraMap F K)).roots)
(minpoly F e).aroots K)
_ (aux_inj_roots_of_min_poly F E K)
#align minpoly.alg_hom.fintype minpoly.AlgHom.fintype

Expand Down
4 changes: 2 additions & 2 deletions Mathlib/FieldTheory/Normal.lean
Expand Up @@ -204,7 +204,7 @@ theorem Normal.of_isSplittingField (p : F[X]) [hFEp : IsSplittingField F E p] :
-- Porting note: the following proof was just `_`.
rw [← aeval_def, minpoly.aeval]
suffices Nonempty (D →ₐ[C] E) by exact Nonempty.map (AlgHom.restrictScalars F) this
let S : Set D := ((p.map (algebraMap F E)).roots.map (algebraMap E D)).toFinset
let S : Set D := ((p.aroots E).map (algebraMap E D)).toFinset
suffices ⊤ ≤ IntermediateField.adjoin C S by
refine' IntermediateField.algHom_mk_adjoin_splits' (top_le_iff.mp this) fun y hy => _
rcases Multiset.mem_map.mp (Multiset.mem_toFinset.mp hy) with ⟨z, hz1, hz2⟩
Expand All @@ -231,7 +231,7 @@ theorem Normal.of_isSplittingField (p : F[X]) [hFEp : IsSplittingField F E p] :
/- Porting note: the `change` was `dsimp only [S]`. This is the step that requires increasing
`maxHeartbeats`. Using `set S ... with hS` doesn't work. -/
change Subalgebra.restrictScalars F (Algebra.adjoin C
(((p.map (algebraMap F E)).roots.map (algebraMap E D)).toFinset : Set D)) = _
(((p.aroots E).map (algebraMap E D)).toFinset : Set D)) = _
rw [← Finset.image_toFinset, Finset.coe_image]
apply
Eq.trans
Expand Down
2 changes: 1 addition & 1 deletion Mathlib/FieldTheory/PolynomialGaloisGroup.lean
Expand Up @@ -289,7 +289,7 @@ theorem restrictProd_injective : Function.Injective (restrictProd p q) := by
simp only [restrictProd, restrictDvd_def] at hfg
simp only [dif_neg hpq, MonoidHom.prod_apply, Prod.mk.inj_iff] at hfg
ext (x hx)
rw [rootSet_def, Polynomial.map_mul, Polynomial.roots_mul] at hx
rw [rootSet_def, aroots_def, Polynomial.map_mul, Polynomial.roots_mul] at hx
cases' Multiset.mem_add.mp (Multiset.mem_toFinset.mp hx) with h h
· haveI : Fact (p.Splits (algebraMap F (p * q).SplittingField)) :=
⟨splits_of_splits_of_dvd _ hpq (SplittingField.splits (p * q)) (dvd_mul_right p q)⟩
Expand Down
2 changes: 1 addition & 1 deletion Mathlib/FieldTheory/Separable.lean
Expand Up @@ -575,7 +575,7 @@ variable [Algebra K S] [Algebra K L]
theorem AlgHom.card_of_powerBasis (pb : PowerBasis K S) (h_sep : (minpoly K pb.gen).Separable)
(h_splits : (minpoly K pb.gen).Splits (algebraMap K L)) :
@Fintype.card (S →ₐ[K] L) (PowerBasis.AlgHom.fintype pb) = pb.dim := by
let s := ((minpoly K pb.gen).map (algebraMap K L)).roots.toFinset
let s := ((minpoly K pb.gen).aroots L).toFinset
negiizhao marked this conversation as resolved.
Show resolved Hide resolved
let _ := (PowerBasis.AlgHom.fintype pb : Fintype (S →ₐ[K] L))
rw [Fintype.card_congr pb.liftEquiv', Fintype.card_of_subtype s (fun x => Multiset.mem_toFinset),
← pb.natDegree_minpoly, natDegree_eq_card_roots h_splits, Multiset.toFinset_card_of_nodup]
Expand Down
4 changes: 2 additions & 2 deletions Mathlib/FieldTheory/SplittingField/Construction.lean
Expand Up @@ -195,13 +195,13 @@ theorem adjoin_rootSet (n : ℕ) :
∀ {K : Type u} [Field K],
∀ (f : K[X]) (_hfn : f.natDegree = n),
Algebra.adjoin K
(↑(f.map <| algebraMap K <| SplittingFieldAux n f).roots.toFinset :
Set (SplittingFieldAux n f)) = ⊤)
((f.aroots (SplittingFieldAux n f)).toFinset : Set (SplittingFieldAux n f)) = ⊤)
negiizhao marked this conversation as resolved.
Show resolved Hide resolved
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 [aroots_def]
rw [algebraMap_succ, ←map_map, ←X_sub_C_mul_removeFactor _ hndf, Polynomial.map_mul] at hmf0 ⊢
rw [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,
Expand Down
6 changes: 3 additions & 3 deletions Mathlib/FieldTheory/SplittingField/IsSplittingField.lean
Expand Up @@ -73,15 +73,15 @@ variable [Algebra F K] [Algebra F L] [IsScalarTower F K L]
instance map (f : F[X]) [IsSplittingField F L f] : IsSplittingField K L (f.map <| algebraMap F K) :=
⟨by rw [splits_map_iff, ← IsScalarTower.algebraMap_eq]; exact splits L f,
Subalgebra.restrictScalars_injective F <| by
rw [rootSet, map_map, ← IsScalarTower.algebraMap_eq, Subalgebra.restrictScalars_top,
rw [rootSet, aroots, map_map, ← IsScalarTower.algebraMap_eq, Subalgebra.restrictScalars_top,
eq_top_iff, ← adjoin_rootSet L f, Algebra.adjoin_le_iff]
exact fun x hx => @Algebra.subset_adjoin K _ _ _ _ _ _ hx⟩
#align polynomial.is_splitting_field.map Polynomial.IsSplittingField.map

theorem splits_iff (f : K[X]) [IsSplittingField K L f] :
Polynomial.Splits (RingHom.id K) f ↔ (⊤ : Subalgebra K L) = ⊥ :=
⟨fun h => by -- Porting note: replaced term-mode proof
rw [eq_bot_iff, ← adjoin_rootSet L f, rootSet, roots_map (algebraMap K L) h,
rw [eq_bot_iff, ← adjoin_rootSet L f, rootSet, aroots, roots_map (algebraMap K L) h,
Algebra.adjoin_le_iff]
intro y hy
rw [Multiset.toFinset_map, Finset.mem_coe, Finset.mem_image] at hy
Expand All @@ -99,7 +99,7 @@ theorem mul (f g : F[X]) (hf : f ≠ 0) (hg : g ≠ 0) [IsSplittingField F K f]
⟨(IsScalarTower.algebraMap_eq F K L).symm ▸
splits_mul _ (splits_comp_of_splits _ _ (splits K f))
((splits_map_iff _ _).1 (splits L <| g.map <| algebraMap F K)), by
rw [rootSet, Polynomial.map_mul,
rw [rootSet, aroots, Polynomial.map_mul,
roots_mul (mul_ne_zero (map_ne_zero hf : f.map (algebraMap F L) ≠ 0) (map_ne_zero hg)),
Multiset.toFinset_add, Finset.coe_union, Algebra.adjoin_union_eq_adjoin_adjoin,
IsScalarTower.algebraMap_eq F K L, ← map_map,
Expand Down
8 changes: 4 additions & 4 deletions Mathlib/RingTheory/AdjoinRoot.lean
Expand Up @@ -42,7 +42,7 @@ The main definitions are in the `AdjoinRoot` namespace.
* `lift_hom (x : S) (hfx : aeval x f = 0) : AdjoinRoot f →ₐ[R] S`, the algebra
homomorphism from R[X]/(f) to S extending `algebraMap R S` and sending `X` to `x`

* `equiv : (AdjoinRoot f →ₐ[F] E) ≃ {x // x ∈ (f.map (algebraMap F E)).roots}` a
* `equiv : (AdjoinRoot f →ₐ[F] E) ≃ {x // x ∈ f.aroots E}` a
bijection between algebra homomorphisms from `AdjoinRoot` and roots of `f` in `S`

-/
Expand Down Expand Up @@ -698,11 +698,11 @@ variable (pb : PowerBasis F K)
/-- If `L` is a field extension of `F` and `f` is a polynomial over `F` then the set
of maps from `F[x]/(f)` into `L` is in bijection with the set of roots of `f` in `L`. -/
def equiv (f : F[X]) (hf : f ≠ 0) :
(AdjoinRoot f →ₐ[F] L) ≃ { x // x ∈ (f.map (algebraMap F L)).roots } :=
(AdjoinRoot f →ₐ[F] L) ≃ { x // x ∈ f.aroots L } :=
(powerBasis hf).liftEquiv'.trans
((Equiv.refl _).subtypeEquiv fun x => by
rw [powerBasis_gen, minpoly_root hf, Polynomial.map_mul, roots_mul, Polynomial.map_C,
roots_C, add_zero, Equiv.refl_apply]
rw [powerBasis_gen, minpoly_root hf, aroots_def, Polynomial.map_mul, roots_mul,
Polynomial.map_C, roots_C, add_zero, Equiv.refl_apply]
rw [← Polynomial.map_mul]; exact map_monic_ne_zero (monic_mul_leadingCoeff_inv hf))
#align adjoin_root.equiv AdjoinRoot.equiv

Expand Down
4 changes: 2 additions & 2 deletions Mathlib/RingTheory/Discriminant.lean
Expand Up @@ -230,9 +230,9 @@ theorem discr_powerBasis_eq_norm [IsSeparable K L] :
refine' equivOfCardEq _
rw [Fintype.card_fin, AlgHom.card]
exact (PowerBasis.finrank pb).symm
have hnodup : ((minpoly K pb.gen).map (algebraMap K E)).roots.Nodup :=
have hnodup : ((minpoly K pb.gen).aroots E).Nodup :=
nodup_roots (Separable.map (IsSeparable.separable K pb.gen))
have hroots : ∀ σ : L →ₐ[K] E, σ pb.gen ∈ ((minpoly K pb.gen).map (algebraMap K E)).roots := by
have hroots : ∀ σ : L →ₐ[K] E, σ pb.gen ∈ (minpoly K pb.gen).aroots E := by
intro σ
rw [mem_roots, IsRoot.def, eval_map, ← aeval_def, aeval_algHom_apply]
repeat' simp [minpoly.ne_zero (IsSeparable.isIntegral K pb.gen)]
Expand Down
2 changes: 1 addition & 1 deletion Mathlib/RingTheory/IntegralClosure.lean
Expand Up @@ -1204,7 +1204,7 @@ instance : IsDomain (integralClosure R S) :=
inferInstance

theorem roots_mem_integralClosure {f : R[X]} (hf : f.Monic) {a : S}
(ha : a ∈ (f.map <| algebraMap R S).roots) : a ∈ integralClosure R S :=
(ha : a ∈ f.aroots S) : a ∈ integralClosure R S :=
⟨f, hf, (eval₂_eq_eval_map _).trans <| (mem_roots <| (hf.map _).ne_zero).1 ha⟩
#align roots_mem_integral_closure roots_mem_integralClosure

Expand Down