Skip to content

Commit 9439afe

Browse files
committed
feat: the Geck Construction yields trace-free matrices (#27831)
This will be used with `LieAlgebra.hasTrivialRadical_of_isIrreducible_of_isFaithful` (and a proof of irreducibility) to prove semisimplicity.
1 parent 6c7a256 commit 9439afe

File tree

6 files changed

+208
-13
lines changed

6 files changed

+208
-13
lines changed

Mathlib/Algebra/Lie/Semisimple/Lemmas.lean

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,16 @@ This file is a home for lemmas about semisimple and reductive Lie algebras.
1919
2020
## TODO
2121
22-
* It appears that the lemmas in this file may hold for any principal ideal domain (of
23-
characteristic zero) instead of a field. The plan would be to define the nilradical of a Lie
24-
algebra (currently missing) and use it with
25-
`LieModule.exists_nontrivial_weightSpace_of_isNilpotent` instead of using the solvable radical
26-
with `LieModule.exists_nontrivial_weightSpace_of_isSolvable`, as below. The conclusion of
27-
`LieAlgebra.hasCentralRadical_and_of_isIrreducible_of_isFaithful` would then make a statement
28-
that the nilradical vanishes and one would prove elsewhere that vanishing nilradical is
29-
equivalent to `HasCentralRadical`.
22+
* Introduce a `Prop`-valued typeclass `LieModule.IsTracefree` stating
23+
`(toEnd R L M).range ≤ LieAlgebra.derivedSeries R (Module.End R M) 1`, prove
24+
`f ∈ LieAlgebra.derivedSeries k (Module.End k V) 1 ↔ LinearMap.trace k _ f = 0`, and restate
25+
`LieAlgebra.hasTrivialRadical_of_isIrreducible_of_isFaithful` using `LieModule.IsTracefree`.
3026
3127
-/
3228

3329
namespace LieAlgebra
3430

35-
open LieModule LieSubmodule Module
31+
open LieModule LieSubmodule Module Set
3632

3733
variable (k L M : Type*) [Field k] [CharZero k]
3834
[LieRing L] [LieAlgebra k L] [Module.Finite k L]
@@ -76,4 +72,18 @@ theorem hasTrivialRadical_of_isIrreducible_of_isFaithful
7672
suffices t = 0 by simp [← toEnd_eq_zero_iff (R := k) (L := L) (M := M), ← ht, this]
7773
simpa [this, ← ht] using h
7874

75+
variable {k L M}
76+
variable {R : Type*} [CommRing R] [IsReduced R] [LieAlgebra R L] [Module R M] [LieModule R L M]
77+
78+
open LinearMap in
79+
lemma trace_toEnd_eq_zero {s : Set L} (hs : ∀ x ∈ s, _root_.IsNilpotent (toEnd R _ M x))
80+
{x : L} (hx : x ∈ LieSubalgebra.lieSpan R L s) :
81+
trace R _ (toEnd R _ M x) = 0 := by
82+
induction hx using LieSubalgebra.lieSpan_induction with
83+
| mem u hu => simpa using isNilpotent_trace_of_isNilpotent (hs u hu)
84+
| zero => simp
85+
| add u v _ _ hu hv => simp [hu, hv]
86+
| smul t u _ hu => simp [hu]
87+
| lie u v _ _ _ _ => simp
88+
7989
end LieAlgebra

Mathlib/Data/Matrix/Mul.lean

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,20 @@ lemma vecMul_injective_of_isUnit [Fintype m] [DecidableEq m] {A : Matrix m m R}
934934
intro x y hxy
935935
simpa [hBl] using congrArg B.vecMul hxy
936936

937+
lemma pow_row_eq_zero_of_le [Fintype n] [DecidableEq n] {M : Matrix n n R} {k l : ℕ} {i : n}
938+
(h : (M ^ k).row i = 0) (h' : k ≤ l) :
939+
(M ^ l).row i = 0 := by
940+
replace h' : l = k + (l - k) := by omega
941+
rw [← single_one_vecMul] at h ⊢
942+
rw [h', pow_add, ← vecMul_vecMul, h, zero_vecMul]
943+
944+
lemma pow_col_eq_zero_of_le [Fintype n] [DecidableEq n] {M : Matrix n n R} {k l : ℕ} {i : n}
945+
(h : (M ^ k).col i = 0) (h' : k ≤ l) :
946+
(M ^ l).col i = 0 := by
947+
replace h' : l = (l - k) + k := by omega
948+
rw [← mulVec_single_one] at h ⊢
949+
rw [h', pow_add, ← mulVec_mulVec, h, mulVec_zero]
950+
937951
end Semiring
938952

939953
section CommSemiring

Mathlib/LinearAlgebra/RootSystem/GeckConstruction/Basic.lean

Lines changed: 116 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@ Copyright (c) 2025 Oliver Nash. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Oliver Nash
55
-/
6+
import Mathlib.Algebra.Lie.Matrix
67
import Mathlib.Algebra.Lie.OfAssociative
8+
import Mathlib.Algebra.Lie.Semisimple.Lemmas
79
import Mathlib.Algebra.Lie.Sl2
810
import Mathlib.LinearAlgebra.RootSystem.CartanMatrix
911
import Mathlib.LinearAlgebra.RootSystem.GeckConstruction.Lemmas
12+
import Mathlib.RingTheory.Finiteness.Nilpotent
1013

1114
/-!
1215
# Geck's construction of a Lie algebra associated to a root system
@@ -64,7 +67,7 @@ namespace RootPairing.GeckConstruction
6467

6568
variable {ι R M N : Type*} [Finite ι] [CommRing R] [IsDomain R] [CharZero R]
6669
[AddCommGroup M] [Module R M] [AddCommGroup N] [Module R N]
67-
{P : RootSystem ι R M N} [P.IsCrystallographic] {b : P.Base}
70+
{P : RootPairing ι R M N} [P.IsCrystallographic] {b : P.Base}
6871

6972
/-- Part of an `sl₂` triple used in Geck's construction of a Lie algebra from a root system. -/
7073
def e (i : b.support) :
@@ -117,7 +120,7 @@ variable {b}
117120
attribute [local simp] Ring.lie_def Matrix.mul_apply Matrix.one_apply Matrix.diagonal_apply
118121

119122
omit [Finite ι] [IsDomain R] [CharZero R] [P.IsCrystallographic] in
120-
lemma ω_mul_ω [DecidableEq ι] [Fintype ι] :
123+
@[simp] lemma ω_mul_ω [DecidableEq ι] [Fintype ι] :
121124
ω b * ω b = 1 := by
122125
ext (k | k) (l | l) <;>
123126
simp [ω, -indexNeg_neg]
@@ -478,4 +481,115 @@ lemma lie_e_f_ne [P.IsNotG2] :
478481

479482
end lie_e_f_ne
480483

484+
variable [DecidableEq ι]
485+
486+
/-- An auxiliary lemma en route to `RootPairing.GeckConstruction.isNilpotent_e`. -/
487+
private lemma isNilpotent_e_aux {j : ι} (n : ℕ) (h : letI _i := P.indexNeg; j ≠ -i) :
488+
(e i ^ n).col (.inr j) = 0
489+
∃ (k : ι) (x : ℕ), P.root k = P.root j + n • P.root i ∧
490+
(e i ^ n).col (.inr j) = x • Pi.single (.inr k) 1 := by
491+
have _i : NoZeroSMulDivisors ℤ M := by have := P.reflexive_left; exact .int_of_charZero R M
492+
letI _i := P.indexNeg
493+
have aux (n : ℕ) : (e i ^ (n + 1)).col (.inr j) = (e i).mulVec ((e i ^ n).col (.inr j)) := by
494+
rw [pow_succ', ← Matrix.mulVec_single_one, ← Matrix.mulVec_mulVec]; simp
495+
induction n with
496+
| zero => exact Or.inr ⟨j, 1, by simp, by ext; simp [Pi.single_apply]⟩
497+
| succ n ih =>
498+
rcases ih with hn | ⟨k, x, hk₁, hk₂⟩
499+
· left; simp [aux, hn]
500+
rw [aux, hk₂, Matrix.mulVec_smul]
501+
have hki : k ≠ -i := by
502+
rintro rfl
503+
replace hk₁ : P.root (-j) = (n + 1) • P.root i := by
504+
simp only [indexNeg_neg, root_reflectionPerm, reflection_apply_self, neg_eq_iff_add_eq_zero,
505+
add_smul, one_smul] at hk₁ ⊢
506+
rw [← hk₁]
507+
module
508+
rcases n.eq_zero_or_pos with rfl | hn
509+
· apply h
510+
rw [zero_add, one_smul, EmbeddingLike.apply_eq_iff_eq] at hk₁
511+
simp [← hk₁, -indexNeg_neg]
512+
· have _i : (n + 1).AtLeastTwo := ⟨by omega⟩
513+
exact P.nsmul_notMem_range_root (n := n + 1) (i := i) ⟨-j, hk₁⟩
514+
by_cases hij : P.root j + (n + 1) • P.root i ∈ range P.root
515+
· obtain ⟨l, hl⟩ := hij
516+
right
517+
refine ⟨l, x * (P.chainBotCoeff i k + 1), hl, ?_⟩
518+
ext (m | m)
519+
· simp [e, -indexNeg_neg, hki]
520+
· rcases eq_or_ne m l with rfl | hml
521+
· replace hl : P.root m = P.root i + P.root k := by rw [hl, hk₁]; module
522+
simp [e, -indexNeg_neg, hl, mul_add]
523+
· replace hl : P.root m ≠ P.root i + P.root k :=
524+
fun contra ↦ hml (P.root.injective <| by rw [hl, contra, hk₁]; module)
525+
simp [e, -indexNeg_neg, hml, hl]
526+
· left
527+
ext (l | l)
528+
· simp [e, -indexNeg_neg, hki]
529+
· replace hij : P.root l ≠ P.root i + P.root k :=
530+
fun contra ↦ hij ⟨l, by rw [contra, hk₁]; module⟩
531+
simp [e, -indexNeg_neg, hij]
532+
533+
lemma isNilpotent_e :
534+
IsNilpotent (e i) := by
535+
classical
536+
have _i : NoZeroSMulDivisors ℤ M := by have := P.reflexive_left; exact .int_of_charZero R M
537+
letI _i := P.indexNeg
538+
rw [Matrix.isNilpotent_iff_forall_col]
539+
have case_inl (j : b.support) : (e i ^ 2).col (Sum.inl j) = 0 := by
540+
ext (k | k)
541+
· simp [e, sq, ne_neg P i, -indexNeg_neg]
542+
· have aux : ∀ x : ι, x ∈ Finset.univ → ¬ (x = i ∧ P.root k = P.root i + P.root x) := by
543+
suffices P.root k ≠ (2 : ℕ) • P.root i by simpa [two_smul]
544+
exact fun contra ↦ P.nsmul_notMem_range_root (n := 2) (i := i) ⟨k, contra⟩
545+
simp [e, sq, -indexNeg_neg, ← ite_and, Finset.sum_ite_of_false aux]
546+
rintro (j | j)
547+
· exact ⟨2, case_inl j⟩
548+
· by_cases hij : j = -i
549+
· use 2 + 1
550+
replace hij : (e i).col (Sum.inr j) = Pi.single (Sum.inl i) 1 := by
551+
ext (k | k)
552+
· simp [e, -indexNeg_neg, Pi.single_apply, hij]
553+
· have hk : P.root k ≠ P.root i + P.root j := by simp [hij, P.ne_zero k]
554+
simp [e, -indexNeg_neg, hk]
555+
rw [pow_succ, ← Matrix.mulVec_single_one, ← Matrix.mulVec_mulVec]
556+
simp [hij, case_inl i]
557+
use P.chainTopCoeff i j + 1
558+
rcases isNilpotent_e_aux i (P.chainTopCoeff i j + 1) hij with this | ⟨k, x, hk₁, -⟩
559+
· assumption
560+
exfalso
561+
replace hk₁ : P.root j + (P.chainTopCoeff i j + 1) • P.root i ∈ range P.root := ⟨k, hk₁⟩
562+
have hij' : LinearIndependent R ![P.root i, P.root j] := by
563+
apply IsReduced.linearIndependent P ?_ ?_
564+
· rintro rfl
565+
apply P.nsmul_notMem_range_root (n := P.chainTopCoeff i i + 2) (i := i)
566+
convert hk₁ using 1
567+
module
568+
· contrapose! hij
569+
rw [root_eq_neg_iff] at hij
570+
rw [hij, ← indexNeg_neg, neg_neg]
571+
rw [root_add_nsmul_mem_range_iff_le_chainTopCoeff hij'] at hk₁
572+
omega
573+
574+
lemma isNilpotent_f :
575+
IsNilpotent (f i) := by
576+
obtain ⟨n, hn⟩ := isNilpotent_e i
577+
suffices (ω b) * (f i ^ n) = 0 from ⟨n, by simpa [← mul_assoc] using congr_arg (ω b * ·) this⟩
578+
suffices (ω b) * (f i ^ n) = (e i ^ n) * (ω b) by simp [this, hn]
579+
clear hn
580+
induction n with
581+
| zero => simp
582+
| succ n ih => rw [pow_succ, pow_succ, ← mul_assoc, ih, mul_assoc, ω_mul_f, ← mul_assoc]
583+
584+
open LinearMap LieModule in
585+
/-- This is the main result of lemma 4.1 from [Geck](Geck2017). -/
586+
lemma trace_toEnd_eq_zero (x : lieAlgebra b) :
587+
trace R _ (toEnd R _ (b.support ⊕ ι → R) x) = 0 := by
588+
obtain ⟨x, hx⟩ := x
589+
suffices trace R _ x.toLin' = 0 by simpa
590+
refine LieAlgebra.trace_toEnd_eq_zero ?_ hx
591+
rintro - (⟨i, rfl⟩ | ⟨i, rfl⟩)
592+
· simpa using isNilpotent_e i
593+
· simpa using isNilpotent_f i
594+
481595
end RootPairing.GeckConstruction

Mathlib/Order/ConditionallyCompleteLattice/Finset.lean

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,22 @@ end ListMultiset
175175

176176
end ConditionallyCompleteLinearOrder
177177

178+
namespace Finite
179+
180+
variable [Finite ι] [ConditionallyCompleteLattice α] (f : ι → α)
181+
182+
lemma le_ciSup (i : ι) : f i ≤ ⨆ j, f j := by
183+
suffices BddAbove (range f) from _root_.le_ciSup this i
184+
let : Fintype ι := Fintype.ofFinite ι
185+
use Finset.sup' Finset.univ ⟨i, Finset.mem_univ i⟩ f
186+
simp only [mem_upperBounds, mem_range, forall_exists_index, forall_apply_eq_imp_iff]
187+
exact fun j ↦ Finset.le_sup' f <| Finset.mem_univ j
188+
189+
lemma ciInf_le (i : ι) : ⨅ j, f j ≤ f i :=
190+
le_ciSup (α := αᵒᵈ) f i
191+
192+
end Finite
193+
178194
/-!
179195
### Relation between `sSup` / `sInf` and `Finset.sup'` / `Finset.inf'`
180196

Mathlib/RingTheory/Finiteness/Nilpotent.lean

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ Copyright (c) 2020 Johan Commelin. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Johan Commelin
55
-/
6-
import Mathlib.RingTheory.Finiteness.Defs
7-
import Mathlib.RingTheory.Nilpotent.Defs
6+
import Mathlib.RingTheory.Finiteness.Basic
7+
import Mathlib.RingTheory.Nilpotent.Lemmas
88

99
/-!
1010
# Nilpotent maps on finite modules
@@ -26,3 +26,36 @@ theorem Module.End.isNilpotent_iff_of_finite [Module.Finite R M] {f : End R M} :
2626
| zero => simp
2727
| add => simp_all
2828
| smul => simp_all
29+
30+
namespace Matrix
31+
32+
open scoped Matrix
33+
34+
variable {ι : Type*} [DecidableEq ι] [Fintype ι] {A : Matrix ι ι R}
35+
36+
@[simp]
37+
theorem isNilpotent_transpose_iff :
38+
IsNilpotent Aᵀ ↔ IsNilpotent A := by
39+
simp_rw [IsNilpotent, ← transpose_pow, transpose_eq_zero]
40+
41+
theorem isNilpotent_iff :
42+
IsNilpotent A ↔ ∀ v, ∃ n : ℕ, A ^ n *ᵥ v = 0 := by
43+
simp_rw [← isNilpotent_toLin'_iff, Module.End.isNilpotent_iff_of_finite, ← toLin'_pow,
44+
toLin'_apply]
45+
46+
theorem isNilpotent_iff_forall_row :
47+
IsNilpotent A ↔ ∀ i, ∃ n : ℕ, (A ^ n).row i = 0 := by
48+
rw [← isNilpotent_transpose_iff, isNilpotent_iff]
49+
refine ⟨fun h i ↦ ?_, fun h v ↦ ?_⟩
50+
· obtain ⟨n, hn⟩ := h (Pi.single i 1)
51+
exact ⟨n, by simpa [← transpose_pow] using hn⟩
52+
· choose n hn using h
53+
suffices ∀ i, (A ^ ⨆ j, n j) i = 0 from ⟨⨆ j, n j, by simp [mulVec_eq_sum, this]⟩
54+
exact fun i ↦ pow_row_eq_zero_of_le (hn i) (Finite.le_ciSup n i)
55+
56+
theorem isNilpotent_iff_forall_col :
57+
IsNilpotent A ↔ ∀ i, ∃ n : ℕ, (A ^ n).col i = 0 := by
58+
rw [← isNilpotent_transpose_iff, isNilpotent_iff_forall_row]
59+
simp_rw [← transpose_pow, row_transpose]
60+
61+
end Matrix

Mathlib/RingTheory/Nilpotent/Lemmas.lean

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,14 @@ lemma isNilpotent_toMatrix_iff (b : Basis ι R M) (f : M →ₗ[R] M) :
9393

9494
end LinearMap
9595

96+
@[simp]
97+
lemma Matrix.isNilpotent_toLin'_iff {ι : Type*} [DecidableEq ι] [Fintype ι] [CommSemiring R]
98+
(A : Matrix ι ι R) :
99+
IsNilpotent A.toLin' ↔ IsNilpotent A := by
100+
have : A.toLin'.toMatrix (Pi.basisFun R ι) (Pi.basisFun R ι) = A := LinearMap.toMatrix'_toLin' A
101+
conv_rhs => rw [← this]
102+
rw [LinearMap.isNilpotent_toMatrix_iff]
103+
96104
namespace Module.End
97105

98106
section

0 commit comments

Comments
 (0)