Skip to content

Commit f2df8d3

Browse files
mariainesdffxroblot
authored andcommitted
feat(RingTheory/ClassGroup): prove mulEquiv (leanprover-community#35535)
We prove that isomorphic rings have isomorphic class groups. Co-authored by: @xgenereux. Co-authored-by: mariainesdff <mariaines.dff@gmail.com>
1 parent c4e37d8 commit f2df8d3

6 files changed

Lines changed: 216 additions & 9 deletions

File tree

Mathlib/Algebra/Ring/CompTypeclasses.lean

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,8 @@ def toRingEquiv : R₁ ≃+* R₂ := .ofRingHom σ σ' comp_eq₂ comp_eq
120120
121121
This is not an instance, as for equivalences that are involutions, a better instance
122122
would be `RingHomInvPair e e`.
123-
124-
This declaration should not be used as an instance to state a theorem,
125-
but it may be useful sometimes in the middle of a proof.
126123
-/
127-
theorem of_ringEquiv (e : R₁ ≃+* R₂) : RingHomInvPair (↑e : R₁ →+* R₂) ↑e.symm :=
124+
lemma of_ringEquiv (e : R₁ ≃+* R₂) : RingHomInvPair (↑e : R₁ →+* R₂) ↑e.symm :=
128125
⟨e.symm_toRingHom_comp_toRingHom, e.symm.symm_toRingHom_comp_toRingHom⟩
129126

130127
/-- Construct a `RingHomInvPair` from both directions of a ring equiv.

Mathlib/RingTheory/ClassGroup.lean

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,3 +414,43 @@ theorem card_classGroup_eq_one_iff [IsDedekindDomain R] [Fintype (ClassGroup R)]
414414
by_cases hI : I = ⊥
415415
· rw [hI]; exact bot_isPrincipal
416416
· exact (ClassGroup.mk0_eq_one_iff (mem_nonZeroDivisors_iff_ne_zero.mpr hI)).mp (eq_one _)
417+
418+
section MulEquiv
419+
420+
theorem FractionalIdeal.map_ringEquivOfRingEquiv_toPrincipalIdeal {S L : Type*} [CommRing S]
421+
[IsDomain S] [Field L] [Algebra S L] [IsFractionRing S L] (f : R ≃+* S) :
422+
Subgroup.map ((Units.mapEquiv (ringEquivOfRingEquiv K L f))).toMonoidHom
423+
(toPrincipalIdeal R K).range = (toPrincipalIdeal S L).range := by
424+
ext I
425+
simp only [MulEquiv.toMonoidHom_eq_coe, Subgroup.mem_map, MonoidHom.mem_range,
426+
toPrincipalIdeal_eq_iff, MonoidHom.coe_coe]
427+
refine ⟨fun ⟨u, ⟨v, huv⟩, hu⟩ ↦ ?_, fun ⟨u, hu⟩ ↦ ?_⟩
428+
· use Units.map (IsFractionRing.ringEquivOfRingEquiv f (K := K)
429+
(L := L)).toRingHom v
430+
rw [← hu]
431+
simp only [RingEquiv.toRingHom_eq_coe, Units.coe_map, MonoidHom.coe_coe, RingHom.coe_coe,
432+
Units.coe_mapEquiv, ← huv, RingEquiv.coe_toMulEquiv]
433+
rw [FractionalIdeal.ringEquivOfRingEquiv_spanSingleton]
434+
· use Units.mapEquiv (FractionalIdeal.ringEquivOfRingEquiv _ _ f).symm.toMulEquiv I
435+
refine ⟨?_, by simp [← Units.val_inj]⟩
436+
· use Units.map (IsFractionRing.ringEquivOfRingEquiv f (K := K)
437+
(L := L)).symm.toRingHom u
438+
simp only [IsFractionRing.ringEquivOfRingEquiv_symm, RingEquiv.toRingHom_eq_coe,
439+
Units.coe_map, MonoidHom.coe_coe, RingHom.coe_coe, RingEquiv.toMulEquiv_eq_coe,
440+
RingEquiv.coe_toMulEquiv_symm, Units.coe_mapEquiv]
441+
rw [← FractionalIdeal.ringEquivOfRingEquiv_spanSingleton,
442+
← FractionalIdeal.ringEquivOfRingEquiv_symm_eq, hu]
443+
rfl
444+
445+
/-- A ring isomorphism `R ≃+* R'` induces an isomorphism on their class groups. -/
446+
@[simps!]
447+
noncomputable def ClassGroup.mulEquiv {R' : Type*} [CommRing R'] [IsDomain R'] (g : R ≃+* R') :
448+
ClassGroup R ≃* ClassGroup R' :=
449+
(ClassGroup.equiv (R := R) (FractionRing R)).trans
450+
((QuotientGroup.congr (toPrincipalIdeal R (FractionRing R)).range
451+
(toPrincipalIdeal R' (FractionRing R')).range
452+
(Units.mapEquiv (FractionalIdeal.ringEquivOfRingEquiv (FractionRing R) (FractionRing R') g))
453+
(FractionalIdeal.map_ringEquivOfRingEquiv_toPrincipalIdeal g)).trans
454+
(ClassGroup.equiv (FractionRing R')).symm)
455+
456+
end MulEquiv

Mathlib/RingTheory/FractionalIdeal/Operations.lean

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -907,4 +907,124 @@ theorem mem_adjoinIntegral_self (hx : IsIntegral R x) : x ∈ adjoinIntegral S x
907907

908908
end Adjoin
909909

910+
section RingEquiv
911+
912+
open IsFractionRing
913+
914+
variable {R S : Type*} (K L : Type*) [CommRing R] [IsDomain R] [CommRing S] [IsDomain S]
915+
[CommRing K] [CommRing L] [Algebra R K] [Algebra S L] [IsFractionRing R K] [IsFractionRing S L]
916+
(f : R ≃+* S)
917+
918+
local instance (f : R ≃+* S) : RingHomInvPair (f : R →+* S) f.symm :=
919+
RingHomInvPair.of_ringEquiv f
920+
921+
/-- If `f : R ≃+* S` is a ring isomorphism and `I : Submodule R K` is fractional with respect to
922+
`R⁰`, then `I.map (IsFractionRing.semilinearEquivOfRingEquiv K L f).toLinearMap`
923+
is fractional with respect to `S⁰`.
924+
925+
Do not confuse with `IsFractional.map`. -/
926+
theorem _root_.IsFractional.mapEquiv {I : Submodule R K} (hI : IsFractional R⁰ I) :
927+
IsFractional S⁰ (I.map (semilinearEquivOfRingEquiv K L f).toLinearMap) := by
928+
simp only [IsFractional, mem_nonZeroDivisors_iff_ne_zero, ne_eq, Submodule.mem_map,
929+
forall_exists_index, and_imp, forall_apply_eq_imp_iff₂] at hI ⊢
930+
obtain ⟨r, hr0, hr⟩ := hI
931+
use f r
932+
refine ⟨by simp [hr0], ?_⟩
933+
intro x hx
934+
specialize hr x hx
935+
simp only [IsLocalization.IsInteger, RingHom.mem_rangeS] at hr ⊢
936+
obtain ⟨r', hr'⟩ := hr
937+
use f r'
938+
simp only [semilinearEquivOfRingEquiv, RingEquiv.toEquiv_eq_coe, Equiv.toFun_as_coe,
939+
EquivLike.coe_coe, Equiv.invFun_as_coe, LinearMap.coe_mk, AddHom.coe_mk]
940+
rw [Algebra.smul_def, ← ringEquivOfRingEquiv_algebraMap f (K := K) (L := L) r,
941+
← map_mul, ← Algebra.smul_def, ← hr', ringEquivOfRingEquiv_algebraMap]
942+
943+
/-- The equiv `FractionalIdeal R⁰ K ≃+* FractionalIdeal S⁰ L`
944+
induced by a ring isomorphism `f : R ≃+* S`. -/
945+
@[simps -isSimp]
946+
noncomputable def ringEquivOfRingEquiv :
947+
FractionalIdeal R⁰ K ≃+* FractionalIdeal S⁰ L :=
948+
{ toFun I := ⟨Submodule.map (semilinearEquivOfRingEquiv _ _ f).toLinearMap I.val,
949+
IsFractional.mapEquiv K L f I.prop⟩
950+
invFun J := ⟨J.val.map (semilinearEquivOfRingEquiv _ _ f.symm).toLinearMap,
951+
IsFractional.mapEquiv L K f.symm J.prop⟩
952+
map_add' I J := by ext x; simp [← mem_coe]
953+
map_mul' I J := by
954+
simp only [FractionalIdeal.coe_ext_iff, val_eq_coe, coe_mul, coe_mk]
955+
apply le_antisymm <;> simp only [map_le_iff_le_comap, Submodule.mul_le, mem_coe, mem_comap,
956+
semilinearEquivOfRingEquiv_apply, map_mul, mem_map_equiv,
957+
semilinearEquivOfRingEquiv_symm_apply, LinearEquiv.coe_coe]
958+
· exact fun m hm n hn ↦ Submodule.mul_mem_mul (mem_map_of_mem hm) (mem_map_of_mem hn)
959+
· exact fun m hm n hn ↦ Submodule.mul_mem_mul hm hn
960+
left_inv I := by
961+
simp only [RingEquiv.symm_symm, val_eq_coe, ← Submodule.map_comp, LinearEquiv.comp_coe,
962+
coe_ext_iff, coe_mk]
963+
convert Submodule.map_id _
964+
ext; simp [semilinearEquivOfRingEquiv, IsLocalization.map_map]
965+
right_inv I := by
966+
simp only [RingEquiv.symm_symm, val_eq_coe, ← Submodule.map_comp, LinearEquiv.comp_coe,
967+
coe_ext_iff, coe_mk]
968+
convert Submodule.map_id _
969+
ext; simp [semilinearEquivOfRingEquiv, IsLocalization.map_map]}
970+
971+
lemma ringEquivOfRingEquiv_apply (f : R ≃+* S) (I : FractionalIdeal (nonZeroDivisors R) K) :
972+
ringEquivOfRingEquiv K L f I =
973+
⟨Submodule.map (semilinearEquivOfRingEquiv _ _ f).toLinearMap I.val,
974+
IsFractional.mapEquiv K L f I.prop⟩ := rfl
975+
976+
lemma ringEquivOfRingEquiv_apply_val (f : R ≃+* S) (I : FractionalIdeal R⁰ K) :
977+
(ringEquivOfRingEquiv K L f I).val =
978+
I.val.map (semilinearEquivOfRingEquiv _ _ f).toLinearMap := rfl
979+
980+
lemma ringEquivOfRingEquiv_trans {T : Type*} [CommRing T] [IsDomain T] (M : Type*) [CommRing M]
981+
[Algebra T M] [IsFractionRing T M] (f : R ≃+* S) (g : S ≃+* T) :
982+
ringEquivOfRingEquiv K M (f.trans g) =
983+
(ringEquivOfRingEquiv K L f).trans (ringEquivOfRingEquiv L M g) := by
984+
have : RingHomCompTriple f (g : S →+* T) (f.trans g : R →+* T) := ⟨rfl⟩
985+
ext1 I
986+
simp only [ringEquivOfRingEquiv, RingEquiv.coe_ringHom_trans, Function.comp_apply,
987+
semilinearEquivOfRingEquiv_comp K L f M, LinearEquiv.coe_trans,
988+
Submodule.map_comp, RingEquiv.coe_mk, Equiv.coe_fn_mk, RingEquiv.coe_trans]
989+
990+
lemma ringEquivOfRingEquiv_trans_apply {T : Type*} [CommRing T] [IsDomain T] (M : Type*)
991+
[CommRing M] [Algebra T M] [IsFractionRing T M]
992+
(f : R ≃+* S) (g : S ≃+* T) (I : FractionalIdeal R⁰ K) :
993+
ringEquivOfRingEquiv K M (f.trans g) I =
994+
ringEquivOfRingEquiv L M g (ringEquivOfRingEquiv K L f I) := by
995+
simp [ringEquivOfRingEquiv_trans K L M]
996+
997+
lemma ringEquivOfRingEquiv_refl :
998+
ringEquivOfRingEquiv K K (RingEquiv.refl R) = RingEquiv.refl (FractionalIdeal R⁰ K) := by
999+
ext I x
1000+
simp only [ringEquivOfRingEquiv_apply, RingEquiv.coe_ringHom_refl, RingEquiv.symm_refl,
1001+
val_eq_coe, RingEquiv.refl_apply, ← mem_coe]
1002+
simp [semilinearEquivOfRingEquiv]
1003+
1004+
lemma ringEquivOfRingEquiv_spanSingleton (x : K) :
1005+
FractionalIdeal.ringEquivOfRingEquiv K L f (spanSingleton R⁰ x) =
1006+
spanSingleton S⁰ (IsFractionRing.ringEquivOfRingEquiv (L := L) f x) := by
1007+
simp only [ringEquivOfRingEquiv, val_eq_coe, RingEquiv.symm_symm, RingEquiv.coe_mk,
1008+
Equiv.coe_fn_mk, coe_spanSingleton, IsFractionRing.ringEquivOfRingEquiv_apply]
1009+
rw [SetLike.ext_iff]
1010+
intro y
1011+
simp only [← FractionalIdeal.mem_coe, coe_mk, mem_map_equiv, coe_spanSingleton,
1012+
Submodule.mem_span_singleton, (semilinearEquivOfRingEquiv K L f).eq_symm_apply]
1013+
constructor
1014+
· rintro ⟨r, rfl⟩
1015+
use f r
1016+
exact .symm (map_smulₛₗ _ r x)
1017+
· rintro ⟨s, rfl⟩
1018+
use f.symm s
1019+
simp only [Algebra.smul_def, semilinearEquivOfRingEquiv_apply, map_mul, map_eq, RingHom.coe_coe,
1020+
IsFractionRing.ringEquivOfRingEquiv_apply, RingEquiv.apply_symm_apply]
1021+
1022+
lemma ringEquivOfRingEquiv_symm_eq :
1023+
(FractionalIdeal.ringEquivOfRingEquiv K L f).symm =
1024+
FractionalIdeal.ringEquivOfRingEquiv L K f.symm := by
1025+
exact (RingEquiv.coe_nonUnitalRingHom_inj_iff (ringEquivOfRingEquiv K L f).symm
1026+
(ringEquivOfRingEquiv L K f.symm)).mpr rfl
1027+
1028+
end RingEquiv
1029+
9101030
end FractionalIdeal

Mathlib/RingTheory/IntegralClosure/IsIntegral/Basic.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,8 @@ theorem RingEquiv.isIntegral_iff {R S T : Type*} [CommRing R] [Ring S] [CommRing
175175
fun r t s ↦ by simp only [Algebra.smul_def, map_mul, ← h, mul_assoc]; rfl⟩
176176
exact IsIntegral.tower_top ha
177177
· have h' : (algebraMap T S) = (algebraMap R S).comp φ.symm.toRingHom := by
178-
simp only [← h, RingHom.comp_assoc, RingEquiv.toRingHom_eq_coe, RingEquiv.comp_symm,
179-
RingHomCompTriple.comp_eq]
178+
have : RingHomInvPair (φ : R →+* T) φ.symm := RingHomInvPair.of_ringEquiv _
179+
simp only [← h, RingHom.comp_assoc, RingEquiv.toRingHom_eq_coe, RingHomCompTriple.comp_eq]
180180
letI : Algebra T R := φ.symm.toRingHom.toAlgebra
181181
letI : IsScalarTower T R S :=
182182
fun r t s ↦ by simp only [Algebra.smul_def, map_mul, h', mul_assoc]; rfl⟩

Mathlib/RingTheory/LocalProperties/Basic.lean

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,10 +328,11 @@ lemma RingHom.LocalizationAwayPreserves.respectsIso
328328
have : IsLocalization.Away (f 1) T :=
329329
IsLocalization.away_of_isUnit_of_bijective _ (by simp) (Equiv.refl _).bijective
330330
convert hP f 1 R T hf
331+
have : RingHomInvPair (e : R →+* S) e.symm := RingHomInvPair.of_ringEquiv _
331332
have : (IsLocalization.Away.map R T f 1).comp e.symm.toRingHom = f :=
332333
IsLocalization.map_comp ..
333334
conv_lhs => rw [← this, RingHom.comp_assoc]
334-
simp only [RingEquiv.toRingHom_eq_coe, RingEquiv.symm_comp, RingHomCompTriple.comp_eq]
335+
simp only [RingEquiv.toRingHom_eq_coe, RingHomCompTriple.comp_eq]
335336

336337
lemma RingHom.StableUnderCompositionWithLocalizationAway.respectsIso
337338
(hP : StableUnderCompositionWithLocalizationAway P) :

Mathlib/RingTheory/Localization/FractionRing.lean

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ public import Mathlib.Algebra.Field.Equiv
99
public import Mathlib.Algebra.Field.Subfield.Basic
1010
public import Mathlib.Algebra.Order.GroupWithZero.Submonoid
1111
public import Mathlib.Algebra.Order.Ring.Int
12+
public import Mathlib.Algebra.Ring.CompTypeclasses
1213
public import Mathlib.RingTheory.Localization.Basic
1314
public import Mathlib.RingTheory.SimpleRing.Basic
1415

@@ -423,20 +424,68 @@ variable {A K B L : Type*} [CommRing A] [CommRing B] [CommRing K] [CommRing L]
423424
/-- Given rings `A, B` and localization maps to their fraction rings
424425
`f : A →+* K, g : B →+* L`, an isomorphism `h : A ≃+* B` induces an isomorphism of
425426
fraction rings `K ≃+* L`. -/
427+
@[simps!]
426428
noncomputable def ringEquivOfRingEquiv : K ≃+* L :=
427429
IsLocalization.ringEquivOfRingEquiv K L h (MulEquivClass.map_nonZeroDivisors h)
428430

429-
@[simp]
430431
lemma ringEquivOfRingEquiv_algebraMap
431432
(a : A) : ringEquivOfRingEquiv h (algebraMap A K a) = algebraMap B L (h a) := by
432-
simp [ringEquivOfRingEquiv]
433+
simp
433434

434435
@[simp]
435436
lemma ringEquivOfRingEquiv_symm :
436437
(ringEquivOfRingEquiv h : K ≃+* L).symm = ringEquivOfRingEquiv h.symm := rfl
437438

439+
variable (K L) in
440+
theorem ringEquivOfRingEquiv_comp {C : Type*} (M : Type*) [CommRing C]
441+
[CommRing M] [Algebra C M] [IsFractionRing C M] (f : A ≃+* B) (g : B ≃+* C) :
442+
(ringEquivOfRingEquiv (f.trans g)) =
443+
(ringEquivOfRingEquiv (K := K) f).trans (ringEquivOfRingEquiv (K := L) (L := M) g) := by
444+
ext a
445+
simp [IsLocalization.map_map]
446+
438447
end ringEquivOfRingEquiv
439448

449+
section semilinearEquivOfRingEquiv
450+
451+
variable {A B : Type*} (K L : Type*) [CommRing A] [CommRing B] [CommRing K] [CommRing L]
452+
[Algebra A K] [IsFractionRing A K] [Algebra B L] [IsFractionRing B L] (f : A ≃+* B)
453+
454+
local instance : RingHomInvPair (f : A →+* B) f.symm :=
455+
RingHomInvPair.of_ringEquiv f
456+
457+
/-- Given rings `A, B` and localization maps to their fraction rings
458+
`f : A →+* K, g : B →+* L`, an isomorphism `h : A ≃+* B` induces a semilinear equivalence
459+
fraction rings `K ≃ₛₗ[f.toRingHom] L`. -/
460+
noncomputable def semilinearEquivOfRingEquiv : K ≃ₛₗ[(f : A →+* B)] L :=
461+
{ ringEquivOfRingEquiv f with
462+
map_smul' r x := by simp [Algebra.smul_def] }
463+
464+
lemma semilinearEquivOfRingEquiv_apply (x : K) :
465+
(semilinearEquivOfRingEquiv K L f) x = (ringEquivOfRingEquiv f) x := rfl
466+
467+
@[simp]
468+
lemma semilinearEquivOfRingEquiv_algebraMap (a : A) :
469+
semilinearEquivOfRingEquiv K L f (algebraMap A K a) = algebraMap B L (f a) := by
470+
simp [semilinearEquivOfRingEquiv, ringEquivOfRingEquiv]
471+
472+
lemma semilinearEquivOfRingEquiv_symm_apply (x : L) :
473+
(semilinearEquivOfRingEquiv K L f).symm x = (ringEquivOfRingEquiv f).symm x := rfl
474+
475+
lemma semilinearEquivOfRingEquiv_comp {C : Type*} (M : Type*) [CommRing C] [CommRing M]
476+
[Algebra C M] [IsFractionRing C M] (g : B ≃+* C) :
477+
let : RingHomCompTriple f (g : B →+* C) (f.trans g : A →+* C) := ⟨rfl⟩
478+
let : RingHomCompTriple g.symm (f.symm : B →+* A) ((f.trans g).symm : C →+* A) := ⟨rfl⟩
479+
(semilinearEquivOfRingEquiv K M (f.trans g)) =
480+
LinearEquiv.trans (σ₁₃ := (f.trans g)) (σ₃₁ := (f.trans g).symm)
481+
(semilinearEquivOfRingEquiv K L f)
482+
(semilinearEquivOfRingEquiv L M g) := by
483+
ext a
484+
simp [-RingEquiv.coe_ringHom_trans, semilinearEquivOfRingEquiv_apply,
485+
semilinearEquivOfRingEquiv_apply K M, ringEquivOfRingEquiv_comp K L M]
486+
487+
end semilinearEquivOfRingEquiv
488+
440489
section algEquivOfAlgEquiv
441490

442491
variable {R A K B L : Type*} [CommSemiring R] [CommRing A] [CommRing B] [CommRing K] [CommRing L]

0 commit comments

Comments
 (0)