Skip to content

Commit

Permalink
feat: roots in an algebra (#6740)
Browse files Browse the repository at this point in the history
Co-authored-by: Ruben Van de Velde <65514131+Ruben-VandeVelde@users.noreply.github.com>
  • Loading branch information
FR-vdash-bot and Ruben-VandeVelde committed Sep 10, 2023
1 parent f93f41c commit a57bfd6
Show file tree
Hide file tree
Showing 20 changed files with 145 additions and 71 deletions.
4 changes: 2 additions & 2 deletions Mathlib/Data/Polynomial/FieldDivision.lean
Original file line number Diff line number Diff line change
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_monomial 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
99 changes: 90 additions & 9 deletions Mathlib/Data/Polynomial/RingDivision.lean
Original file line number Diff line number Diff line change
Expand Up @@ -912,25 +912,108 @@ 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`.
/-- Given a polynomial `p` with coefficients in a ring `T` and a `T`-algebra `S`, `aroots p S` is
the multiset of roots of `p` regarded as a polynomial over `S`. -/
noncomputable abbrev aroots (p : T[X]) (S) [CommRing S] [IsDomain S] [Algebra T S] : Multiset S :=
(p.map (algebraMap T S)).roots

If you have a non-separable polynomial, use `Polynomial.roots` for the multiset
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' [CommRing S] [IsDomain S] [Algebra T S] {p : T[X]} {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 [CommRing S] [IsDomain S] [Algebra T S]
[NoZeroSMulDivisors T S] {p : T[X]} {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

theorem aroots_mul [CommRing S] [IsDomain S] [Algebra T S]
[NoZeroSMulDivisors T S] {p q : T[X]} (hpq : p * q ≠ 0) :
(p * q).aroots S = p.aroots S + q.aroots S := by
suffices : map (algebraMap T S) p * map (algebraMap T S) q ≠ 0
· rw [aroots_def, Polynomial.map_mul, roots_mul this]
rwa [← Polynomial.map_mul, Polynomial.map_ne_zero_iff
(NoZeroSMulDivisors.algebraMap_injective T S)]

@[simp]
theorem aroots_X_sub_C [CommRing S] [IsDomain S] [Algebra T S]
(r : T) : aroots (X - C r) S = {algebraMap T S r} := by
rw [aroots_def, Polynomial.map_sub, map_X, map_C, roots_X_sub_C]

@[simp]
theorem aroots_X [CommRing S] [IsDomain S] [Algebra T S] :
aroots (X : T[X]) S = {0} := by
rw [aroots_def, map_X, roots_X]

@[simp]
theorem aroots_C [CommRing S] [IsDomain S] [Algebra T S] (a : T) : (C a).aroots S = 0 := by
rw [aroots_def, map_C, roots_C]

@[simp]
theorem aroots_zero (S) [CommRing S] [IsDomain S] [Algebra T S] : (0 : T[X]).aroots S = 0 := by
rw [← C_0, aroots_C]

@[simp]
theorem aroots_one [CommRing S] [IsDomain S] [Algebra T S] :
(1 : T[X]).aroots S = 0 :=
aroots_C 1

@[simp]
theorem aroots_C_mul [CommRing S] [IsDomain S] [Algebra T S]
[NoZeroSMulDivisors T S] {a : T} (p : T[X]) (ha : a ≠ 0) :
(C a * p).aroots S = p.aroots S := by
rw [aroots_def, Polynomial.map_mul, map_C, roots_C_mul]
rwa [map_ne_zero_iff]
exact NoZeroSMulDivisors.algebraMap_injective T S

@[simp]
theorem aroots_smul_nonzero [CommRing S] [IsDomain S] [Algebra T S]
[NoZeroSMulDivisors T S] {a : T} (p : T[X]) (ha : a ≠ 0) :
(a • p).aroots S = p.aroots S := by
rw [smul_eq_C_mul, aroots_C_mul _ ha]

@[simp]
theorem aroots_pow [CommRing S] [IsDomain S] [Algebra T S] (p : T[X]) (n : ℕ) :
(p ^ n).aroots S = n • p.aroots S := by
rw [aroots_def, Polynomial.map_pow, roots_pow]

theorem aroots_X_pow [CommRing S] [IsDomain S] [Algebra T S] (n : ℕ) :
(X ^ n : T[X]).aroots S = n • ({0} : Multiset S) := by
rw [aroots_pow, aroots_X]

theorem aroots_C_mul_X_pow [CommRing S] [IsDomain S] [Algebra T S]
[NoZeroSMulDivisors T S] {a : T} (ha : a ≠ 0) (n : ℕ) :
(C a * X ^ n : T[X]).aroots S = n • ({0} : Multiset S) := by
rw [aroots_C_mul _ ha, aroots_X_pow]

@[simp]
theorem aroots_monomial [CommRing S] [IsDomain S] [Algebra T S]
[NoZeroSMulDivisors T S] {a : T} (ha : a ≠ 0) (n : ℕ) :
(monomial n a).aroots S = n • ({0} : Multiset S) := by
rw [← C_mul_X_pow_eq_monomial, aroots_C_mul_X_pow ha]

/-- The set of distinct roots of `p` in `S`.
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_C, Multiset.toFinset_zero, Finset.coe_empty]
set_option linter.uppercaseLean3 false in
#align polynomial.root_set_C Polynomial.rootSet_C

Expand Down Expand Up @@ -970,14 +1053,12 @@ 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 (NoZeroSMulDivisors.algebraMap_injective T S)]
#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
Original file line number Diff line number Diff line change
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
13 changes: 7 additions & 6 deletions Mathlib/FieldTheory/Adjoin.lean
Original file line number Diff line number Diff line change
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 @@ -1099,15 +1099,16 @@ noncomputable def Lifts.liftOfSplits (x : Lifts F E K) {s : E} (h1 : IsIntegral
splits_of_splits_of_dvd _ (map_ne_zero (minpoly.ne_zero h1))
((splits_map_iff _ _).mpr (by convert h2; exact RingHom.ext fun y => x.2.commutes y))
(minpoly.dvd_map_of_isScalarTower _ _ _)
let alg : Algebra {y // y ∈ x.fst} {y // y ∈ restrictScalars F {z // z ∈ x.fst}⟮s⟯} :=
letI : Algebra {y // y ∈ x.fst} {y // y ∈ restrictScalars F {z // z ∈ x.fst}⟮s⟯} :=
{z // z ∈ x.fst}⟮s⟯.toSubalgebra.algebra
letI := x.2.toRingHom.toAlgebra
⟨x.1⟮s⟯.restrictScalars F,
(@algHomEquivSigma F x.1 (x.1⟮s⟯.restrictScalars F) K _ _ _ _ _ _ _
(IntermediateField.algebra x.1⟮s⟯) (IsScalarTower.of_algebraMap_eq fun _ => rfl)).invFun
⟨x.2,
(@algHomAdjoinIntegralEquiv x.1 _ E _ _ s K _ x.2.toRingHom.toAlgebra h3).invFun
(@algHomAdjoinIntegralEquiv x.1 _ E _ _ s K _ _ h3).invFun
⟨rootOfSplits x.2.toRingHom key (ne_of_gt (minpoly.degree_pos h3)), by
rw [mem_roots (map_ne_zero (minpoly.ne_zero h3)), IsRoot, ← eval₂_eq_eval_map]
rw [mem_aroots, and_iff_right (minpoly.ne_zero h3)]
exact map_rootOfSplits x.2.toRingHom key (ne_of_gt (minpoly.degree_pos h3))⟩⟩⟩
#align intermediate_field.lifts.lift_of_splits IntermediateField.Lifts.liftOfSplits

Expand All @@ -1128,8 +1129,8 @@ 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
rw [mem_roots (map_ne_zero (minpoly.ne_zero I1)), IsRoot, ← eval₂_eq_eval_map]
(minpoly x.1 s).aroots K := by
rw [mem_aroots, and_iff_right (minpoly.ne_zero I1)]
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
⟨rootOfSplits (AlgHom.toRingHom x.2) key I2, I3⟩)
Expand Down
2 changes: 1 addition & 1 deletion Mathlib/FieldTheory/Finite/GaloisField.lean
Original file line number Diff line number Diff line change
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
12 changes: 6 additions & 6 deletions Mathlib/FieldTheory/Galois.lean
Original file line number Diff line number Diff line change
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_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,19 +396,19 @@ 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
have adjoin_root : IntermediateField.adjoin F (s : Set E) = ⊤ := by
let s := p.rootSet E
have adjoin_root : IntermediateField.adjoin F s = ⊤ := by
apply IntermediateField.toSubalgebra_injective
rw [IntermediateField.top_toSubalgebra, ← top_le_iff, ← sp.adjoin_rootSet]
apply IntermediateField.algebra_adjoin_le_adjoin
let P : IntermediateField F E → Prop := fun K => Fintype.card (K →ₐ[F] E) = finrank F K
suffices P (IntermediateField.adjoin F s) by
suffices P (IntermediateField.adjoin F s) by
rw [adjoin_root] at this
apply of_card_aut_eq_finrank
rw [← Eq.trans this (LinearEquiv.finrank_eq IntermediateField.topEquiv.toLinearEquiv)]
exact Fintype.card_congr ((algEquivEquivAlgHom F E).toEquiv.trans
(IntermediateField.topEquiv.symm.arrowCongr AlgEquiv.refl))
apply IntermediateField.induction_on_adjoin_finset s P
apply IntermediateField.induction_on_adjoin_finset _ P
· have key := IntermediateField.card_algHom_adjoin_integral F (K := E)
(show IsIntegral F (0 : E) from isIntegral_zero)
rw [minpoly.zero, Polynomial.natDegree_X] at key
Expand Down
8 changes: 4 additions & 4 deletions Mathlib/FieldTheory/IsAlgClosed/Classification.lean
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
7 changes: 3 additions & 4 deletions Mathlib/FieldTheory/Normal.lean
Original file line number Diff line number Diff line change
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 @@ -215,8 +215,7 @@ theorem Normal.of_isSplittingField (p : F[X]) [hFEp : IsSplittingField F E p] :
apply splits_of_splits_of_dvd (algebraMap C E) (map_ne_zero (minpoly.ne_zero Hz))
· rw [splits_map_iff, ← algebraMap_eq F C E]
exact
splits_of_splits_of_dvd _ hp hFEp.splits
(minpoly.dvd F z (Eq.trans (eval₂_eq_eval_map _) ((mem_roots (map_ne_zero hp)).mp hz1)))
splits_of_splits_of_dvd _ hp hFEp.splits (minpoly.dvd F z (mem_aroots.mp hz1).2)
· apply minpoly.dvd
rw [← hz2, aeval_def, eval₂_map, ← algebraMap_eq F C D, algebraMap_eq F E D, ← hom_eval₂, ←
aeval_def, minpoly.aeval F z, RingHom.map_zero]
Expand All @@ -231,7 +230,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
3 changes: 1 addition & 2 deletions Mathlib/FieldTheory/PolynomialGaloisGroup.lean
Original file line number Diff line number Diff line change
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_mul hpq] 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 All @@ -311,7 +311,6 @@ theorem restrictProd_injective : Function.Injective (restrictProd p q) := by
Subtype.ext_iff.mp (Equiv.apply_symm_apply (rootsEquivRoots q _) ⟨x, _⟩).symm
rw [key, ← AlgEquiv.restrictNormal_commutes, ← AlgEquiv.restrictNormal_commutes]
exact congr_arg _ (AlgEquiv.ext_iff.mp hfg.2 _)
· rwa [Ne.def, mul_eq_zero, map_eq_zero, map_eq_zero, ← mul_eq_zero]
#align polynomial.gal.restrict_prod_injective Polynomial.Gal.restrictProd_injective

theorem mul_splits_in_splittingField_of_mul {p₁ q₁ p₂ q₂ : F[X]} (hq₁ : q₁ ≠ 0) (hq₂ : q₂ ≠ 0)
Expand Down
3 changes: 1 addition & 2 deletions Mathlib/FieldTheory/Separable.lean
Original file line number Diff line number Diff line change
Expand Up @@ -575,9 +575,8 @@ 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 _ := (PowerBasis.AlgHom.fintype pb : Fintype (S →ₐ[K] L))
rw [Fintype.card_congr pb.liftEquiv', Fintype.card_of_subtype s (fun x => Multiset.mem_toFinset),
rw [Fintype.card_congr pb.liftEquiv', Fintype.card_of_subtype _ (fun x => Multiset.mem_toFinset),
← pb.natDegree_minpoly, natDegree_eq_card_roots h_splits, Multiset.toFinset_card_of_nodup]
exact nodup_roots ((separable_map (algebraMap K L)).mpr h_sep)
#align alg_hom.card_of_power_basis AlgHom.card_of_powerBasis
Expand Down
Loading

0 comments on commit a57bfd6

Please sign in to comment.