1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
|
(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
(* Distributed under the terms of CeCILL-B. *)
Require Import mathcomp.ssreflect.ssreflect.
From mathcomp
Require Import ssrbool ssrfun eqtype fintype finfun finset ssralg.
From mathcomp
Require Import bigop seq tuple choice ssrnat prime ssralg fingroup pgroup.
From mathcomp
Require Import zmodp matrix vector falgebra galgebra.
(*****************************************************************************)
(* * Module over an algebra *)
(* amoduleType A == type for finite dimension module structure. *)
(* *)
(* v :* x == right product of the module *)
(* (M :* A)%VS == the smallest vector space that contains *)
(* {v :* x | v \in M & x \in A} *)
(* (modv M A) == M is a module for A *)
(* (modf f M A) == f is a module homomorphism on M for A *)
(*****************************************************************************)
(*****************************************************************************)
Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.
Local Open Scope ring_scope.
Delimit Scope amodule_scope with aMS.
Import GRing.Theory.
Module AModuleType.
Section ClassDef.
Variable R : ringType.
Variable V: vectType R.
Variable A: FalgType R.
Structure mixin_of (V : vectType R) : Type := Mixin {
action: A -> 'End(V);
action_morph: forall x a b, action (a * b) x = action b (action a x);
action_linear: forall x , linear (action^~ x);
action1: forall x , action 1 x = x
}.
Structure class_of (V : Type) : Type := Class {
base : Vector.class_of R V;
mixin : mixin_of (Vector.Pack _ base V)
}.
Local Coercion base : class_of >-> Vector.class_of.
Implicit Type phA : phant A.
Structure type phA : Type := Pack {sort : Type; _ : class_of sort; _ : Type}.
Local Coercion sort : type >-> Sortclass.
Definition class phA (cT : type phA):=
let: Pack _ c _ := cT return class_of cT in c.
Definition clone phA T cT c of phant_id (@class phA cT) c := @Pack phA T c T.
Definition pack phA V V0 (m0 : mixin_of (@Vector.Pack R _ V V0 V)) :=
fun bT b & phant_id (@Vector.class _ (Phant R) bT) b =>
fun m & phant_id m0 m => Pack phA (@Class V b m) V.
Definition eqType phA cT := Equality.Pack (@class phA cT) cT.
Definition choiceType phA cT := choice.Choice.Pack (@class phA cT) cT.
Definition zmodType phA cT := GRing.Zmodule.Pack (@class phA cT) cT.
Definition lmodType phA cT := GRing.Lmodule.Pack (Phant R) (@class phA cT) cT.
Definition vectType phA cT := Vector.Pack (Phant R) (@class phA cT) cT.
End ClassDef.
Module Exports.
Coercion base : class_of >-> Vector.class_of.
Coercion mixin : class_of >-> mixin_of.
Coercion sort : type >-> Sortclass.
Coercion eqType : type >-> Equality.type.
Canonical Structure eqType.
Coercion choiceType : type >-> Choice.type.
Canonical Structure choiceType.
Coercion zmodType : type >-> GRing.Zmodule.type.
Canonical Structure zmodType.
Coercion lmodType : type>-> GRing.Lmodule.type.
Canonical Structure lmodType.
Coercion vectType : type >-> Vector.type.
Canonical Structure vectType.
Notation amoduleType A := (@type _ _ (Phant A)).
Notation AModuleType A m := (@pack _ _ (Phant A) _ _ m _ _ id _ id).
Notation AModuleMixin := Mixin.
Bind Scope ring_scope with sort.
End Exports.
End AModuleType.
Import AModuleType.Exports.
Section AModuleDef.
Variables (F : fieldType) (A: FalgType F) (M: amoduleType A).
Definition rmorph (a: A) := AModuleType.action (AModuleType.class M) a.
Definition rmul (a: M) (b: A) : M := rmorph b a.
Notation "a :* b" := (rmul a b): ring_scope.
Implicit Types x y: A.
Implicit Types v w: M.
Implicit Types c: F.
Lemma rmulD x: {morph (rmul^~ x): v1 v2 / v1 + v2}.
Proof. by move=> *; apply: linearD. Qed.
Lemma rmul_linear_proof : forall v, linear (rmul v).
Proof. by rewrite /rmul /rmorph; case: M => s [] b []. Qed.
Canonical Structure rmul_linear v := GRing.Linear (rmul_linear_proof v).
Lemma rmulA v x y: v :* (x * y) = (v :* x) :* y.
Proof. exact: AModuleType.action_morph. Qed.
Lemma rmulZ : forall c v x, (c *: v) :* x = c *: (v :* x).
Proof. by move=> c v x; apply: linearZZ. Qed.
Lemma rmul0 : left_zero 0 rmul.
Proof. by move=> x; apply: linear0. Qed.
Lemma rmul1 : forall v , v :* 1 = v.
Proof. by rewrite /rmul /rmorph; case: M => s [] b []. Qed.
Lemma rmul_sum : forall I r P (f : I -> M) x,
\sum_(i <- r | P i) f i :* x = (\sum_(i <- r | P i) f i) :* x.
Proof.
by move=> I r P f x; rewrite -linear_sum.
Qed.
Implicit Types vs: {vspace M}.
Implicit Types ws: {vspace A}.
Lemma size_eprodv : forall vs ws,
size (allpairs rmul (vbasis vs) (vbasis ws)) == (\dim vs * \dim ws)%N.
Proof. by move=> *; rewrite size_allpairs !size_tuple. Qed.
Definition eprodv vs ws := span (Tuple (size_eprodv vs ws)).
Local Notation "A :* B" := (eprodv A B) : vspace_scope.
Lemma memv_eprod vs ws a b : a \in vs -> b \in ws -> a :* b \in (vs :* ws)%VS.
Proof.
move=> Ha Hb.
rewrite (coord_vbasis Ha) (coord_vbasis Hb).
rewrite linear_sum /=; apply: memv_suml => j _.
rewrite -rmul_sum; apply: memv_suml => i _ /=.
rewrite linearZ memvZ //= rmulZ memvZ //=.
apply: memv_span; apply/allpairsP; exists ((vbasis vs)`_i, (vbasis ws)`_j)=> //.
by rewrite !mem_nth //= size_tuple.
Qed.
Lemma eprodvP : forall vs1 ws vs2,
reflect (forall a b, a \in vs1 -> b \in ws -> a :* b \in vs2)
(vs1 :* ws <= vs2)%VS.
Proof.
move=> vs1 ws vs2; apply: (iffP idP).
move=> Hs a b Ha Hb.
by apply: subv_trans Hs; apply: memv_eprod.
move=> Ha; apply/subvP=> v.
move/coord_span->; apply: memv_suml=> i _ /=.
apply: memvZ.
set u := allpairs _ _ _.
have: i < size u by rewrite (eqP (size_eprodv _ _)).
move/(mem_nth 0); case/allpairsP=> [[x1 x2] [I1 I2 ->]].
by apply Ha; apply: vbasis_mem.
Qed.
Lemma eprod0v: left_zero 0%VS eprodv.
Proof.
move=> vs; apply subv_anti; rewrite sub0v andbT.
apply/eprodvP=> a b; case/vlineP=> k1 -> Hb.
by rewrite scaler0 rmul0 mem0v.
Qed.
Lemma eprodv0 : forall vs, (vs :* 0 = 0)%VS.
Proof.
move=> vs; apply subv_anti; rewrite sub0v andbT.
apply/eprodvP=> a b Ha; case/vlineP=> k1 ->.
by rewrite scaler0 linear0 mem0v.
Qed.
Lemma eprodv1 : forall vs, (vs :* 1 = vs)%VS.
Proof.
case: (vbasis1 A) => k Hk He /=.
move=> vs; apply subv_anti; apply/andP; split.
apply/eprodvP=> a b Ha; case/vlineP=> k1 ->.
by rewrite linearZ /= rmul1 memvZ.
apply/subvP=> v Hv.
rewrite (coord_vbasis Hv); apply: memv_suml=> [] [i Hi] _ /=.
apply: memvZ.
rewrite -[_`_i]rmul1; apply: memv_eprod; last by apply: memv_line.
by apply: vbasis_mem; apply: mem_nth; rewrite size_tuple.
Qed.
Lemma eprodvSl ws vs1 vs2 : (vs1 <= vs2 -> vs1 :* ws <= vs2 :* ws)%VS.
Proof.
move=> Hvs; apply/eprodvP=> a b Ha Hb; apply: memv_eprod=> //.
by apply: subv_trans Hvs.
Qed.
Lemma eprodvSr vs ws1 ws2 : (ws1 <= ws2 -> vs :* ws1 <= vs :* ws2)%VS.
Proof.
move=> Hvs; apply/eprodvP=> a b Ha Hb; apply: memv_eprod=> //.
by apply: subv_trans Hvs.
Qed.
Lemma eprodv_addl: left_distributive eprodv addv.
Proof.
move=> vs1 vs2 ws; apply subv_anti; apply/andP; split.
apply/eprodvP=> a b;case/memv_addP=> v1 Hv1 [v2 Hv2 ->] Hb.
by rewrite rmulD; apply: memv_add; apply: memv_eprod.
apply/subvP=> v; case/memv_addP=> v1 Hv1 [v2 Hv2 ->].
apply: memvD.
by move: v1 Hv1; apply/subvP; apply: eprodvSl; apply: addvSl.
by move: v2 Hv2; apply/subvP; apply: eprodvSl; apply: addvSr.
Qed.
Lemma eprodv_sumr vs ws1 ws2 : (vs :* (ws1 + ws2) = vs :* ws1 + vs :* ws2)%VS.
Proof.
apply subv_anti; apply/andP; split.
apply/eprodvP=> a b Ha;case/memv_addP=> v1 Hv1 [v2 Hv2 ->].
by rewrite linearD; apply: memv_add; apply: memv_eprod.
apply/subvP=> v; case/memv_addP=> v1 Hv1 [v2 Hv2 ->].
apply: memvD.
by move: v1 Hv1; apply/subvP; apply: eprodvSr; apply: addvSl.
by move: v2 Hv2; apply/subvP; apply: eprodvSr; apply: addvSr.
Qed.
Definition modv (vs: {vspace M}) (al: {aspace A}) :=
(vs :* al <= vs)%VS.
Lemma mod0v : forall al, modv 0 al.
Proof. by move=> al; rewrite /modv eprod0v subvv. Qed.
Lemma modv1 : forall vs, modv vs (aspace1 A).
Proof. by move=> vs; rewrite /modv eprodv1 subvv. Qed.
Lemma modfv : forall al, modv fullv al.
Proof. by move=> al; apply: subvf. Qed.
Lemma memv_mod_mul : forall ms al m a,
modv ms al -> m \in ms -> a \in al -> m :* a \in ms.
Proof.
move=> ms al m a Hmo Hm Ha; apply: subv_trans Hmo.
by apply: memv_eprod.
Qed.
Lemma modvD : forall ms1 ms2 al ,
modv ms1 al -> modv ms2 al -> modv (ms1 + ms2) al.
Proof.
move=> ms1 ms2 al Hm1 Hm2; rewrite /modv eprodv_addl.
apply: (subv_trans (addvS Hm1 (subvv _))).
exact: (addvS (subvv _) Hm2).
Qed.
Lemma modv_cap : forall ms1 ms2 al ,
modv ms1 al -> modv ms2 al -> modv (ms1:&: ms2) al.
Proof.
move=> ms1 ms2 al Hm1 Hm2.
by rewrite /modv subv_cap; apply/andP; split;
[apply: subv_trans Hm1 | apply: subv_trans Hm2];
apply: eprodvSl; rewrite (capvSr,capvSl).
Qed.
Definition irreducible ms al :=
[/\ modv ms al, ms != 0%VS &
forall ms1, modv ms1 al -> (ms1 <= ms)%VS -> ms != 0%VS -> ms1 = ms].
Definition completely_reducible ms al :=
forall ms1, modv ms1 al -> (ms1 <= ms)%VS ->
exists ms2,
[/\ modv ms2 al, (ms1 :&: ms2 = 0)%VS & (ms1 + ms2)%VS = ms].
Lemma completely_reducible0 : forall al, completely_reducible 0 al.
Proof.
move=> al ms1 Hms1; rewrite subv0; move/eqP->.
by exists 0%VS; split; [apply: mod0v | apply: cap0v | apply: add0v].
Qed.
End AModuleDef.
Notation "a :* b" := (rmul a b): ring_scope.
Notation "A :* B" := (eprodv A B) : vspace_scope.
Section HomMorphism.
Variable (K: fieldType) (A: FalgType K) (M1 M2: amoduleType A).
Implicit Types ms : {vspace M1}.
Implicit Types f : 'Hom(M1, M2).
Implicit Types al : {aspace A}.
Definition modf f ms al :=
all (fun p => f (p.1 :* p.2) == f p.1 :* p.2)
(allpairs (fun x y => (x,y)) (vbasis ms) (vbasis al)).
Lemma modfP : forall f ms al,
reflect (forall x v, v \in ms -> x \in al -> f (v :* x) = f v :* x)
(modf f ms al).
Proof.
move=> f ms al; apply: (iffP idP)=> H; last first.
apply/allP=> [] [v x]; case/allpairsP=> [[x1 x2] [I1 I2 ->]].
by apply/eqP; apply: H; apply: vbasis_mem.
move=> x v Hv Hx; rewrite (coord_vbasis Hv) (coord_vbasis Hx).
rewrite !linear_sum; apply: eq_big=> //= i _.
rewrite !linearZ /=; congr (_ *: _).
rewrite -!rmul_sum linear_sum; apply: eq_big=> //= j _.
rewrite rmulZ !linearZ /= rmulZ; congr (_ *: _).
set x1 := _`_ _; set y1 := _ `_ _.
case: f H => f /=; move/allP; move/(_ (x1,y1))=> HH.
apply/eqP; apply: HH; apply/allpairsP; exists (x1, y1).
by rewrite !mem_nth //= size_tuple.
Qed.
Lemma modf_zero : forall ms al, modf 0 ms al.
Proof. by move=> ms al; apply/allP=> i _; rewrite !lfunE rmul0. Qed.
Lemma modf_add : forall f1 f2 ms al,
modf f1 ms al -> modf f2 ms al -> modf (f1 + f2) ms al.
Proof.
move=> f1 f2 ms al Hm1 Hm2; apply/allP=> [] [v x].
case/allpairsP=> [[x1 x2] [I1 I2 ->]]; rewrite !lfunE rmulD /=.
move/modfP: Hm1->; try apply: vbasis_mem=>//.
by move/modfP: Hm2->; try apply: vbasis_mem.
Qed.
Lemma modf_scale : forall k f ms al, modf f ms al -> modf (k *: f) ms al.
Proof.
move=> k f ms al Hm; apply/allP=> [] [v x].
case/allpairsP=> [[x1 x2] [I1 I2 ->]]; rewrite !lfunE rmulZ /=.
by move/modfP: Hm->; try apply: vbasis_mem.
Qed.
Lemma modv_ker : forall f ms al,
modv ms al -> modf f ms al -> modv (ms :&: lker f) al.
Proof.
move=> f ms al Hmd Hmf; apply/eprodvP=> x v.
rewrite memv_cap !memv_ker.
case/andP=> Hx Hf Hv.
rewrite memv_cap (memv_mod_mul Hmd) // memv_ker.
by move/modfP: Hmf=> ->; rewrite // (eqP Hf) rmul0 eqxx.
Qed.
Lemma modv_img : forall f ms al,
modv ms al -> modf f ms al -> modv (f @: ms) al.
Proof.
move=> f ms al Hmv Hmf; apply/eprodvP=> v x.
case/memv_imgP=> u Hu -> Hx.
move/modfP: Hmf<-=> //.
apply: memv_img.
by apply: (memv_mod_mul Hmv).
Qed.
End HomMorphism.
Section ModuleRepresentation.
Variable (F: fieldType) (gT: finGroupType)
(G: {group gT}) (M: amoduleType (galg F gT)).
Hypothesis CG: ([char F]^'.-group G)%g.
Implicit Types ms : {vspace M}.
Let FG := gaspace F G.
Local Notation " g %:FG " := (injG _ g).
Lemma Maschke : forall ms, modv ms FG -> completely_reducible ms FG.
Proof.
move=> ms Hmv ms1 Hms1 Hsub; rewrite /completely_reducible.
pose act g : 'End(M) := rmorph M (g%:FG).
have actE: forall g v, act g v = v :* g%:FG by done.
pose f: 'End(M) := #|G|%:R^-1 *:
\sum_(i in G) (act (i^-1)%g \o projv ms1 \o act i)%VF.
have Cf: forall v x, x \in FG -> f (v :* x) = f v :* x.
move=> v x; case/memv_sumP=> g_ Hg_ ->.
rewrite !linear_sum; apply: eq_big => //= i Hi.
move: (Hg_ _ Hi); case/vlineP=> k ->.
rewrite !linearZ /=; congr (_ *: _).
rewrite /f /= !lfunE /= !sum_lfunE rmulZ /=; congr (_ *: _).
rewrite -rmul_sum (reindex (fun g => (i^-1 * g)%g)); last first.
by exists (fun g => (i * g)%g)=> h; rewrite mulgA (mulVg, mulgV) mul1g.
apply: eq_big=> g; first by rewrite groupMl // groupV.
rewrite !lfunE /= !lfunE /= !actE -rmulA=> Hig.
have Hg: g \in G by rewrite -[g]mul1g -[1%g](mulgV i) -mulgA groupM.
by rewrite -injGM // mulgA mulgV mul1g invMg invgK !injGM
?groupV // rmulA.
have Himf: forall v, v \in ms1 -> f v = v.
move=> v Hv.
rewrite /f !lfunE /= sum_lfunE (eq_bigr (fun x => v)); last move=> i Hi.
by rewrite sumr_const -scaler_nat scalerA mulVf // ?scale1r // -?charf'_nat.
rewrite !lfunE /= !lfunE /= projv_id !actE; last first.
by rewrite (memv_mod_mul Hms1) //= /gvspace (bigD1 i) // memvE addvSl.
by rewrite -rmulA -injGM // ?groupV // mulgV rmul1.
have If: limg f = ms1.
apply: subv_anti; apply/andP; split; last first.
by apply/subvP=> v Hv; rewrite -(Himf _ Hv) memv_img // memvf.
apply/subvP=> i; case/memv_imgP=> x _ ->.
rewrite !lfunE memvZ //= sum_lfunE memv_suml=> // j Hj.
rewrite lfunE /= lfunE (memv_mod_mul Hms1) //; first by apply: memv_proj.
by rewrite memvE /= /gvspace (bigD1 (j^-1)%g) ?addvSl // groupV.
exists (ms :&: lker f)%VS; split.
- by apply: modv_ker=> //; apply/modfP=> *; apply: Cf.
apply/eqP; rewrite -subv0; apply/subvP=> v; rewrite memv0.
rewrite !memv_cap; case/andP=> Hv1; case/andP=> Hv2 Hv3.
by move: Hv3; rewrite memv_ker Himf.
apply: subv_anti; rewrite subv_add Hsub capvSl.
apply/subvP=> v Hv.
have->: v = f v + (v - f v) by rewrite addrC -addrA addNr addr0.
apply: memv_add; first by rewrite -If memv_img // memvf.
rewrite memv_cap; apply/andP; split.
apply: memvB=> //; apply: subv_trans Hsub.
by rewrite -If; apply: memv_img; apply: memvf.
rewrite memv_ker linearB /= (Himf (f v)) ?subrr // /in_mem /= -If.
by apply: memv_img; apply: memvf.
Qed.
End ModuleRepresentation.
Export AModuleType.Exports.
|