From 7884decd0a31ad70f23cc8c33e97c101e8a077c6 Mon Sep 17 00:00:00 2001 From: Xavier Roblot <46200072+xroblot@users.noreply.github.com> Date: Sun, 21 Jun 2026 16:05:10 +0200 Subject: [PATCH 1/3] Merge #38864 (restrictHom1): add restrictHom and quotientMulEquiv --- Mathlib/FieldTheory/Galois/IsGaloisGroup.lean | 125 +++++++++++++++++- 1 file changed, 122 insertions(+), 3 deletions(-) diff --git a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean index 1495a47a590cae..b5766d8bd44dfc 100644 --- a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean +++ b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean @@ -376,6 +376,12 @@ theorem mulEquivCongr_symm_apply_smul (g : G') (x : B) : end IsDomain +theorem mulEquivCongr_mapSubgroup_fixingSubgroup (F : Set L) [IsGaloisGroup G K L] [Finite G] + [IsGaloisGroup G' K L] [Finite G'] : + (fixingSubgroup G F).map (mulEquivCongr G G' K L) = fixingSubgroup G' F := by + ext g + simp [Subgroup.map_equiv_eq_comap_symm, mem_fixingSubgroup_iff] + variable (H H' : Subgroup G) (F F' : IntermediateField K L) instance (R S : Type*) [CommRing R] [CommRing S] [Algebra R S] @@ -430,6 +436,17 @@ instance intermediateField [Finite G] [hGKL : IsGaloisGroup G K L] : have := hGKL.isGalois .of_mulEquiv_algEquiv e fun _ _ ↦ rfl +include K in +/-- If `G` is a Galois group on `L/K` and `L/E/K` is a tower of field extensions, +then the fixing subgroup of the image of `E` in `L` is a Galois group on `L/E`. -/ +theorem of_isScalarTower [Finite G] [IsGaloisGroup G K L] (E : Type*) [Field E] [Algebra K E] + [Algebra E L] [IsScalarTower K E L] : + IsGaloisGroup (fixingSubgroup G (Set.range (algebraMap E L))) E L := by + rw [← IsScalarTower.toAlgHom_fieldRange K E L] + refine IsGaloisGroup.of_ringEquiv _ _ _ L + (AlgHom.equivFieldRange (IsScalarTower.toAlgHom K E L)).toRingEquiv.symm fun ⟨_, ⟨x, rfl⟩⟩ ↦ ?_ + simp [AlgEquiv.symm_apply_eq, Subtype.ext_iff] + @[simp] theorem card_fixingSubgroup_eq_finrank [Finite G] [IsGaloisGroup G K L] : Nat.card (fixingSubgroup G (F : Set L)) = Module.finrank F L := @@ -566,6 +583,20 @@ theorem fixingSubgroup_range_algebraMap [Finite G] (A B C : Type*) (H : Subgroup use algebraMap B (FractionRing B) x rw [← IsScalarTower.algebraMap_apply, ← IsScalarTower.algebraMap_apply] +open Pointwise in +/-- If `G` is a finite Galois group for `L/K`, `H` is a Galois group for `L/E`, and `E/K` is +Galois, then `H` is a normal subgroup of `G`. -/ +theorem normal_of_isGalois (E : Type*) [Field E] [Algebra K E] [Algebra E L] [IsScalarTower K E L] + [Finite G] [IsGaloisGroup H E L] [IsGalois K E] : H.Normal := by + let F := (IsScalarTower.toAlgHom K E L).fieldRange + have : IsGalois K F := .of_algEquiv (IsScalarTower.toAlgHom K E L).equivFieldRange + have hFL : IsGaloisGroup H F L := inferInstanceAs (IsGaloisGroup H (algebraMap E L).range L) + have := isGalois G K L + have : Finite Gal(L/K) := Finite.of_equiv _ (mulEquivAlgEquiv G K L).toEquiv + rw [← fixingSubgroup_fixedPoints G K L H, subgroup_iff.mp hFL, + ← mulEquivCongr_mapSubgroup_fixingSubgroup Gal(L/K) G K, MulEquiv.normal_map_iff ] + exact IsGalois.fixingSubgroup_normal_of_isGalois F + end IsGaloisGroup end GaloisCorrespondence @@ -635,7 +666,7 @@ theorem mulSemiringActionQuotient_smul_def [MulSemiringAction G B] [SMulDistribC refine (Quotient.liftOn'_mk'' (· • b) _ g).trans (FaithfulSMul.algebraMap_injective B C ?_) rw [algebraMap.smul', algebraMap.smul'] -theorem isScalarTower_mulSemiringActionQuotient [MulSemiringAction G B] [SMulDistribClass G B C] +instance isScalarTower_mulSemiringActionQuotient [MulSemiringAction G B] [SMulDistribClass G B C] [IsGaloisGroup N B C] [N.Normal] : letI := mulSemiringActionQuotient G B C N IsScalarTower G (G ⧸ N) B := @@ -659,7 +690,7 @@ end Semiring section Domain variable (A B C : Type*) [CommRing A] [CommRing B] [CommRing C] [IsDomain C] [Algebra A B] - [Algebra A C] [Algebra B C] [FaithfulSMul A C] [FaithfulSMul B C] [IsScalarTower A B C] + [Algebra A C] [Algebra B C] [FaithfulSMul A B] [FaithfulSMul B C] [IsScalarTower A B C] /-- If `G` is a Galois group for `C/A`, and the normal subgroup `N ≤ G` is a Galois group for `C/B`, then the quotient `G ⧸ N` is a Galois group for `B/A`. -/ @@ -669,6 +700,7 @@ theorem quotient [Finite G] (N : Subgroup G) [N.Normal] [MulSemiringAction G C] [IsGaloisGroup N B C] : IsGaloisGroup (G ⧸ N) A B where faithful.eq_of_smul_eq_smul := fun {g₁} {g₂} ↦ Quotient.inductionOn₂' g₁ g₂ fun g₁ g₂ h ↦ by + have : FaithfulSMul A C := FaithfulSMul.trans A B C have h' : ∀ g : G, (∀ x : B, g • x = x) → g ∈ N := by simp [← fixingSubgroup_range_algebraMap G A B C N, mem_fixingSubgroup_iff, ← algebraMap.smul', (FaithfulSMul.algebraMap_injective B C).eq_iff] @@ -685,6 +717,92 @@ theorem quotient [Finite G] (N : Subgroup G) [N.Normal] [MulSemiringAction G C] have := (FaithfulSMul.algebraMap_injective B C).eq_iff.mpr <| h g rwa [MulAction.coe_quotient_smul, algebraMap.smul'] at this +/-- If `G` is a Galois group for `C/A`, the normal subgroup `N ≤ G` is a Galois group for `C/B`, +and `G'` is a Galois group for `B/A`, then `G ⧸ N ≃* G'`. -/ +noncomputable def quotientMulEquiv [Finite G] [Finite G'] (N : Subgroup G) [N.Normal] + [MulSemiringAction G C] [IsGaloisGroup G A C] [IsGaloisGroup N B C] [MulSemiringAction G' B] + [IsGaloisGroup G' A B] : + G ⧸ N ≃* G' := + haveI : IsDomain B := (FaithfulSMul.algebraMap_injective B C).isDomain + letI := mulSemiringActionOfNormal G B C N + letI := mulSemiringActionQuotient G B C N + haveI := smulCommClassQuotient G A B C N + haveI := quotient G A B C N + mulEquivCongr (G ⧸ N) G' A B + +@[simp] +theorem algebraMap_quotientMulEquiv_smul [Finite G] [Finite G'] (N : Subgroup G) [N.Normal] + [MulSemiringAction G C] [IsGaloisGroup G A C] [IsGaloisGroup N B C] [MulSemiringAction G' B] + [IsGaloisGroup G' A B] (g : G) (x : B) : + algebraMap B C (quotientMulEquiv G G' A B C N g • x) = g • algebraMap B C x := by + haveI : IsDomain B := (FaithfulSMul.algebraMap_injective B C).isDomain + letI := mulSemiringActionOfNormal G B C N + letI := mulSemiringActionQuotient G B C N + haveI := smulCommClassQuotient G A B C N + haveI := quotient G A B C N + rw [← algebraMap_smulOfNormal G B C N g x] + congr + apply mulEquivCongr_apply_smul + +attribute [local instance] FractionRing.liftAlgebra in +/-- The restriction homomorphism from the Galois group of `C/A` to the Galois group of `B/A` where +`C/B/A` is a tower of domains with `C/A` and `B/A` Galois. -/ +noncomputable def restrictHom [Finite G] [Finite G'] [MulSemiringAction G C] [IsGaloisGroup G A C] + [MulSemiringAction G' B] [IsGaloisGroup G' A B] : + G →* G' := + haveI : IsDomain B := IsDomain.of_faithfulSMul B C + haveI : IsDomain A := IsDomain.of_faithfulSMul A B + haveI : FaithfulSMul A C := FaithfulSMul.trans A B C + letI : MulSemiringAction G (FractionRing C) := + IsFractionRing.mulSemiringAction G C (FractionRing C) + letI N := fixingSubgroup G (Set.range (algebraMap (FractionRing B) (FractionRing C))) + haveI : IsGaloisGroup N (FractionRing B) (FractionRing C) := + of_isScalarTower G (FractionRing A) (FractionRing C) (FractionRing B) + letI : MulSemiringAction G' (FractionRing B) := + IsFractionRing.mulSemiringAction G' B (FractionRing B) + haveI := isGalois G' (FractionRing A) (FractionRing B) + haveI : N.Normal := normal_of_isGalois G (FractionRing A) (FractionRing C) N (FractionRing B) + (quotientMulEquiv G G' (FractionRing A) (FractionRing B) (FractionRing C) N).toMonoidHom.comp + (QuotientGroup.mk' N) + +attribute [local instance] FractionRing.liftAlgebra in +@[simp] +theorem algebraMap_restrictHom_smul [Finite G] [Finite G'] [MulSemiringAction G C] + [IsGaloisGroup G A C] [MulSemiringAction G' B] [IsGaloisGroup G' A B] (g : G) (x : B) : + algebraMap B C (restrictHom G G' A B C g • x) = g • algebraMap B C x := by + have : IsDomain B := IsDomain.of_faithfulSMul B C + have : IsDomain A := IsDomain.of_faithfulSMul A B + have : FaithfulSMul A C := FaithfulSMul.trans A B C + let : MulSemiringAction G (FractionRing C) := + IsFractionRing.mulSemiringAction G C (FractionRing C) + let : MulSemiringAction G' (FractionRing B) := + IsFractionRing.mulSemiringAction G' B (FractionRing B) + apply FaithfulSMul.algebraMap_injective C (FractionRing C) + rw [← IsScalarTower.algebraMap_apply, + IsScalarTower.algebraMap_apply B (FractionRing B) (FractionRing C)] + simp only [restrictHom, MulEquiv.toMonoidHom_eq_coe, MonoidHom.coe_comp, MonoidHom.coe_coe, + QuotientGroup.coe_mk', Function.comp_apply] + rw [algebraMap.smul', algebraMap_quotientMulEquiv_smul, ← IsScalarTower.algebraMap_apply, + algebraMap.smul', ← IsScalarTower.algebraMap_apply] + +attribute [local instance] FractionRing.liftAlgebra in +theorem restrictHom_surjective [Finite G] [Finite G'] [MulSemiringAction G C] + [IsGaloisGroup G A C] [MulSemiringAction G' B] [IsGaloisGroup G' A B] : + Function.Surjective (restrictHom G G' A B C) := by + have : IsDomain B := IsDomain.of_faithfulSMul B C + have : IsDomain A := IsDomain.of_faithfulSMul A B + have : FaithfulSMul A C := FaithfulSMul.trans A B C + let : MulSemiringAction G (FractionRing C) := + IsFractionRing.mulSemiringAction G C (FractionRing C) + let N := fixingSubgroup G (Set.range (algebraMap (FractionRing B) (FractionRing C))) + have : IsGaloisGroup N (FractionRing B) (FractionRing C) := + of_isScalarTower G (FractionRing A) (FractionRing C) (FractionRing B) + let : MulSemiringAction G' (FractionRing B) := + IsFractionRing.mulSemiringAction G' B (FractionRing B) + have := isGalois G' (FractionRing A) (FractionRing B) + have : N.Normal := normal_of_isGalois G (FractionRing A) (FractionRing C) N (FractionRing B) + simpa [restrictHom] using QuotientGroup.mk_surjective + end Domain noncomputable section IntermediateField @@ -733,7 +851,8 @@ theorem map_quotientMk' [Finite G] [IsGaloisGroup G K L] (h : E ≤ F) : isInvariant := ⟨fun x h ↦ by obtain ⟨a, ha⟩ := hE.isInvariant.isInvariant (algebraMap F L x) (by rintro ⟨g, hg⟩ - simpa only [← algebraMap.smul'] using! congr_arg (algebraMap F L) <| h ⟨g, ⟨g, hg, rfl⟩⟩) + rw [MulAction.subgroup_smul_def, ← algebraMap.smul'] + exact congr_arg (algebraMap F L) <| h ⟨g, ⟨g, hg, rfl⟩⟩) exact ⟨a, FaithfulSMul.algebraMap_injective F L (by rw [← IsScalarTower.algebraMap_apply, ha])⟩⟩ } From 5f0ca670c2a94968ecc18424bfb77d97868a0621 Mon Sep 17 00:00:00 2001 From: Xavier Roblot <46200072+xroblot@users.noreply.github.com> Date: Sun, 21 Jun 2026 16:06:22 +0200 Subject: [PATCH 2/3] Merge #40864 (fixingsubgroup-fractionring): add IsFractionRing.fixingSubgroup_range_algebraMap + golf --- Mathlib/FieldTheory/Galois/IsGaloisGroup.lean | 15 +----------- .../RingTheory/Localization/FractionRing.lean | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean index b5766d8bd44dfc..71b8720f034af5 100644 --- a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean +++ b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean @@ -568,20 +568,7 @@ theorem fixingSubgroup_range_algebraMap [Finite G] (A B C : Type*) (H : Subgroup let : MulSemiringAction G L := IsFractionRing.mulSemiringAction G C L have : IsGaloisGroup H (FractionRing B) L := IsGaloisGroup.toFractionRing H B C rw [← fixingSubgroup_range_algebraMap' G K L H (FractionRing B)] - ext g - simp only [mem_fixingSubgroup_iff, Set.mem_range] - refine ⟨?_, ?_⟩ - · rintro h _ ⟨x, rfl⟩ - have {x} : g • (algebraMap B L) x = (algebraMap B L) x := by - rw [IsScalarTower.algebraMap_apply B C L, ← algebraMap.smul', h _ ⟨x, rfl⟩] - obtain ⟨a, b, _, rfl⟩ := IsFractionRing.div_surjective B x - simp only [map_div₀, ← IsScalarTower.algebraMap_apply, smul_div₀', this] - · rintro h _ ⟨x, rfl⟩ - apply FaithfulSMul.algebraMap_injective C L - rw [algebraMap.smul'] - apply h - use algebraMap B (FractionRing B) x - rw [← IsScalarTower.algebraMap_apply, ← IsScalarTower.algebraMap_apply] + exact IsFractionRing.fixingSubgroup_range_algebraMap G (FractionRing B) L open Pointwise in /-- If `G` is a finite Galois group for `L/K`, `H` is a Galois group for `L/E`, and `E/K` is diff --git a/Mathlib/RingTheory/Localization/FractionRing.lean b/Mathlib/RingTheory/Localization/FractionRing.lean index 54d432f40eba71..e520d4ae754eb5 100644 --- a/Mathlib/RingTheory/Localization/FractionRing.lean +++ b/Mathlib/RingTheory/Localization/FractionRing.lean @@ -10,6 +10,7 @@ public import Mathlib.Algebra.Field.Subfield.Basic public import Mathlib.Algebra.Order.GroupWithZero.Submonoid public import Mathlib.Algebra.Order.Ring.Int public import Mathlib.Algebra.Ring.CompTypeclasses +public import Mathlib.GroupTheory.GroupAction.FixingSubgroup public import Mathlib.RingTheory.Localization.Basic public import Mathlib.RingTheory.SimpleRing.Basic @@ -677,6 +678,28 @@ protected theorem smulCommClass [SMulCommClass G A B] : SMulCommClass G K L := IsScalarTower.algebraMap_apply A B L, smul_mul', smul_div₀', ← algebraMap.coe_smul', smul_algebraMap]⟩ +variable {A B} in +/-- If `K` is the fraction field of `A` and `L` is the fraction field of `B` with `A ⊆ B`, +then for `G` acting on `B` and `L`, the fixing subgroup of `A` in `B` equals the fixing subgroup +of `K` in `L`. -/ +theorem fixingSubgroup_range_algebraMap : + fixingSubgroup G (Set.range (algebraMap A B)) = + fixingSubgroup G (Set.range (algebraMap K L)) := by + ext g + simp only [mem_fixingSubgroup_iff, Set.mem_range] + refine ⟨?_, ?_⟩ + · rintro h _ ⟨x, rfl⟩ + have {x} : g • (algebraMap A L) x = (algebraMap A L) x := by + rw [IsScalarTower.algebraMap_apply A B L, ← algebraMap.smul', h _ ⟨x, rfl⟩] + obtain ⟨a, b, _, rfl⟩ := IsFractionRing.div_surjective A x + simp only [map_div₀, ← IsScalarTower.algebraMap_apply, smul_div₀', this] + · rintro h _ ⟨x, rfl⟩ + apply FaithfulSMul.algebraMap_injective B L + rw [algebraMap.smul'] + apply h + use algebraMap A K x + rw [← IsScalarTower.algebraMap_apply, ← IsScalarTower.algebraMap_apply] + end MulAction end IsFractionRing From 0918158941159621e20351d9238140e504c6db95 Mon Sep 17 00:00:00 2001 From: Xavier Roblot <46200072+xroblot@users.noreply.github.com> Date: Sun, 21 Jun 2026 16:42:04 +0200 Subject: [PATCH 3/3] feat(FieldTheory/Galois/IsGaloisGroup): add IsGaloisGroup.of_isScalarTower' for towers of domains --- Mathlib/FieldTheory/Galois/IsGaloisGroup.lean | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean index 71b8720f034af5..4fd0ce14e47acc 100644 --- a/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean +++ b/Mathlib/FieldTheory/Galois/IsGaloisGroup.lean @@ -447,6 +447,27 @@ theorem of_isScalarTower [Finite G] [IsGaloisGroup G K L] (E : Type*) [Field E] (AlgHom.equivFieldRange (IsScalarTower.toAlgHom K E L)).toRingEquiv.symm fun ⟨_, ⟨x, rfl⟩⟩ ↦ ?_ simp [AlgEquiv.symm_apply_eq, Subtype.ext_iff] +attribute [local instance] FractionRing.liftAlgebra in +/-- If `G` is a Galois group for `B / R` and `R ⊆ A ⊆ B` is a tower of commutative domains with +`B / A` integral and `A` integrally closed, then the fixing subgroup of the image of `A` in `B` +is a Galois group for `B / A`. -/ +theorem of_isScalarTower' [Finite G] (R A B : Type*) [CommRing R] [CommRing A] [CommRing B] + [IsDomain B] [Algebra R A] [Algebra A B] [Algebra R B] [IsScalarTower R A B] + [FaithfulSMul R A] [FaithfulSMul A B] [MulSemiringAction G B] [IsGaloisGroup G R B] + [IsIntegrallyClosed A] [Algebra.IsIntegral A B] : + IsGaloisGroup (fixingSubgroup G (Set.range (algebraMap A B))) A B := by + have : IsDomain A := IsDomain.of_faithfulSMul A B + have : IsDomain R := IsDomain.of_faithfulSMul R A + have : FaithfulSMul R B := FaithfulSMul.trans R A B + let F := FractionRing A + let K := FractionRing R + let L := FractionRing B + let : MulSemiringAction G L := IsFractionRing.mulSemiringAction G B L + rw [IsFractionRing.fixingSubgroup_range_algebraMap G F L] + have : IsGaloisGroup (fixingSubgroup G (Set.range (algebraMap F L))) F L := + of_isScalarTower G K L F + exact IsGaloisGroup.of_isFractionRing _ A B F L + @[simp] theorem card_fixingSubgroup_eq_finrank [Finite G] [IsGaloisGroup G K L] : Nat.card (fixingSubgroup G (F : Set L)) = Module.finrank F L :=