Skip to content

Commit b554b15

Browse files
WhysoserioushahReemMelamed
authored andcommitted
chore(Matrix/GeneralLinearGroup/Projective): sort out namespace and golf the proof (leanprover-community#40666)
1 parent a844008 commit b554b15

5 files changed

Lines changed: 121 additions & 37 deletions

File tree

Mathlib/GroupTheory/QuotientGroup/Defs.lean

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,12 @@ theorem ker_lift (φ : G →* M) (HN : N ≤ φ.ker) :
278278
rw [← congrArg MonoidHom.ker (lift_comp_mk' N φ HN), ← MonoidHom.comap_ker,
279279
Subgroup.map_comap_eq_self_of_surjective (mk'_surjective N)]
280280

281+
@[to_additive]
282+
lemma injective_lift_iff (φ : G →* M) (HN : N ≤ φ.ker) :
283+
Function.Injective (QuotientGroup.lift N φ HN) ↔ N = φ.ker := by
284+
rw [← MonoidHom.ker_eq_bot_iff, QuotientGroup.ker_lift, Subgroup.map_eq_bot_iff]
285+
grind [QuotientGroup.ker_mk']
286+
281287
/-- A surjective group homomorphism `φ : G →* H` with `N = ker(φ)` descends (i.e. `lift`s) to a
282288
group isomorphism `G/N ≃* H`. -/
283289
@[to_additive /-- A surjective `AddGroup` homomorphism `φ : G →+ H` with `N = ker(φ)` descends

Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Basic.lean

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ lemma mem_center_iff_val_mem_range_scalar {g : GL n R} :
4646
refine Matrix.mem_range_scalar_of_commute_transvectionStruct fun t ↦ ?_
4747
simpa [Units.ext_iff] using! Subgroup.mem_center_iff.mp hg (.mk _ _ t.mul_inv t.inv_mul)
4848
· refine fun ⟨a, ha⟩ ↦ Subgroup.mem_center_iff.mpr fun h ↦ ?_
49-
simpa [Units.ext_iff, ← ha] using! (scalar_commute a (mul_comm a ·) h.val).symm
49+
simp [-scalar_apply, Units.ext_iff, ← ha, Matrix.scalar_comm a (Commute.all _)]
5050

5151
@[deprecated (since := "2026-02-08")]
5252
alias mem_center_iff_val_eq_scalar := mem_center_iff_val_mem_range_scalar
@@ -74,8 +74,31 @@ lemma center_eq_range_scalar :
7474
@[deprecated (since := "2026-02-08")]
7575
alias center_eq_range_units := center_eq_range_scalar
7676

77+
lemma map_center_le {S : Type*} [CommRing S] (f : R →+* S) :
78+
Subgroup.center (GL n R) ≤ (Subgroup.center (GL n S)).comap (map f) := fun u hu ↦ by
79+
simp only [GeneralLinearGroup.center_eq_range_scalar, MonoidHom.mem_range,
80+
Subgroup.mem_comap] at hu ⊢
81+
obtain ⟨r, rfl⟩ := hu
82+
exact ⟨(Units.map f) r, GeneralLinearGroup.map_scalar _ _ |>.symm⟩
83+
7784
end Center
7885

7986
end GeneralLinearGroup
8087

88+
lemma SpecialLinearGroup.toGL_mem_center_iff {n R : Type*} [Fintype n] [DecidableEq n] [CommRing R]
89+
(g : SpecialLinearGroup n R) :
90+
toGL g ∈ Subgroup.center (GL n R) ↔ g ∈ Subgroup.center (SpecialLinearGroup n R) := by
91+
if hn : IsEmpty n then simp [Subgroup.center_eq_top] else
92+
replace hn : Nonempty n := by simpa using hn
93+
obtain ⟨i⟩ := hn
94+
simp only [GeneralLinearGroup.center_eq_range_scalar, MonoidHom.mem_range,
95+
mem_center_iff, scalar_apply]
96+
refine ⟨fun ⟨r, hr⟩ ↦ ⟨r, by simpa [Units.ext_iff] using congr(GeneralLinearGroup.det $hr),
97+
by simpa [Units.ext_iff] using hr⟩, fun ⟨r, hr1, hr⟩ ↦ ⟨⟨r, g⁻¹.1 i i, ?_, ?_⟩,
98+
by simp [Units.ext_iff, hr]⟩⟩
99+
· simpa [-mul_inv_cancel, ← hr, ← pow_succ',
100+
Nat.sub_one_add_one Fintype.card_pos.ne.symm] using
101+
Matrix.ext_iff.2 (Subtype.ext_iff.1 (mul_inv_cancel g)) i i
102+
· simpa [-inv_mul_cancel, ← hr] using Matrix.ext_iff.2 (Subtype.ext_iff.1 (inv_mul_cancel g)) i i
103+
81104
end Matrix

Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Defs.lean

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,23 +52,25 @@ variable {n : Type u} [DecidableEq n] [Fintype n] {R : Type v}
5252

5353
variable (n) in
5454
/-- Scalar matrix as an element of `GL n R`. -/
55-
@[simps!]
5655
def scalar [Semiring R] : Rˣ →* GL n R :=
5756
Units.map (Matrix.scalar n).toMonoidHom
5857

59-
#adaptation_note /-- As of nightly-2026-04-29, the simpNF linter is failing here.
60-
Assistance investigating this would be appreciated. -/
61-
attribute [nolint simpNF] _root_.Matrix.GeneralLinearGroup.val_inv_scalar_apply
62-
6358
section CoeFnInstance
6459

6560
instance instCoeFun [Semiring R] : CoeFun (GL n R) fun _ => n → n → R where
6661
coe A := (A : Matrix n n R)
6762

63+
@[simp]
64+
lemma coe_scalar [Semiring R] (u : Rˣ) : ↑(scalar n u) = Matrix.scalar n u.1 := rfl
65+
6866
end CoeFnInstance
6967

7068
variable [CommRing R]
7169

70+
lemma scalar_commute (u : Rˣ) (A : GL n R) : scalar n u * A = A * scalar n u := by
71+
ext : 1
72+
rw [Units.val_mul, Units.val_mul, coe_scalar, Matrix.scalar_comm _ (Commute.all _)]
73+
7274
/-- The determinant of a unit matrix is itself a unit. -/
7375
@[simps]
7476
def det : GL n R →* Rˣ where
@@ -220,6 +222,11 @@ lemma coe_map_inv_mul_map (g : GL n R) : g.val⁻¹.map f * g.val.map f = 1 := b
220222
rw [← Matrix.map_mul]
221223
simp only [isUnits_det_units, nonsing_inv_mul, map_zero, map_one, Matrix.map_one]
222224

225+
lemma map_scalar (u : Rˣ) : map f (scalar n u) = scalar n (Units.map f u) := by
226+
ext
227+
simp [Matrix.diagonal_apply]
228+
split <;> simp
229+
223230
section kronecker
224231
variable {R m : Type*} [CommSemiring R] [Fintype m] [DecidableEq m]
225232

Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Projective.lean

Lines changed: 67 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/-
22
Copyright (c) 2026 Yury G. Kudryashov. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
4-
Authors: Yury G. Kudryashov
4+
Authors: Yury G. Kudryashov, Edison Xie
55
-/
66
module
77

@@ -17,11 +17,22 @@ In this file we define `Matrix.ProjGenLinGroup n R` as the quotient of `GL n R`
1717
We introduce notation `PGL(n, R)` for this group,
1818
which works if `n` is either a finite type or a natural number.
1919
If `n` is a number, then `PGL(n, R)` is interpreted as `PGL(Fin n, R)`.
20+
21+
## Main definitions
22+
23+
* `Matrix.SpecialLinearGroup.toPGL` is the natural map from `SL(n, R)` to `PGL(n, R)`.
24+
25+
* `Matrix.ProjectiveSpecialLinearGroup.toPGL` is the natural
26+
inclusion from `PSL(n, R)` to `PGL(n, R)`.
27+
28+
* `Matrix.ProjectiveSpecialLinearGroup.isoPSLOfAlgClosed` is an isomorphism between
29+
`PGL(n, F)` and `PSL(n, F)` in the case of an algebraically closed field.
30+
2031
-/
2132

2233
open scoped MatrixGroups
2334

24-
public section
35+
@[expose] public section
2536

2637
namespace Matrix
2738

@@ -61,6 +72,9 @@ theorem ker_mk : mk.ker = Subgroup.center (GL n R) := QuotientGroup.ker_mk' _
6172
theorem mk_eq_one {g : GL n R} : mk g = 1 ↔ g ∈ Subgroup.center (GL n R) := by
6273
rw [← MonoidHom.mem_ker, ker_mk]
6374

75+
@[simp]
76+
lemma mk_one : mk (1 : GL n R) = 1 := rfl
77+
6478
@[simp]
6579
theorem mk_scalar (u : Rˣ) : mk (.scalar n u) = 1 := by
6680
rw [← MonoidHom.mem_ker, ker_mk, GeneralLinearGroup.center_eq_range_scalar]
@@ -71,41 +85,43 @@ theorem induction_on {motive : PGL(n, R) → Prop} (g : PGL(n, R))
7185
(mk : ∀ g : GL n R, motive (ProjGenLinGroup.mk g)) : motive g :=
7286
Quotient.inductionOn g mk
7387

88+
end ProjGenLinGroup
89+
7490
section isoPSL
7591

92+
variable {n R : Type*} [Fintype n] [DecidableEq n] [CommRing R]
93+
94+
open Matrix.ProjGenLinGroup
95+
96+
namespace SpecialLinearGroup
97+
98+
/-- The natural map from `SL(n, R)` to `PGL(n, R)` by composing the maps from `SL` to `GL` and the
99+
quotient map from `GL` to `PGL`. -/
100+
abbrev toPGL : SpecialLinearGroup n R →* PGL(n, R) := mk.comp toGL
101+
102+
lemma toPGL_ker : toPGL.ker = Subgroup.center (SpecialLinearGroup n R) := by
103+
ext; simp [toGL_mem_center_iff]
104+
105+
end SpecialLinearGroup
106+
107+
namespace ProjectiveSpecialLinearGroup
108+
76109
open Matrix.SpecialLinearGroup
77110

78111
/-- The natural inclusion map from `PSL(n, R)` to `PGL(n, R)` induced by the inclusion
79112
map from `SL(n, R)` to `GL(n, R)`. -/
80-
@[expose]
81-
def _root_.Matrix.ProjectiveSpecialLinearGroup.toPGL :
82-
ProjectiveSpecialLinearGroup n R →* PGL(n, R) :=
83-
QuotientGroup.lift _ (mk.comp toGL) fun x hx ↦ by
84-
simp only [mem_center_iff, scalar_apply, MonoidHom.mem_ker, MonoidHom.coe_comp,
85-
Function.comp_apply, mk_eq_one, GeneralLinearGroup.mem_center_iff_val_mem_range_scalar,
86-
coe_GL_coe_matrix, Set.mem_range] at hx ⊢
87-
exact ⟨hx.choose, hx.choose_spec.2
113+
def toPGL : ProjectiveSpecialLinearGroup n R →* PGL(n, R) :=
114+
QuotientGroup.lift _ SpecialLinearGroup.toPGL <| le_of_eq toPGL_ker.symm
88115

89116
@[simp]
90-
lemma _root_.Matrix.ProjectiveSpecialLinearGroup.toPGL_mk (g : SpecialLinearGroup n R) :
117+
lemma toPGL_mk (g : SpecialLinearGroup n R) :
91118
ProjectiveSpecialLinearGroup.toPGL g = mk (toGL g) := rfl
92119

93-
lemma _root_.Matrix.ProjectiveSpecialLinearGroup.toPGL_injective :
94-
Function.Injective (ProjectiveSpecialLinearGroup.toPGL (n := n) (R := R)) := fun x y h ↦ by
95-
induction x using QuotientGroup.induction_on with | H x =>
96-
induction y using QuotientGroup.induction_on with | H y =>
97-
simp only [ProjectiveSpecialLinearGroup.toPGL_mk, mk_eq_mk_iff] at h
98-
rw [← QuotientGroup.mk'_apply, ← QuotientGroup.mk'_apply]
99-
simp only [QuotientGroup.mk'_eq_mk', mem_center_iff]
100-
obtain ⟨u, hu'⟩ := h
101-
have hu : u.1 ^ Fintype.card n = 1 := by
102-
simpa [Units.ext_iff] using congr(Matrix.GeneralLinearGroup.det $hu')
103-
set z : SpecialLinearGroup n R := ⟨scalar n u.1, by simpa using hu⟩ with hz_eq
104-
have hz : (GeneralLinearGroup.scalar n) u = toGL z := by ext; simp [hz_eq]
105-
refine ⟨z, ⟨u.1, hu, by simp [hz_eq]⟩, ?_⟩
106-
rwa [hz, ← map_mul, toGL_inj] at hu'
107-
108-
lemma _root_.Matrix.ProjectiveSpecialLinearGroup.toPGL_surj_of_roots
120+
lemma toPGL_injective :
121+
Function.Injective (ProjectiveSpecialLinearGroup.toPGL (n := n) (R := R)) :=
122+
QuotientGroup.injective_lift_iff _ _ _ |>.2 toPGL_ker.symm
123+
124+
lemma toPGL_surj_of_roots
109125
(hR : ∀ r : Rˣ, ∃ k : Rˣ, k ^ Fintype.card n = r) :
110126
Function.Surjective (ProjectiveSpecialLinearGroup.toPGL (n := n) (R := R)) := fun g ↦ by
111127
induction g using Matrix.ProjGenLinGroup.induction_on with | mk g =>
@@ -117,10 +133,10 @@ lemma _root_.Matrix.ProjectiveSpecialLinearGroup.toPGL_surj_of_roots
117133
use QuotientGroup.mk ⟨r.1 • g.1, hr⟩
118134
simp only [ProjectiveSpecialLinearGroup.toPGL_mk, mk_eq_mk_iff]
119135
refine ⟨r⁻¹, Units.ext ?_⟩
120-
simp only [Units.val_mul, coe_GL_coe_matrix,GeneralLinearGroup.val_scalar_apply]
136+
simp only [Units.val_mul, coe_GL_coe_matrix, GeneralLinearGroup.coe_scalar]
121137
simp [← Matrix.mul_smul, ← Matrix.diagonal_smul, Pi.smul_def, smul_eq_mul]
122138

123-
lemma _root_.Matrix.ProjectiveSpecialLinearGroup.toPGL_surj_iff [Nonempty n] :
139+
lemma toPGL_surj_iff [Nonempty n] :
124140
Function.Surjective (ProjectiveSpecialLinearGroup.toPGL (n := n) (R := R)) ↔
125141
∀ r : Rˣ, ∃ k : Rˣ, k ^ Fintype.card n = r := by
126142
refine ⟨fun h r ↦ ?_, ProjectiveSpecialLinearGroup.toPGL_surj_of_roots⟩
@@ -156,9 +172,13 @@ noncomputable def isoPSLOfAlgClosed {F : Type*} [Field F] [IsAlgClosed F] :
156172
MulEquiv.symm (MulEquiv.ofBijective Matrix.ProjectiveSpecialLinearGroup.toPGL
157173
⟨Matrix.ProjectiveSpecialLinearGroup.toPGL_injective, Function.surjective_to_subsingleton _⟩)
158174

175+
end ProjectiveSpecialLinearGroup
176+
159177
end isoPSL
160178

161-
variable {M : Type*} [Monoid M]
179+
namespace ProjGenLinGroup
180+
181+
variable {n R : Type*} [Fintype n] [DecidableEq n] [CommRing R] {M : Type*} [Monoid M]
162182

163183
/-- Lift a monoid homomorphism `f : GL n R →* M` that vanishes on all scalar matrices
164184
to a homomorphism from `PGL(n, R)`. -/
@@ -191,6 +211,23 @@ theorem mk_smul {α : Type*} [MulAction (GL n R) α] (h) (g : GL n R) (a : α) :
191211
mk g • a = g • a := by
192212
rfl
193213

214+
/-- The monoid hom between `PGL(n, R)` and `PGL(n, S)` induced by a
215+
ring homomorphism `f : R →+* S`. -/
216+
def map {S : Type*} [CommRing S] (f : R →+* S) : PGL(n, R) →* PGL(n, S) :=
217+
QuotientGroup.map _ _ (GeneralLinearGroup.map (n := n) f) <| GeneralLinearGroup.map_center_le f
218+
219+
@[simp]
220+
lemma map_id : map (RingHom.id R) = MonoidHom.id (PGL(n, R)) := QuotientGroup.map_id _
221+
222+
@[simp]
223+
lemma map_mk {S : Type*} [CommRing S] (f : R →+* S) (g : GL n R) :
224+
map f (mk g) = mk (GeneralLinearGroup.map f g) := rfl
225+
226+
lemma map_comp {S T : Type*} [CommRing S] [CommRing T] (f : R →+* S) (g : S →+* T) :
227+
map (n := n) (g.comp f) = (map g).comp (map f) := by
228+
ext g
229+
induction g using Matrix.ProjGenLinGroup.induction_on with | mk g => simp
230+
194231
variable [Fact (Even (Fintype.card n))] [LinearOrder R] [IsStrictOrderedRing R]
195232

196233
/-- In case of an even dimension, the sign of the determinant of `g : PGL(n, R)` is well-defined. -/

Mathlib/LinearAlgebra/Projectivization/Action.lean

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public import Mathlib.LinearAlgebra.Projectivization.Basic
1111
public import Mathlib.LinearAlgebra.SpecialLinearGroup
1212
public import Mathlib.LinearAlgebra.Transvection.Basic
1313
public import Mathlib.LinearAlgebra.Matrix.IsDiag
14-
public import Mathlib.LinearAlgebra.Matrix.ProjectiveSpecialLinearGroup
14+
public import Mathlib.LinearAlgebra.Matrix.GeneralLinearGroup.Projective
1515
public import Mathlib.LinearAlgebra.Center
1616

1717
/-!
@@ -240,6 +240,17 @@ instance : IsPreprimitive (Matrix.ProjectiveSpecialLinearGroup ι K) (ℙ K (ι
240240
{toFun := id, map_smul' := by intros; simp; rfl} (prePrimitive_SL (ι := ι) (K := K))
241241
Function.surjective_id
242242

243+
open MatrixGroups Matrix.ProjGenLinGroup
244+
245+
instance : MulAction PGL(ι, K) (ℙ K (ι → K)) :=
246+
mulActionOfGL fun u ↦ ind fun v hv ↦ by
247+
simp only [smul_mk, mk_eq_mk_iff]
248+
exact ⟨u, by simp [Units.smul_def]⟩
249+
250+
@[simp]
251+
lemma PGL.mk_smul_mk (g : GL ι K) {v : ι → K} (hv : v ≠ 0) :
252+
(.mk g : PGL(ι, K)) • mk K v hv = mk K (g • v) (smul_ne_zero_iff_ne g|>.2 hv) := rfl
253+
243254
end Field
244255

245256
end Projectivization

0 commit comments

Comments
 (0)