Skip to content

Commit 29c689a

Browse files
committed
chore(IsGaloisGroup): refactor IsGaloisGroup.quotient (#38153)
Refactors the quotient construction in `IsGaloisGroup` to work at the level of ring extensions rather than intermediate fields.
1 parent ae7637b commit 29c689a

3 files changed

Lines changed: 205 additions & 59 deletions

File tree

Mathlib/Algebra/Algebra/Basic.lean

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,32 @@ lemma algebraMap_eq_one_iff {r : R} : algebraMap R A r = 1 ↔ r = 1 :=
360360

361361
end FaithfulSMul
362362

363+
/-- If `R` embeds faithfully into `A` and `G` satisfies `SMulDistribClass G R A`, then
364+
the `SMul` of `G` on `R` extends to a `MulSemiringAction`. -/
365+
@[implicit_reducible]
366+
noncomputable def mulSemiringActionOfSmulDistribClass (G : Type*) [Monoid G]
367+
[MulSemiringAction G A] [SMul G R] [SMulDistribClass G R A] :
368+
MulSemiringAction G R where
369+
one_smul _ := by
370+
apply FaithfulSMul.algebraMap_injective R A
371+
rw [algebraMap.smul', one_smul]
372+
smul_zero _ := by
373+
apply FaithfulSMul.algebraMap_injective R A
374+
rw [algebraMap.smul', map_zero, smul_zero]
375+
mul_smul _ _ _ := by
376+
apply FaithfulSMul.algebraMap_injective R A
377+
rw [algebraMap.smul', algebraMap.smul', algebraMap.smul', mul_smul]
378+
smul_add _ _ _ := by
379+
apply FaithfulSMul.algebraMap_injective R A
380+
rw [algebraMap.smul', map_add, smul_add, ← algebraMap.smul', ← algebraMap.smul', ← map_add]
381+
smul_one _ := by
382+
apply FaithfulSMul.algebraMap_injective R A
383+
rw [algebraMap.smul', map_one, smul_one]
384+
smul_mul _ _ _ := by
385+
apply FaithfulSMul.algebraMap_injective R A
386+
rw [algebraMap.smul', map_mul, map_mul, algebraMap.smul', algebraMap.smul',
387+
MulSemiringAction.smul_mul]
388+
363389
namespace algebraMap
364390

365391
@[norm_cast, simp]

Mathlib/FieldTheory/Galois/IsGaloisGroup.lean

Lines changed: 172 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,26 @@ instance [IsGaloisGroup G A B] : IsGaloisGroup (⊤ : Subgroup G) A B :=
8282

8383
attribute [instance low] IsGaloisGroup.commutes IsGaloisGroup.isInvariant
8484

85-
variable [FaithfulSMul A B] [hA : IsGaloisGroup G A B]
85+
variable {C : Type*} [CommSemiring C] [Algebra C B]
86+
87+
variable {G} in
88+
protected theorem Subgroup.smul_algebraMap {H : Subgroup G} [SMulCommClass H C B] {g : G}
89+
(hg : g ∈ H) (x : C) :
90+
g • algebraMap C B x = algebraMap C B x :=
91+
smul_algebraMap (⟨g, hg⟩ : H) x
92+
93+
theorem IsGaloisGroup.smul_mem_of_normal (N : Subgroup G) [hN : N.Normal]
94+
[hC : IsGaloisGroup N C B] (g : G) (x : C) :
95+
g • algebraMap C B x ∈ Set.range (algebraMap C B) := by
96+
apply hC.isInvariant.isInvariant (g • algebraMap C B x)
97+
intro n
98+
rw [← inv_smul_eq_iff, Subgroup.smul_def, ← mul_smul, ← mul_smul]
99+
exact Subgroup.smul_algebraMap B (hN.conj_mem' n n.prop g) x
100+
101+
@[deprecated (since := "2026-05-28")] alias smul_eq_self := Subgroup.smul_algebraMap
102+
@[deprecated (since := "2026-05-28")] alias smul_mem_of_normal := IsGaloisGroup.smul_mem_of_normal
103+
104+
variable [hA : IsGaloisGroup G A B] [FaithfulSMul A B]
86105

87106
/--
88107
If `B/A` is Galois with Galois group `G`, then `A` is isomorphic to the subring of elements of `B`
@@ -315,21 +334,6 @@ theorem subgroup_iff [hGKL : IsGaloisGroup G K L] :
315334
IsGaloisGroup H F L ↔ FixedPoints.intermediateField H = F :=
316335
fun _ ↦ fixedPoints_of_isGaloisGroup G K L H F, fun h ↦ of_fixedPoints_eq G K L H F h⟩
317336

318-
theorem smul_eq_self [IsGaloisGroup H F L] (g : G) (hg : g ∈ H) (x : F) :
319-
g • (x : L) = x :=
320-
smul_algebraMap (⟨g, hg⟩ : H) x
321-
322-
theorem smul_mem_of_normal (N : Subgroup G) [hN : N.Normal] [hF : IsGaloisGroup N F L] (g : G)
323-
(x : F) : g • (x : L) ∈ F := by
324-
have : ∀ (n : N), n • g • (x : L) = g • x := by
325-
intro n
326-
rw [← smul_assoc, MulAction.subgroup_smul_def, smul_eq_mul,
327-
show n * g = g * (g⁻¹ * n * g) by group, ← smul_eq_mul, smul_assoc,
328-
IsGaloisGroup.smul_eq_self G K L N F (g⁻¹ * (n : G) * g)]
329-
exact hN.conj_mem' n n.prop g
330-
obtain ⟨y, hy⟩ := hF.isInvariant.isInvariant (g • x) this
331-
simp [← hy]
332-
333337
@[simp]
334338
theorem finrank_fixedPoints_eq_card_subgroup [IsGaloisGroup G K L] :
335339
Module.finrank (FixedPoints.intermediateField H : IntermediateField K L) L = Nat.card H :=
@@ -494,64 +498,173 @@ end GaloisCorrespondence
494498

495499
section Quotient
496500

497-
variable (N : Subgroup G) [N.Normal] [hF : IsGaloisGroup N F L]
501+
section Semiring
498502

499-
instance : SMul (G ⧸ N) F where
500-
smul g x := Quotient.liftOn' g (fun g ↦ ⟨g • (x : L), smul_mem_of_normal G K L F N g x⟩)
501-
fun g g' h ↦ Subtype.ext <| by
502-
rw [smul_eq_iff_eq_inv_smul, ← smul_assoc, smul_eq_mul, smul_eq_self G K L N]
503-
rwa [← QuotientGroup.leftRel_apply]
503+
variable (A B C : Type*) [CommSemiring A] [Semiring C] [Algebra A C] [MulSemiringAction G C]
504+
variable (N : Subgroup G) [CommSemiring B] [Algebra B C]
504505

505-
@[simp]
506-
lemma coe_quotient_smul (g : G) (x : F) :
507-
((g : G ⧸ N) • x : F) = g • (x : L) := rfl
508-
509-
instance : MulSemiringAction (G ⧸ N) F where
510-
one_smul _ := Subtype.ext <| by rw [← QuotientGroup.mk_one, coe_quotient_smul, one_smul]
511-
smul_zero g := Quotient.inductionOn' g fun g ↦ Subtype.ext <| by simp
512-
mul_smul g g' x := Quotient.inductionOn₂' g g' fun g g' ↦ Subtype.ext <| by
513-
simp [← QuotientGroup.mk_mul, coe_quotient_smul, mul_smul]
514-
smul_add g x y := Quotient.inductionOn' g fun g ↦ Subtype.ext <| by simp [smul_add]
515-
smul_one g := Quotient.inductionOn' g fun g ↦ Subtype.ext <| by simp
516-
smul_mul g x y := Quotient.inductionOn' g fun g ↦ Subtype.ext <| by simp [smul_mul']
517-
518-
instance [SMulCommClass G K L] : SMulCommClass (G ⧸ N) K F :=
519-
fun g k x ↦ Quotient.inductionOn' g fun g ↦ Subtype.ext <| by simp [smul_comm]⟩
520-
521-
variable [hK : IsGaloisGroup G K L] [Finite G]
506+
/-- If `N` is a normal subgroup of `G` and `IsGaloisGroup N B C`, then `G` acts on `B`.
507+
For `g : G` and `x : B`, `g • x` is the unique element of `B` whose image in `C` is
508+
`g • algebraMap B C x`, see `algebraMap_smulOfNormal`. -/
509+
@[implicit_reducible]
510+
noncomputable def smulOfNormal [N.Normal] [IsGaloisGroup N B C] : SMul G B where
511+
smul g x := (smul_mem_of_normal G C N g x).choose
522512

523-
instance quotient : IsGaloisGroup (G ⧸ N) K F where
513+
@[simp]
514+
theorem algebraMap_smulOfNormal [N.Normal] [IsGaloisGroup N B C] (g : G) (x : B) :
515+
letI := smulOfNormal G B C
516+
algebraMap B C (g • x) = g • algebraMap B C x :=
517+
(smul_mem_of_normal G C N g x).choose_spec
518+
519+
/-- If `N` is normal and `IsGaloisGroup N B C`, the action `smulOfNormal G B C` satisfies
520+
`SMulDistribClass G B C`. -/
521+
instance smulDistribClass_smulOfNormal [N.Normal] [IsGaloisGroup N B C] :
522+
letI := smulOfNormal G B C
523+
SMulDistribClass G B C :=
524+
let := smulOfNormal G B C
525+
fun g b c ↦ by simp [Algebra.smul_def]⟩
526+
527+
variable [FaithfulSMul B C]
528+
529+
/-- If `N` is a normal subgroup of `G` and `IsGaloisGroup N B C`, then `G` acts on `B` as a
530+
`MulSemiringAction`, via the action defined in `smulOfNormal`. -/
531+
@[implicit_reducible]
532+
noncomputable def mulSemiringActionOfNormal [IsGaloisGroup N B C] [N.Normal] :
533+
MulSemiringAction G B := by
534+
let : SMul G B := smulOfNormal G B C N
535+
have : SMulDistribClass G B C := smulDistribClass_smulOfNormal G B C N
536+
exact mulSemiringActionOfSmulDistribClass B C G
537+
538+
/-- If `N` is a normal subgroup of `G` and `IsGaloisGroup N B C`, then the quotient group `G ⧸ N`
539+
acts on `B` by `(g : G ⧸ N) • x = g • x`. -/
540+
@[implicit_reducible]
541+
noncomputable def mulSemiringActionQuotient [IsGaloisGroup N B C] [N.Normal] :
542+
MulSemiringAction (G ⧸ N) B :=
543+
letI := mulSemiringActionOfNormal G B C N
544+
{ smul q x :=
545+
Quotient.liftOn' q (· • x) fun g₁ g₂ h ↦ by
546+
apply FaithfulSMul.algebraMap_injective B C
547+
rw [algebraMap.smul', algebraMap.smul', smul_eq_iff_eq_inv_smul, ← smul_assoc, smul_eq_mul,
548+
Subgroup.smul_algebraMap C (by rwa [← QuotientGroup.leftRel_apply])]
549+
one_smul x := one_smul G x
550+
mul_smul q₁ q₂ x := Quotient.inductionOn₂' q₁ q₂ fun g h ↦ mul_smul g h x
551+
smul_add q x y := Quotient.inductionOn' q fun g ↦ smul_add g x y
552+
smul_zero q := Quotient.inductionOn' q fun g ↦ smul_zero g
553+
smul_one q := Quotient.inductionOn' q fun g ↦ smul_one g
554+
smul_mul q x y := Quotient.inductionOn' q fun g ↦ smul_mul' g x y }
555+
556+
theorem mulSemiringActionQuotient_smul_def [MulSemiringAction G B] [SMulDistribClass G B C]
557+
[IsGaloisGroup N B C] [N.Normal] (g : G) (b : B) :
558+
letI := mulSemiringActionQuotient G B C N
559+
(g : G ⧸ N) • b = g • b := by
560+
let := mulSemiringActionOfNormal G B C N
561+
refine (Quotient.liftOn'_mk'' (· • b) _ g).trans (FaithfulSMul.algebraMap_injective B C ?_)
562+
rw [algebraMap.smul', algebraMap.smul']
563+
564+
theorem isScalarTower_mulSemiringActionQuotient [MulSemiringAction G B] [SMulDistribClass G B C]
565+
[IsGaloisGroup N B C] [N.Normal] :
566+
letI := mulSemiringActionQuotient G B C N
567+
IsScalarTower G (G ⧸ N) B :=
568+
let := mulSemiringActionQuotient G B C N
569+
fun g q b ↦ Quotient.inductionOn' q fun h ↦ by
570+
simp [mul_smul, mulSemiringActionQuotient_smul_def]⟩
571+
572+
/-- If `G` acts on `C` commuting with `A`, then the action of `G ⧸ N` on `B` commutes with `A`. -/
573+
@[implicit_reducible]
574+
def smulCommClassQuotient [N.Normal] [Algebra A B] [IsScalarTower A B C] [SMulCommClass G A C]
575+
[MulSemiringAction G B] [MulAction (G ⧸ N) B] [SMulDistribClass G B C]
576+
[IsScalarTower G (G ⧸ N) B] :
577+
SMulCommClass (G ⧸ N) A B :=
578+
fun g k x ↦ Quotient.inductionOn' g fun g ↦
579+
FaithfulSMul.algebraMap_injective B C (by
580+
simp [algebraMap.smul, algebraMap.smul', smul_comm])⟩
581+
582+
end Semiring
583+
584+
section Domain
585+
586+
variable (A B C : Type*) [CommRing A] [CommRing B] [CommRing C] [IsDomain C] [Algebra A B]
587+
[Algebra A C] [Algebra B C] [FaithfulSMul A C] [FaithfulSMul B C] [IsScalarTower A B C]
588+
589+
/-- If `G` is a Galois group for `C/A`, and the normal subgroup `N ≤ G` is a Galois group for
590+
`C/B`, then the quotient `G ⧸ N` is a Galois group for `B/A`. -/
591+
theorem quotient [Finite G] (N : Subgroup G) [N.Normal] [MulSemiringAction G C]
592+
[hG : IsGaloisGroup G A C] [MulSemiringAction G B] [MulSemiringAction (G ⧸ N) B]
593+
[SMulCommClass (G ⧸ N) A B] [SMulDistribClass G B C] [IsScalarTower G (G ⧸ N) B]
594+
[IsGaloisGroup N B C] :
595+
IsGaloisGroup (G ⧸ N) A B where
524596
faithful.eq_of_smul_eq_smul := fun {g₁} {g₂} ↦ Quotient.inductionOn₂' g₁ g₂ fun g₁ g₂ h ↦ by
525-
rw [QuotientGroup.eq, ← fixingSubgroup_fixedPoints G K L N, subgroup_iff.mp hF,
526-
mem_fixingSubgroup_iff]
527-
intro x hx
528-
rw [mul_smul, inv_smul_eq_iff]
529-
simpa [eq_comm, coe_quotient_smul] using congr_arg Subtype.val <| h ⟨x, hx⟩
597+
have h' : ∀ g : G, (∀ x : B, g • x = x) → g ∈ N := by
598+
simp [← fixingSubgroup_range_algebraMap G A B C N, mem_fixingSubgroup_iff, ← algebraMap.smul',
599+
(FaithfulSMul.algebraMap_injective B C).eq_iff]
600+
have {g : G} : Quotient.mk'' g = QuotientGroup.mk' N g := rfl
601+
simp_rw [← inv_smul_eq_iff, this, ← map_inv, smul_smul, ← map_mul,
602+
QuotientGroup.mk'_apply, MulAction.coe_quotient_smul] at h
603+
have := h' _ h
604+
rwa [QuotientGroup.eq, ← Subgroup.inv_mem_iff, mul_inv_rev, inv_inv]
530605
commutes := inferInstance
531-
isInvariant.isInvariant := fun x h ↦ by
532-
have : ∀ (g : G), g • (x : L) = x := fun g ↦ by
533-
simpa [coe_quotient_smul] using congr_arg Subtype.val (h g)
534-
obtain ⟨a, ha⟩ := hK.isInvariant.isInvariant x this
535-
refine ⟨a, FaithfulSMul.algebraMap_injective F L ?_⟩
536-
rw [← IsScalarTower.algebraMap_apply, ha, IntermediateField.algebraMap_apply]
606+
isInvariant.isInvariant x h := by
607+
simp_rw [← (FaithfulSMul.algebraMap_injective B C).eq_iff, ← IsScalarTower.algebraMap_apply]
608+
apply hG.isInvariant.isInvariant (algebraMap B C x)
609+
intro g
610+
have := (FaithfulSMul.algebraMap_injective B C).eq_iff.mpr <| h g
611+
rwa [MulAction.coe_quotient_smul, algebraMap.smul'] at this
612+
613+
end Domain
614+
615+
noncomputable section IntermediateField
616+
617+
variable (N : Subgroup G) [N.Normal] [IsGaloisGroup N F L]
618+
619+
instance : MulSemiringAction (G ⧸ N) F :=
620+
letI := smulOfNormal G F L N
621+
haveI := smulDistribClass_smulOfNormal G F L N
622+
letI := mulSemiringActionOfSmulDistribClass F L G
623+
mulSemiringActionQuotient G F L N
624+
625+
instance [SMulCommClass G K L] [MulSemiringAction G F] [SMulDistribClass G F L]
626+
[IsScalarTower G (G ⧸ N) F] : SMulCommClass (G ⧸ N) K F :=
627+
smulCommClassQuotient G K F L N
628+
629+
/-- If `G` is a finite Galois group for `L/K` and `N` is a normal subgroup of `G` that is a
630+
Galois group for `L/F`, then the quotient group `G ⧸ N` is a Galois group for `F/K`. -/
631+
instance [Finite G] [IsGaloisGroup G K L] : IsGaloisGroup (G ⧸ N) K F :=
632+
letI := smulOfNormal G F L N
633+
haveI := smulDistribClass_smulOfNormal G F L N
634+
letI := mulSemiringActionOfSmulDistribClass F L G
635+
haveI := isScalarTower_mulSemiringActionQuotient G F L N
636+
quotient G K F L N
537637

538638
variable (E : IntermediateField K L) [hE : IsGaloisGroup H E L]
539639

540-
theorem quotientMap (h : E ≤ F) :
640+
/-- If `G` is a finite Galois group for `L/K`, `N` is a normal subgroup that is a Galois group for
641+
`L/F`, and `H` is a subgroup that is a Galois group for `L/E` with `E ≤ F`, then the image of `H`
642+
under the canonical quotient map `G → G ⧸ N` is a Galois group for `F/E`. -/
643+
theorem map_quotientMk' [Finite G] [IsGaloisGroup G K L] (h : E ≤ F) :
541644
letI : Algebra E F := (IntermediateField.inclusion h).toAlgebra
542645
IsGaloisGroup (H.map (QuotientGroup.mk' N)) E F :=
543-
have hFN : IsGaloisGroup (G ⧸ N) K F := inferInstance
544646
let : Algebra E F := (IntermediateField.inclusion h).toAlgebra
545-
{ faithful := by have := hFN.faithful; infer_instance
647+
let : SMul G F := smulOfNormal G F L N
648+
have : SMulDistribClass G F L := smulDistribClass_smulOfNormal G F L N
649+
let := mulSemiringActionOfSmulDistribClass F L G
650+
have : IsScalarTower E F L := IsScalarTower.of_algebraMap_eq' rfl
651+
have := isScalarTower_mulSemiringActionQuotient G F L N
652+
{ faithful := have := (inferInstance : IsGaloisGroup (G ⧸ N) K F).faithful; inferInstance
546653
commutes := ⟨by
547654
intro ⟨_, g, hg, rfl⟩ x y
548-
exact FaithfulSMul.algebraMap_injective F L (hE.commutes.smul_comm ⟨g, hg⟩ x (y : L))⟩
655+
apply FaithfulSMul.algebraMap_injective F L
656+
simpa [MulAction.subgroup_smul_def, algebraMap.coe_smul', algebraMap.coe_smul]
657+
using hE.commutes.smul_comm ⟨g, hg⟩ x (y : L)⟩
549658
isInvariant := ⟨fun x h ↦ by
550-
obtain ⟨a, ha⟩ := hE.isInvariant.isInvariant x
551-
fun ⟨g, hg⟩ ↦ congr_arg Subtype.val (h ⟨g, g, hg, rfl⟩)
552-
have : IsScalarTower E F L := IsScalarTower.of_algebraMap_eq' rfl
659+
obtain ⟨a, ha⟩ := hE.isInvariant.isInvariant (algebraMap F L x) (by
660+
rintro ⟨g, hg⟩
661+
simpa only [← algebraMap.smul'] using congr_arg (algebraMap F L) <| h ⟨g, ⟨g, hg, rfl⟩⟩)
553662
exact ⟨a, FaithfulSMul.algebraMap_injective F L
554-
(by rw [← IsScalarTower.algebraMap_apply, ha, IntermediateField.algebraMap_apply])⟩⟩ }
663+
(by rw [← IsScalarTower.algebraMap_apply, ha])⟩⟩ }
664+
665+
@[deprecated (since := "2026-04-21")] alias quotientMap := map_quotientMk'
666+
667+
end IntermediateField
555668

556669
end Quotient
557670

Mathlib/GroupTheory/GroupAction/Quotient.lean

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,13 @@ theorem _root_.MulActionHom.toQuotient_apply (H : Subgroup α) (g : α) :
125125
MulActionHom.toQuotient H g = g :=
126126
rfl
127127

128+
@[to_additive (attr := simp)]
129+
theorem coe_quotient_smul {H : Subgroup α} [H.Normal] [SMul α β]
130+
[MulAction (α ⧸ H) β] [IsScalarTower α (α ⧸ H) β] (g : α) (x : β) :
131+
(g : α ⧸ H) • x = g • x := by
132+
rw [← smul_one_smul (α ⧸ H) g x, ← QuotientGroup.mk_one, Quotient.smul_coe,
133+
smul_eq_mul, mul_one]
134+
128135
@[to_additive]
129136
instance mulLeftCosetsCompSubtypeVal (H I : Subgroup α) : MulAction I (α ⧸ H) :=
130137
MulAction.compHom (α ⧸ H) (Subgroup.subtype I)

0 commit comments

Comments
 (0)