aboutsummaryrefslogtreecommitdiff
path: root/mathcomp/character
diff options
context:
space:
mode:
authorCyril Cohen2015-07-17 18:03:31 +0200
committerCyril Cohen2015-07-17 18:03:31 +0200
commit532de9b68384a114c6534a0736ed024c900447f9 (patch)
treee100a6a7839bf7548ab8a9e053033f8eef3c7492 /mathcomp/character
parentf180c539a00fd83d8b3b5fd2d5710eb16e971e2e (diff)
Updating files + reorganizing everything
Diffstat (limited to 'mathcomp/character')
-rw-r--r--mathcomp/character/Make2
-rw-r--r--mathcomp/character/all_character.v (renamed from mathcomp/character/all.v)0
-rw-r--r--mathcomp/character/character.v1075
-rw-r--r--mathcomp/character/classfun.v129
-rw-r--r--mathcomp/character/finfield.v29
-rw-r--r--mathcomp/character/inertia.v45
-rw-r--r--mathcomp/character/integral_char.v47
-rw-r--r--mathcomp/character/mxabelem.v58
-rw-r--r--mathcomp/character/mxrepresentation.v275
-rw-r--r--mathcomp/character/vcharacter.v69
10 files changed, 867 insertions, 862 deletions
diff --git a/mathcomp/character/Make b/mathcomp/character/Make
index 646641d..6d1f18c 100644
--- a/mathcomp/character/Make
+++ b/mathcomp/character/Make
@@ -1,4 +1,4 @@
-all.v
+all_character.v
character.v
classfun.v
finfield.v
diff --git a/mathcomp/character/all.v b/mathcomp/character/all_character.v
index 927d9a0..927d9a0 100644
--- a/mathcomp/character/all.v
+++ b/mathcomp/character/all_character.v
diff --git a/mathcomp/character/character.v b/mathcomp/character/character.v
index 166fcc5..146d965 100644
--- a/mathcomp/character/character.v
+++ b/mathcomp/character/character.v
@@ -1,27 +1,17 @@
(* (c) Copyright Microsoft Corporation and Inria. All rights reserved. *)
Require Import mathcomp.ssreflect.ssreflect.
-From mathcomp.ssreflect
-Require Import ssreflect ssrbool ssrfun eqtype ssrnat seq.
-From mathcomp.discrete
-Require Import path div choice fintype tuple finfun bigop prime finset.
-From mathcomp.fingroup
-Require Import fingroup morphism perm automorphism quotient action gproduct.
-From mathcomp.algebra
-Require Import ssralg poly finalg zmodp cyclic.
-From mathcomp.algebra
-Require Import matrix mxalgebra mxpoly vector ssrnum.
-From mathcomp.solvable
-Require Import commutator center pgroup nilpotent sylow abelian.
-From mathcomp.field
-Require Import algC.
-Require Import mxrepresentation classfun.
-
-Set Implicit Arguments.
-Unset Strict Implicit.
-Unset Printing Implicit Defensive.
-
-Import GroupScope GRing.Theory Num.Theory.
-Local Open Scope ring_scope.
+From mathcomp
+Require Import ssrbool ssrfun eqtype ssrnat seq path div choice.
+From mathcomp
+Require Import fintype tuple finfun bigop prime ssralg poly finset gproduct.
+From mathcomp
+Require Import fingroup morphism perm automorphism quotient finalg action.
+From mathcomp
+Require Import zmodp commutator cyclic center pgroup nilpotent sylow abelian.
+From mathcomp
+Require Import matrix mxalgebra mxpoly mxrepresentation vector ssrnum algC.
+From mathcomp
+Require Import classfun.
(******************************************************************************)
(* This file contains the basic notions of character theory, based on Isaacs. *)
@@ -78,6 +68,13 @@ Local Open Scope ring_scope.
(* class_Iirr xG == the index of xG \in classes G, in Iirr G. *)
(******************************************************************************)
+Set Implicit Arguments.
+Unset Strict Implicit.
+Unset Printing Implicit Defensive.
+
+Import GroupScope GRing.Theory Num.Theory.
+Local Open Scope ring_scope.
+
Local Notation algCF := [fieldType of algC].
Section AlgC.
@@ -333,9 +330,9 @@ rewrite !big_cons /= in dxW defW *.
rewrite 2!(big_nth i) !big_mkord /= in IHe dxW defW.
set Wi := (\sum_i _)%MS in defW dxW IHe.
rewrite -mxdirectE mxdirect_addsE !mxdirectE eqxx /= -/Wi in dxW.
-have modWi: mxmodule rG Wi by exact: sumsmx_module.
+have modWi: mxmodule rG Wi by apply: sumsmx_module.
case/andP: dxW; move/(IHe Wi modWi) {IHe}; move/(_ (eqmx_refl _))=> rsimWi.
-by move/eqP; move/mxdirect_addsP=> dxUiWi; exact: mx_rsim_dadd (rsimU i) rsimWi.
+by move/eqP; move/mxdirect_addsP=> dxUiWi; apply: mx_rsim_dadd (rsimU i) rsimWi.
Qed.
Definition muln_grepr rW k := \big[dadd_grepr/grepr0]_(i < k) rW.
@@ -348,7 +345,7 @@ Proof.
set M := socle_base W => modW rsimM.
have simM: mxsimple rG M := socle_simple W.
have rankM_gt0: (\rank M > 0)%N by rewrite lt0n mxrank_eq0; case: simM.
-have [I /= U_I simU]: mxsemisimple rG W by exact: component_mx_semisimple.
+have [I /= U_I simU]: mxsemisimple rG W by apply: component_mx_semisimple.
pose U (i : 'I_#|I|) := U_I (enum_val i).
have reindexI := reindex _ (onW_bij I (enum_val_bij I)).
rewrite mxdirectE /= !reindexI -mxdirectE /= => defW dxW.
@@ -360,8 +357,8 @@ have ->: socle_mult W = #|I|.
rewrite -defW (mxdirectP dxW) /= -sum_nat_const reindexI /=.
by apply: eq_bigr => i _; rewrite -(mxrank_iso (isoU i)).
have modU: mxmodule rG (U _) := mxsimple_module (simU _).
-suff: mx_rsim (submod_repr (modU _)) rW by exact: mx_rsim_dsum defW dxW.
-by move=> i; apply: mx_rsim_trans (mx_rsim_sym _) rsimM; exact/mx_rsim_iso.
+suff: mx_rsim (submod_repr (modU _)) rW by apply: mx_rsim_dsum defW dxW.
+by move=> i; apply: mx_rsim_trans (mx_rsim_sym _) rsimM; apply/mx_rsim_iso.
Qed.
End DsumRepr.
@@ -466,7 +463,7 @@ have [defS dxS]: (S :=: 1%:M)%MS /\ mxdirect S.
rewrite /soc; case: pickP => [W' | /(_ Wi)] /= /eqP // eqWi.
apply/eqP/socle_rsimP.
apply: mx_rsim_trans (rsim_irr_comp iG C'G (socle_irr _)) (mx_rsim_sym _).
- by rewrite [irr_comp _ _]eqWi; exact: rsim_irr_comp (socle_irr _).
+ by rewrite [irr_comp _ _]eqWi; apply: rsim_irr_comp (socle_irr _).
have bij_irr: {on [pred i | soc i], bijective standard_irr}.
exists (odflt W0 \o soc) => [Wi _ | i]; first by rewrite /= irrK.
by rewrite inE /soc /=; case: pickP => //= Wi; move/eqP.
@@ -485,7 +482,7 @@ apply: mx_rsim_dsum (modW) _ defS dxS _ => i.
rewrite /W /standard_irr_coef /modW /soc; case: pickP => [Wi|_] /=; last first.
rewrite /muln_grepr big_ord0.
by exists 0 => [||x _]; rewrite ?mxrank0 ?mulmx0 ?mul0mx.
-by move/eqP=> <-; apply: mx_rsim_socle; exact: rsim_irr_comp (socle_irr Wi).
+by move/eqP=> <-; apply: mx_rsim_socle; apply: rsim_irr_comp (socle_irr Wi).
Qed.
End StandardRepr.
@@ -560,7 +557,7 @@ Lemma NirrE : Nirr G = #|classes G|.
Proof. by rewrite /pred_Nirr (cardD1 [1]) classes1. Qed.
Fact Iirr_cast : Nirr G = #|sG|.
-Proof. by rewrite NirrE ?card_irr ?algC'G //; exact: groupC. Qed.
+Proof. by rewrite NirrE ?card_irr ?algC'G //; apply: groupC. Qed.
Let offset := cast_ord (esym Iirr_cast) (enum_rank [1 sG]%irr).
@@ -790,7 +787,7 @@ Lemma irr_reprP xi :
(xi \in irr G).
Proof.
apply: (iffP (irrP xi)) => [[i ->] | [[n rG] irr_rG ->]].
- by exists (Representation 'Chi_i); [exact: socle_irr | rewrite irrRepr].
+ by exists (Representation 'Chi_i); [apply: socle_irr | rewrite irrRepr].
exists (irr_of_socle (irr_comp sG rG)); rewrite -irrRepr irr_of_socleK /=.
exact/cfRepr_sim/rsim_irr_comp.
Qed.
@@ -799,7 +796,7 @@ Qed.
Lemma Wedderburn_id_expansion i :
'e_i = #|G|%:R^-1 *: \sum_(x in G) 'chi_i 1%g * 'chi_i x^-1%g *: aG x.
Proof.
-have Rei: ('e_i \in 'R_i)%MS by exact: Wedderburn_id_mem.
+have Rei: ('e_i \in 'R_i)%MS by apply: Wedderburn_id_mem.
have /envelop_mxP[a def_e]: ('e_i \in R_G)%MS; last rewrite -/aG in def_e.
by move: Rei; rewrite genmxE mem_sub_gring => /andP[].
apply: canRL (scalerK (neq0CG _)) _; rewrite def_e linear_sum /=.
@@ -932,20 +929,21 @@ Section AutChar.
Variables (gT : finGroupType) (G : {group gT}).
Implicit Type u : {rmorphism algC -> algC}.
+Implicit Type chi : 'CF(G).
Lemma cfRepr_map u n (rG : mx_representation algCF G n) :
cfRepr (map_repr u rG) = cfAut u (cfRepr rG).
Proof. by apply/cfun_inP=> x Gx; rewrite !cfunE Gx map_reprE trace_map_mx. Qed.
-Lemma cfAut_char u (chi : 'CF(G)) :
- chi \is a character -> cfAut u chi \is a character.
+Lemma cfAut_char u chi : (cfAut u chi \is a character) = (chi \is a character).
Proof.
-case/char_reprP=> rG ->; apply/char_reprP.
+without loss /char_reprP[rG ->]: u chi / chi \is a character.
+ by move=> IHu; apply/idP/idP=> ?; first rewrite -(cfAutK u chi); rewrite IHu.
+rewrite cfRepr_char; apply/char_reprP.
by exists (Representation (map_repr u rG)); rewrite cfRepr_map.
Qed.
-Lemma cfConjC_char (chi : 'CF(G)) :
- chi \is a character -> chi^*%CF \is a character.
+Lemma cfConjC_char chi : (chi^*%CF \is a character) = (chi \is a character).
Proof. exact: cfAut_char. Qed.
Lemma cfAut_char1 u (chi : 'CF(G)) :
@@ -1037,7 +1035,7 @@ Qed.
Lemma lin_char_irr : xi \in irr G.
Proof.
case/andP: CFxi => /char_reprP[rG ->]; rewrite cfRepr1 pnatr_eq1 => /eqP n1.
-by apply/irr_reprP; exists rG => //; exact/mx_abs_irrW/linear_mx_abs_irr.
+by apply/irr_reprP; exists rG => //; apply/mx_abs_irrW/linear_mx_abs_irr.
Qed.
Lemma mul_conjC_lin_char : xi * xi^*%CF = 1.
@@ -1052,12 +1050,6 @@ Proof. by apply/unitrPr; exists xi^*%CF; apply: mul_conjC_lin_char. Qed.
Lemma invr_lin_char : xi^-1 = xi^*%CF.
Proof. by rewrite -[_^-1]mulr1 -mul_conjC_lin_char mulKr ?lin_char_unitr. Qed.
-Lemma cfAut_lin_char u : cfAut u xi \is a linear_char.
-Proof. by rewrite qualifE cfunE lin_char1 rmorph1 cfAut_char ?lin_charW /=. Qed.
-
-Lemma cfConjC_lin_char : xi^*%CF \is a linear_char.
-Proof. exact: cfAut_lin_char. Qed.
-
Lemma fful_lin_char_inj : cfaithful xi -> {in G &, injective xi}.
Proof.
move=> fful_phi x y Gx Gy xi_xy; apply/eqP; rewrite eq_mulgV1 -in_set1.
@@ -1068,6 +1060,14 @@ Qed.
End OneChar.
+Lemma cfAut_lin_char u (xi : 'CF(G)) :
+ (cfAut u xi \is a linear_char) = (xi \is a linear_char).
+Proof. by rewrite qualifE cfAut_char; apply/andb_id2l=> /cfAut_char1->. Qed.
+
+Lemma cfConjC_lin_char (xi : 'CF(G)) :
+ (xi^*%CF \is a linear_char) = (xi \is a linear_char).
+Proof. exact: cfAut_lin_char. Qed.
+
Lemma card_Iirr_abelian : abelian G -> #|Iirr G| = #|G|.
Proof. by rewrite card_ord NirrE card_classes_abelian => /eqP. Qed.
@@ -1079,7 +1079,7 @@ Lemma char_abelianP :
Proof.
apply: (iffP idP) => [cGG i | CF_G].
rewrite qualifE irr_char /= irr1_degree.
- by rewrite irr_degree_abelian //; last exact: groupC.
+ by rewrite irr_degree_abelian //; last apply: groupC.
rewrite card_classes_abelian -NirrE -eqC_nat -irr_sum_square //.
rewrite -{1}[Nirr G]card_ord -sumr_const; apply/eqP/eq_bigr=> i _.
by rewrite lin_char1 ?expr1n ?CF_G.
@@ -1115,173 +1115,6 @@ End Linear.
Prenex Implicits linear_char.
-Section Restrict.
-
-Variable (gT : finGroupType) (G H : {group gT}).
-
-Lemma cfRepr_sub n (rG : mx_representation algCF G n) (sHG : H \subset G) :
- cfRepr (subg_repr rG sHG) = 'Res[H] (cfRepr rG).
-Proof.
-by apply/cfun_inP => x Hx; rewrite cfResE // !cfunE Hx (subsetP sHG).
-Qed.
-
-Lemma cfRes_char chi : chi \is a character -> 'Res[H, G] chi \is a character.
-Proof.
-have [sHG | not_sHG] := boolP (H \subset G).
- by case/char_reprP=> rG ->; rewrite -(cfRepr_sub rG sHG) cfRepr_char.
-by move/Cnat_char1=> Nchi1; rewrite cfResEout // rpredZ_Cnat ?rpred1.
-Qed.
-
-Lemma cfRes_eq0 phi : phi \is a character -> ('Res[H, G] phi == 0) = (phi == 0).
-Proof. by move=> Nchi; rewrite -!char1_eq0 ?cfRes_char // cfRes1. Qed.
-
-Lemma cfRes_lin_char chi :
- chi \is a linear_char -> 'Res[H, G] chi \is a linear_char.
-Proof. by case/andP=> Nchi; rewrite qualifE cfRes_char ?cfRes1. Qed.
-
-Lemma Res_irr_neq0 i : 'Res[H, G] 'chi_i != 0.
-Proof. by rewrite cfRes_eq0 ?irr_neq0 ?irr_char. Qed.
-
-Lemma cfRes_lin_lin (chi : 'CF(G)) :
- chi \is a character -> 'Res[H] chi \is a linear_char -> chi \is a linear_char.
-Proof. by rewrite !qualifE cfRes1 => -> /andP[]. Qed.
-
-Lemma cfRes_irr_irr chi :
- chi \is a character -> 'Res[H] chi \in irr H -> chi \in irr G.
-Proof.
-have [sHG /char_reprP[rG ->] | not_sHG Nchi] := boolP (H \subset G).
- rewrite -(cfRepr_sub _ sHG) => /irr_reprP[rH irrH def_rH]; apply/irr_reprP.
- suffices /subg_mx_irr: mx_irreducible (subg_repr rG sHG) by exists rG.
- by apply: mx_rsim_irr irrH; exact/cfRepr_rsimP/eqP.
-rewrite cfResEout // => /irrP[j Dchi_j]; apply/lin_char_irr/cfRes_lin_lin=> //.
-suffices j0: j = 0 by rewrite cfResEout // Dchi_j j0 irr0 rpred1.
-apply: contraNeq (irr1_neq0 j) => nz_j.
-have:= xcfun_id j 0; rewrite -Dchi_j cfunE xcfunZl -irr0 xcfun_id eqxx => ->.
-by rewrite (negPf nz_j).
-Qed.
-
-Definition Res_Iirr (A B : {set gT}) i := cfIirr ('Res[B, A] 'chi_i).
-
-Lemma Res_Iirr0 : Res_Iirr H (0 : Iirr G) = 0.
-Proof. by rewrite /Res_Iirr irr0 rmorph1 -irr0 irrK. Qed.
-
-Lemma lin_Res_IirrE i : 'chi[G]_i 1%g = 1 -> 'chi_(Res_Iirr H i) = 'Res 'chi_i.
-Proof.
-move=> chi1; rewrite cfIirrE ?lin_char_irr ?cfRes_lin_char //.
-by rewrite qualifE irr_char /= chi1.
-Qed.
-
-End Restrict.
-
-Arguments Scope Res_Iirr [_ group_scope group_scope ring_scope].
-
-Section Morphim.
-
-Variables (aT rT : finGroupType) (G D : {group aT}) (f : {morphism D >-> rT}).
-Implicit Type chi : 'CF(f @* G).
-
-Lemma cfRepr_morphim n (rfG : mx_representation algCF (f @* G) n) sGD :
- cfRepr (morphim_repr rfG sGD) = cfMorph (cfRepr rfG).
-Proof.
-apply/cfun_inP=> x Gx; have Dx: x \in D := subsetP sGD x Gx.
-by rewrite cfMorphE // !cfunE ?mem_morphim ?Gx.
-Qed.
-
-Lemma cfMorph_char chi : chi \is a character -> cfMorph chi \is a character.
-Proof.
-have [sGD /char_reprP[rG ->] | outGD Nchi] := boolP (G \subset D); last first.
- by rewrite cfMorphEout // rpredZ_Cnat ?rpred1 ?Cnat_char1.
-apply/char_reprP; exists (Representation (morphim_repr rG sGD)).
-by rewrite cfRepr_morphim.
-Qed.
-
-Lemma cfMorph_lin_char chi :
- chi \is a linear_char -> cfMorph chi \is a linear_char.
-Proof. by case/andP=> Nchi; rewrite qualifE cfMorph_char ?cfMorph1. Qed.
-
-Lemma cfMorph_irr chi :
- G \subset D -> chi \in irr (f @* G) -> cfMorph chi \in irr G.
-Proof.
-move=> sGD /irr_reprP[rG irrG ->]; apply/irr_reprP.
-exists (Representation (morphim_repr rG sGD)); first exact/morphim_mx_irr.
-apply/cfun_inP=> x Gx; rewrite !cfunElock /= sGD Gx.
-by rewrite mem_morphim ?(subsetP sGD).
-Qed.
-
-Definition morph_Iirr i := cfIirr (cfMorph 'chi[f @* G]_i).
-
-Lemma morph_Iirr0 : morph_Iirr 0 = 0.
-Proof. by rewrite /morph_Iirr irr0 rmorph1 -irr0 irrK. Qed.
-
-Hypothesis sGD : G \subset D.
-
-Lemma morph_IirrE i : 'chi_(morph_Iirr i) = cfMorph 'chi_i.
-Proof. by rewrite cfIirrE ?cfMorph_irr ?mem_irr. Qed.
-
-Lemma morph_Iirr_inj : injective morph_Iirr.
-Proof.
-by move=> i j eq_ij; apply/irr_inj/cfMorph_inj; rewrite // -!morph_IirrE eq_ij.
-Qed.
-
-Lemma morph_Iirr_eq0 i : (morph_Iirr i == 0) = (i == 0).
-Proof. by rewrite -!irr_eq1 morph_IirrE cfMorph_eq1. Qed.
-
-End Morphim.
-
-Section Isom.
-
-Variables (aT rT : finGroupType) (G : {group aT}) (f : {morphism G >-> rT}).
-Variables (R : {group rT}) (isoGR : isom G R f).
-Implicit Type chi : 'CF(G).
-
-Lemma cfIsom_char chi : chi \is a character -> cfIsom isoGR chi \is a character.
-Proof.
-by move=> Nchi; rewrite [cfIsom _]locked_withE cfMorph_char ?cfRes_char.
-Qed.
-
-Lemma cfIsom_lin_char chi :
- chi \is a linear_char -> cfIsom isoGR chi \is a linear_char.
-Proof. by case/andP=> Nchi; rewrite qualifE cfIsom_char ?cfIsom1. Qed.
-
-Lemma cfIsom_irr chi : chi \in irr G -> cfIsom isoGR chi \in irr R.
-Proof.
-move=> irr_chi; rewrite [cfIsom _]locked_withE cfMorph_irr //.
-by rewrite (isom_im (isom_sym isoGR)) cfRes_id.
-Qed.
-
-Definition isom_Iirr i := cfIirr (cfIsom isoGR 'chi_i).
-
-Lemma isom_IirrE i : 'chi_(isom_Iirr i) = cfIsom isoGR 'chi_i.
-Proof. by rewrite cfIirrE ?cfIsom_irr ?mem_irr. Qed.
-
-Lemma isom_Iirr_inj : injective isom_Iirr.
-Proof.
-by move=> i j eqij; apply/irr_inj/(cfIsom_inj isoGR); rewrite -!isom_IirrE eqij.
-Qed.
-
-Lemma isom_Iirr_eq0 i : (isom_Iirr i == 0) = (i == 0).
-Proof. by rewrite -!irr_eq1 isom_IirrE cfIsom_eq1. Qed.
-
-Lemma isom_Iirr0 : isom_Iirr 0 = 0.
-Proof. by apply/eqP; rewrite isom_Iirr_eq0. Qed.
-
-End Isom.
-
-Implicit Arguments isom_Iirr_inj [aT rT G f R x1 x2].
-
-Section IsomInv.
-
-Variables (aT rT : finGroupType) (G : {group aT}) (f : {morphism G >-> rT}).
-Variables (R : {group rT}) (isoGR : isom G R f).
-
-Lemma isom_IirrK : cancel (isom_Iirr isoGR) (isom_Iirr (isom_sym isoGR)).
-Proof. by move=> i; apply: irr_inj; rewrite !isom_IirrE cfIsomK. Qed.
-
-Lemma isom_IirrKV : cancel (isom_Iirr (isom_sym isoGR)) (isom_Iirr isoGR).
-Proof. by move=> i; apply: irr_inj; rewrite !isom_IirrE cfIsomKV. Qed.
-
-End IsomInv.
-
Section OrthogonalityRelations.
Variables aT gT : finGroupType.
@@ -1303,9 +1136,9 @@ have [I U W simU W1 dxW]: mxsemisimple rG 1%:M.
rewrite -(reducible_Socle1 (DecSocleType rG) (mx_Maschke _ (algC'G G))).
exact: Socle_semisimple.
have linU i: \rank (U i) = 1%N.
- by apply: mxsimple_abelian_linear cGG (simU i); exact: groupC.
+ by apply: mxsimple_abelian_linear cGG (simU i); apply: groupC.
have castI: f = #|I|.
- by rewrite -(mxrank1 algCF f) -W1 (eqnP dxW) /= -sum1_card; exact/eq_bigr.
+ by rewrite -(mxrank1 algCF f) -W1 (eqnP dxW) /= -sum1_card; apply/eq_bigr.
pose B := \matrix_j nz_row (U (enum_val (cast_ord castI j))).
have rowU i: (nz_row (U i) :=: U i)%MS.
apply/eqmxP; rewrite -(geq_leqif (mxrank_leqif_eq (nz_row_sub _))) linU.
@@ -1417,8 +1250,8 @@ Proof. by move=> xG GxG; rewrite /c cast_ordKV enum_rankK_in. Qed.
Lemma reindex_irr_class R idx (op : @Monoid.com_law R idx) F :
\big[op/idx]_(xG in classes G) F xG = \big[op/idx]_i F (c i).
Proof.
-rewrite (reindex c); first by apply: eq_bigl => i; exact: enum_valP.
-by exists iC; [apply: in1W; exact: irr_classK | exact: class_IirrK].
+rewrite (reindex c); first by apply: eq_bigl => i; apply: enum_valP.
+by exists iC; [apply: in1W; apply: irr_classK | apply: class_IirrK].
Qed.
(* The explicit value of the inverse is needed for the proof of the second *)
@@ -1451,10 +1284,10 @@ transitivity ((#|'C_G[repr (y ^: G)]|%:R *: (X' *m X)) i_y i_x).
rewrite scalemxAl !mxE; apply: eq_bigr => k _; rewrite !mxE mulrC -!mulrA.
by rewrite !class_IirrK ?mem_classes // !cfun_repr mulVKf ?neq0CG.
rewrite mulmx1C // !mxE -!divg_index !(index_cent1, =^~ indexgI).
-rewrite (class_transr (mem_repr y _)) ?class_refl // mulr_natr.
+rewrite (class_eqP (mem_repr y _)) ?class_refl // mulr_natr.
rewrite (can_in_eq class_IirrK) ?mem_classes //.
have [-> | not_yGx] := altP eqP; first by rewrite class_refl.
-by rewrite [x \in _](contraNF _ not_yGx) // => /class_transr->.
+by rewrite [x \in _](contraNF _ not_yGx) // => /class_eqP->.
Qed.
Lemma eq_irr_mem_classP x y :
@@ -1638,24 +1471,435 @@ Qed.
End InnerProduct.
+Section IrrConstt.
+
+Variable (gT : finGroupType) (G H : {group gT}).
+
+Lemma char1_ge_norm (chi : 'CF(G)) x :
+ chi \is a character -> `|chi x| <= chi 1%g.
+Proof.
+case/char_reprP=> rG ->; case Gx: (x \in G); last first.
+ by rewrite cfunE cfRepr1 Gx normr0 ler0n.
+by have [e [_ _ []]] := repr_rsim_diag rG Gx.
+Qed.
+
+Lemma max_cfRepr_norm_scalar n (rG : mx_representation algCF G n) x :
+ x \in G -> `|cfRepr rG x| = cfRepr rG 1%g ->
+ exists2 c, `|c| = 1 & rG x = c%:M.
+Proof.
+move=> Gx; have [e [[B uB def_x] [_ e1] [-> _] _]] := repr_rsim_diag rG Gx.
+rewrite cfRepr1 -[n in n%:R]card_ord -sumr_const -(eq_bigr _ (in1W e1)).
+case/normC_sum_eq1=> [i _ | c /eqP norm_c_1 def_e]; first by rewrite e1.
+have{def_e} def_e: e = const_mx c by apply/rowP=> i; rewrite mxE def_e ?andbT.
+by exists c => //; rewrite def_x def_e diag_const_mx scalar_mxC mulmxKV.
+Qed.
+
+Lemma max_cfRepr_mx1 n (rG : mx_representation algCF G n) x :
+ x \in G -> cfRepr rG x = cfRepr rG 1%g -> rG x = 1%:M.
+Proof.
+move=> Gx kerGx; have [|c _ def_x] := @max_cfRepr_norm_scalar n rG x Gx.
+ by rewrite kerGx cfRepr1 normr_nat.
+move/eqP: kerGx; rewrite cfRepr1 cfunE Gx {rG}def_x mxtrace_scalar.
+case: n => [_|n]; first by rewrite ![_%:M]flatmx0.
+rewrite mulrb -subr_eq0 -mulrnBl -mulr_natl mulf_eq0 pnatr_eq0 /=.
+by rewrite subr_eq0 => /eqP->.
+Qed.
+
+Definition irr_constt (B : {set gT}) phi := [pred i | '[phi, 'chi_i]_B != 0].
+
+Lemma irr_consttE i phi : (i \in irr_constt phi) = ('[phi, 'chi_i]_G != 0).
+Proof. by []. Qed.
+
+Lemma constt_charP (i : Iirr G) chi :
+ chi \is a character ->
+ reflect (exists2 chi', chi' \is a character & chi = 'chi_i + chi')
+ (i \in irr_constt chi).
+Proof.
+move=> Nchi; apply: (iffP idP) => [i_in_chi| [chi' Nchi' ->]]; last first.
+ rewrite inE /= cfdotDl cfdot_irr eqxx -(eqP (Cnat_cfdot_char_irr i Nchi')).
+ by rewrite -natrD pnatr_eq0.
+exists (chi - 'chi_i); last by rewrite addrC subrK.
+apply/forallP=> j; rewrite coord_cfdot cfdotBl cfdot_irr.
+have [<- | _] := eqP; last by rewrite subr0 Cnat_cfdot_char_irr.
+have := i_in_chi; rewrite inE /= -(eqP (Cnat_cfdot_char_irr i Nchi)) pnatr_eq0.
+by case: (truncC _) => // n _; rewrite mulrSr addrK ?isNatC_nat.
+Qed.
+
+Lemma cfun_sum_constt (phi : 'CF(G)) :
+ phi = \sum_(i in irr_constt phi) '[phi, 'chi_i] *: 'chi_i.
+Proof.
+rewrite {1}[phi]cfun_sum_cfdot (bigID [pred i | '[phi, 'chi_i] == 0]) /=.
+by rewrite big1 ?add0r // => i /eqP->; rewrite scale0r.
+Qed.
+
+Lemma neq0_has_constt (phi : 'CF(G)) :
+ phi != 0 -> exists i, i \in irr_constt phi.
+Proof.
+move=> nz_phi; apply/existsP; apply: contra nz_phi => /pred0P phi0.
+by rewrite [phi]cfun_sum_constt big_pred0.
+Qed.
+
+Lemma constt_irr i : irr_constt 'chi[G]_i =i pred1 i.
+Proof.
+by move=> j; rewrite !inE cfdot_irr pnatr_eq0 (eq_sym j); case: (i == j).
+Qed.
+
+Lemma char1_ge_constt (i : Iirr G) chi :
+ chi \is a character -> i \in irr_constt chi -> 'chi_i 1%g <= chi 1%g.
+Proof.
+move=> {chi} _ /constt_charP[// | chi Nchi ->].
+by rewrite cfunE addrC -subr_ge0 addrK char1_ge0.
+Qed.
+
+Lemma constt_ortho_char (phi psi : 'CF(G)) i j :
+ phi \is a character -> psi \is a character ->
+ i \in irr_constt phi -> j \in irr_constt psi ->
+ '[phi, psi] = 0 -> '['chi_i, 'chi_j] = 0.
+Proof.
+move=> _ _ /constt_charP[//|phi1 Nphi1 ->] /constt_charP[//|psi1 Npsi1 ->].
+rewrite cfdot_irr; case: eqP => // -> /eqP/idPn[].
+rewrite cfdotDl !cfdotDr cfnorm_irr -addrA gtr_eqF ?ltr_paddr ?ltr01 //.
+by rewrite Cnat_ge0 ?rpredD ?Cnat_cfdot_char ?irr_char.
+Qed.
+
+End IrrConstt.
+
+Arguments Scope irr_constt [_ group_scope cfun_scope].
+
+Section Kernel.
+
+Variable (gT : finGroupType) (G : {group gT}).
+Implicit Types (phi chi xi : 'CF(G)) (H : {group gT}).
+
+Lemma cfker_repr n (rG : mx_representation algCF G n) :
+ cfker (cfRepr rG) = rker rG.
+Proof.
+apply/esym/setP=> x; rewrite inE mul1mx /=.
+case Gx: (x \in G); last by rewrite inE Gx.
+apply/eqP/idP=> Kx; last by rewrite max_cfRepr_mx1 // cfker1.
+rewrite inE Gx; apply/forallP=> y; rewrite !cfunE !mulrb groupMl //.
+by case: ifP => // Gy; rewrite repr_mxM // Kx mul1mx.
+Qed.
+
+Lemma cfkerEchar chi :
+ chi \is a character -> cfker chi = [set x in G | chi x == chi 1%g].
+Proof.
+move=> Nchi; apply/setP=> x; apply/idP/setIdP=> [Kx | [Gx /eqP chi_x]].
+ by rewrite (subsetP (cfker_sub chi)) // cfker1.
+case/char_reprP: Nchi => rG -> in chi_x *; rewrite inE Gx; apply/forallP=> y.
+rewrite !cfunE groupMl // !mulrb; case: ifP => // Gy.
+by rewrite repr_mxM // max_cfRepr_mx1 ?mul1mx.
+Qed.
+
+Lemma cfker_nzcharE chi :
+ chi \is a character -> chi != 0 -> cfker chi = [set x | chi x == chi 1%g].
+Proof.
+move=> Nchi nzchi; apply/setP=> x; rewrite cfkerEchar // !inE andb_idl //.
+by apply: contraLR => /cfun0-> //; rewrite eq_sym char1_eq0.
+Qed.
+
+Lemma cfkerEirr i : cfker 'chi[G]_i = [set x | 'chi_i x == 'chi_i 1%g].
+Proof. by rewrite cfker_nzcharE ?irr_char ?irr_neq0. Qed.
+
+Lemma cfker_irr0 : cfker 'chi[G]_0 = G.
+Proof. by rewrite irr0 cfker_cfun1. Qed.
+
+Lemma cfaithful_reg : cfaithful (cfReg G).
+Proof.
+apply/subsetP=> x; rewrite cfkerEchar ?cfReg_char // !inE !cfRegE eqxx.
+by case/andP=> _; apply: contraLR => /negbTE->; rewrite eq_sym neq0CG.
+Qed.
+
+Lemma cfkerE chi :
+ chi \is a character ->
+ cfker chi = G :&: \bigcap_(i in irr_constt chi) cfker 'chi_i.
+Proof.
+move=> Nchi; rewrite cfkerEchar //; apply/setP=> x; rewrite !inE.
+apply: andb_id2l => Gx; rewrite {1 2}[chi]cfun_sum_constt !sum_cfunE.
+apply/eqP/bigcapP=> [Kx i Ci | Kx]; last first.
+ by apply: eq_bigr => i /Kx Kx_i; rewrite !cfunE cfker1.
+rewrite cfkerEirr inE /= -(inj_eq (mulfI Ci)).
+have:= (normC_sum_upper _ Kx) i; rewrite !cfunE => -> // {i Ci} i _.
+have chi_i_ge0: 0 <= '[chi, 'chi_i].
+ by rewrite Cnat_ge0 ?Cnat_cfdot_char_irr.
+by rewrite !cfunE normrM (normr_idP _) ?ler_wpmul2l ?char1_ge_norm ?irr_char.
+Qed.
+
+Lemma TI_cfker_irr : \bigcap_i cfker 'chi[G]_i = [1].
+Proof.
+apply/trivgP; apply: subset_trans cfaithful_reg; rewrite cfkerE ?cfReg_char //.
+rewrite subsetI (bigcap_min 0) //=; last by rewrite cfker_irr0.
+by apply/bigcapsP=> i _; rewrite bigcap_inf.
+Qed.
+
+Lemma cfker_constt i chi :
+ chi \is a character -> i \in irr_constt chi ->
+ cfker chi \subset cfker 'chi[G]_i.
+Proof. by move=> Nchi Ci; rewrite cfkerE ?subIset ?(bigcap_min i) ?orbT. Qed.
+
+Section KerLin.
+
+Variable xi : 'CF(G).
+Hypothesis lin_xi : xi \is a linear_char.
+Let Nxi: xi \is a character. Proof. by have [] := andP lin_xi. Qed.
+
+Lemma lin_char_der1 : G^`(1)%g \subset cfker xi.
+Proof.
+rewrite gen_subG /=; apply/subsetP=> _ /imset2P[x y Gx Gy ->].
+rewrite cfkerEchar // inE groupR //= !lin_charM ?lin_charV ?in_group //.
+by rewrite mulrCA mulKf ?mulVf ?lin_char_neq0 // lin_char1.
+Qed.
+
+Lemma cforder_lin_char : #[xi]%CF = exponent (G / cfker xi)%g.
+Proof.
+apply/eqP; rewrite eqn_dvd; apply/andP; split.
+ apply/dvdn_cforderP=> x Gx; rewrite -lin_charX // -cfQuoEker ?groupX //.
+ rewrite morphX ?(subsetP (cfker_norm xi)) //= expg_exponent ?mem_quotient //.
+ by rewrite cfQuo1 ?cfker_normal ?lin_char1.
+have abGbar: abelian (G / cfker xi) := sub_der1_abelian lin_char_der1.
+have [_ /morphimP[x Nx Gx ->] ->] := exponent_witness (abelian_nil abGbar).
+rewrite order_dvdn -morphX //= coset_id cfkerEchar // !inE groupX //=.
+by rewrite lin_charX ?lin_char1 // (dvdn_cforderP _ _ _).
+Qed.
+
+Lemma cforder_lin_char_dvdG : #[xi]%CF %| #|G|.
+Proof.
+by rewrite cforder_lin_char (dvdn_trans (exponent_dvdn _)) ?dvdn_morphim.
+Qed.
+
+Lemma cforder_lin_char_gt0 : (0 < #[xi]%CF)%N.
+Proof. by rewrite cforder_lin_char exponent_gt0. Qed.
+
+End KerLin.
+
+End Kernel.
+
+Section Restrict.
+
+Variable (gT : finGroupType) (G H : {group gT}).
+
+Lemma cfRepr_sub n (rG : mx_representation algCF G n) (sHG : H \subset G) :
+ cfRepr (subg_repr rG sHG) = 'Res[H] (cfRepr rG).
+Proof.
+by apply/cfun_inP => x Hx; rewrite cfResE // !cfunE Hx (subsetP sHG).
+Qed.
+
+Lemma cfRes_char chi : chi \is a character -> 'Res[H, G] chi \is a character.
+Proof.
+have [sHG | not_sHG] := boolP (H \subset G).
+ by case/char_reprP=> rG ->; rewrite -(cfRepr_sub rG sHG) cfRepr_char.
+by move/Cnat_char1=> Nchi1; rewrite cfResEout // rpredZ_Cnat ?rpred1.
+Qed.
+
+Lemma cfRes_eq0 phi : phi \is a character -> ('Res[H, G] phi == 0) = (phi == 0).
+Proof. by move=> Nchi; rewrite -!char1_eq0 ?cfRes_char // cfRes1. Qed.
+
+Lemma cfRes_lin_char chi :
+ chi \is a linear_char -> 'Res[H, G] chi \is a linear_char.
+Proof. by case/andP=> Nchi; rewrite qualifE cfRes_char ?cfRes1. Qed.
+
+Lemma Res_irr_neq0 i : 'Res[H, G] 'chi_i != 0.
+Proof. by rewrite cfRes_eq0 ?irr_neq0 ?irr_char. Qed.
+
+Lemma cfRes_lin_lin (chi : 'CF(G)) :
+ chi \is a character -> 'Res[H] chi \is a linear_char -> chi \is a linear_char.
+Proof. by rewrite !qualifE cfRes1 => -> /andP[]. Qed.
+
+Lemma cfRes_irr_irr chi :
+ chi \is a character -> 'Res[H] chi \in irr H -> chi \in irr G.
+Proof.
+have [sHG /char_reprP[rG ->] | not_sHG Nchi] := boolP (H \subset G).
+ rewrite -(cfRepr_sub _ sHG) => /irr_reprP[rH irrH def_rH]; apply/irr_reprP.
+ suffices /subg_mx_irr: mx_irreducible (subg_repr rG sHG) by exists rG.
+ by apply: mx_rsim_irr irrH; apply/cfRepr_rsimP/eqP.
+rewrite cfResEout // => /irrP[j Dchi_j]; apply/lin_char_irr/cfRes_lin_lin=> //.
+suffices j0: j = 0 by rewrite cfResEout // Dchi_j j0 irr0 rpred1.
+apply: contraNeq (irr1_neq0 j) => nz_j.
+have:= xcfun_id j 0; rewrite -Dchi_j cfunE xcfunZl -irr0 xcfun_id eqxx => ->.
+by rewrite (negPf nz_j).
+Qed.
+
+Definition Res_Iirr (A B : {set gT}) i := cfIirr ('Res[B, A] 'chi_i).
+
+Lemma Res_Iirr0 : Res_Iirr H (0 : Iirr G) = 0.
+Proof. by rewrite /Res_Iirr irr0 rmorph1 -irr0 irrK. Qed.
+
+Lemma lin_Res_IirrE i : 'chi[G]_i 1%g = 1 -> 'chi_(Res_Iirr H i) = 'Res 'chi_i.
+Proof.
+move=> chi1; rewrite cfIirrE ?lin_char_irr ?cfRes_lin_char //.
+by rewrite qualifE irr_char /= chi1.
+Qed.
+
+End Restrict.
+
+Arguments Scope Res_Iirr [_ group_scope group_scope ring_scope].
+
+Section MoreConstt.
+
+Variables (gT : finGroupType) (G H : {group gT}).
+
+Lemma constt_Ind_Res i j :
+ i \in irr_constt ('Ind[G] 'chi_j) = (j \in irr_constt ('Res[H] 'chi_i)).
+Proof. by rewrite !irr_consttE cfdotC conjC_eq0 -cfdot_Res_l. Qed.
+
+Lemma cfdot_Res_ge_constt i j psi :
+ psi \is a character -> j \in irr_constt psi ->
+ '['Res[H, G] 'chi_j, 'chi_i] <= '['Res[H] psi, 'chi_i].
+Proof.
+move=> {psi} _ /constt_charP[// | psi Npsi ->].
+rewrite linearD cfdotDl addrC -subr_ge0 addrK Cnat_ge0 //=.
+by rewrite Cnat_cfdot_char_irr // cfRes_char.
+Qed.
+
+Lemma constt_Res_trans j psi :
+ psi \is a character -> j \in irr_constt psi ->
+ {subset irr_constt ('Res[H, G] 'chi_j) <= irr_constt ('Res[H] psi)}.
+Proof.
+move=> Npsi Cj i; apply: contraNneq; rewrite eqr_le => {1}<-.
+rewrite cfdot_Res_ge_constt ?Cnat_ge0 ?Cnat_cfdot_char_irr //.
+by rewrite cfRes_char ?irr_char.
+Qed.
+
+End MoreConstt.
+
+Section Morphim.
+
+Variables (aT rT : finGroupType) (G D : {group aT}) (f : {morphism D >-> rT}).
+Implicit Type chi : 'CF(f @* G).
+
+Lemma cfRepr_morphim n (rfG : mx_representation algCF (f @* G) n) sGD :
+ cfRepr (morphim_repr rfG sGD) = cfMorph (cfRepr rfG).
+Proof.
+apply/cfun_inP=> x Gx; have Dx: x \in D := subsetP sGD x Gx.
+by rewrite cfMorphE // !cfunE ?mem_morphim ?Gx.
+Qed.
+
+Lemma cfMorph_char chi : chi \is a character -> cfMorph chi \is a character.
+Proof.
+have [sGD /char_reprP[rfG ->] | outGD Nchi] := boolP (G \subset D); last first.
+ by rewrite cfMorphEout // rpredZ_Cnat ?rpred1 ?Cnat_char1.
+apply/char_reprP; exists (Representation (morphim_repr rfG sGD)).
+by rewrite cfRepr_morphim.
+Qed.
+
+Lemma cfMorph_lin_char chi :
+ chi \is a linear_char -> cfMorph chi \is a linear_char.
+Proof. by case/andP=> Nchi; rewrite qualifE cfMorph1 cfMorph_char. Qed.
+
+Lemma cfMorph_charE chi :
+ G \subset D -> (cfMorph chi \is a character) = (chi \is a character).
+Proof.
+move=> sGD; apply/idP/idP=> [/char_reprP[[n rG] /=Dfchi] | /cfMorph_char//].
+pose H := 'ker_G f; have kerH: H \subset rker rG.
+ by rewrite -cfker_repr -Dfchi cfker_morph // setIS // ker_sub_pre.
+have nHG: G \subset 'N(H) by rewrite normsI // (subset_trans sGD) ?ker_norm.
+have [h injh im_h] := first_isom_loc f sGD; rewrite -/H in h injh im_h.
+have DfG: invm injh @*^-1 (G / H) == (f @* G)%g by rewrite morphpre_invm im_h.
+pose rfG := eqg_repr (morphpre_repr _ (quo_repr kerH nHG)) DfG.
+apply/char_reprP; exists (Representation rfG).
+apply/cfun_inP=> _ /morphimP[x Dx Gx ->]; rewrite -cfMorphE // Dfchi !cfunE Gx.
+pose xH := coset H x; have GxH: xH \in (G / H)%g by apply: mem_quotient.
+suffices Dfx: f x = h xH by rewrite mem_morphim //= Dfx invmE ?quo_repr_coset.
+by apply/set1_inj; rewrite -?morphim_set1 ?im_h ?(subsetP nHG) ?sub1set.
+Qed.
+
+Lemma cfMorph_lin_charE chi :
+ G \subset D -> (cfMorph chi \is a linear_char) = (chi \is a linear_char).
+Proof. by rewrite qualifE cfMorph1 => /cfMorph_charE->. Qed.
+
+Lemma cfMorph_irr chi :
+ G \subset D -> (cfMorph chi \in irr G) = (chi \in irr (f @* G)).
+Proof. by move=> sGD; rewrite !irrEchar cfMorph_charE // cfMorph_iso. Qed.
+
+Definition morph_Iirr i := cfIirr (cfMorph 'chi[f @* G]_i).
+
+Lemma morph_Iirr0 : morph_Iirr 0 = 0.
+Proof. by rewrite /morph_Iirr irr0 rmorph1 -irr0 irrK. Qed.
+
+Hypothesis sGD : G \subset D.
+
+Lemma morph_IirrE i : 'chi_(morph_Iirr i) = cfMorph 'chi_i.
+Proof. by rewrite cfIirrE ?cfMorph_irr ?mem_irr. Qed.
+
+Lemma morph_Iirr_inj : injective morph_Iirr.
+Proof.
+by move=> i j eq_ij; apply/irr_inj/cfMorph_inj; rewrite // -!morph_IirrE eq_ij.
+Qed.
+
+Lemma morph_Iirr_eq0 i : (morph_Iirr i == 0) = (i == 0).
+Proof. by rewrite -!irr_eq1 morph_IirrE cfMorph_eq1. Qed.
+
+End Morphim.
+
+Section Isom.
+
+Variables (aT rT : finGroupType) (G : {group aT}) (f : {morphism G >-> rT}).
+Variables (R : {group rT}) (isoGR : isom G R f).
+Implicit Type chi : 'CF(G).
+
+Lemma cfIsom_char chi :
+ (cfIsom isoGR chi \is a character) = (chi \is a character).
+Proof.
+rewrite [cfIsom _]locked_withE cfMorph_charE //.
+by rewrite (isom_im (isom_sym _)) cfRes_id.
+Qed.
+
+Lemma cfIsom_lin_char chi :
+ (cfIsom isoGR chi \is a linear_char) = (chi \is a linear_char).
+Proof. by rewrite qualifE cfIsom_char cfIsom1. Qed.
+
+Lemma cfIsom_irr chi : (cfIsom isoGR chi \in irr R) = (chi \in irr G).
+Proof. by rewrite !irrEchar cfIsom_char cfIsom_iso. Qed.
+
+Definition isom_Iirr i := cfIirr (cfIsom isoGR 'chi_i).
+
+Lemma isom_IirrE i : 'chi_(isom_Iirr i) = cfIsom isoGR 'chi_i.
+Proof. by rewrite cfIirrE ?cfIsom_irr ?mem_irr. Qed.
+
+Lemma isom_Iirr_inj : injective isom_Iirr.
+Proof.
+by move=> i j eqij; apply/irr_inj/(cfIsom_inj isoGR); rewrite -!isom_IirrE eqij.
+Qed.
+
+Lemma isom_Iirr_eq0 i : (isom_Iirr i == 0) = (i == 0).
+Proof. by rewrite -!irr_eq1 isom_IirrE cfIsom_eq1. Qed.
+
+Lemma isom_Iirr0 : isom_Iirr 0 = 0.
+Proof. by apply/eqP; rewrite isom_Iirr_eq0. Qed.
+
+End Isom.
+
+Implicit Arguments isom_Iirr_inj [aT rT G f R x1 x2].
+
+Section IsomInv.
+
+Variables (aT rT : finGroupType) (G : {group aT}) (f : {morphism G >-> rT}).
+Variables (R : {group rT}) (isoGR : isom G R f).
+
+Lemma isom_IirrK : cancel (isom_Iirr isoGR) (isom_Iirr (isom_sym isoGR)).
+Proof. by move=> i; apply: irr_inj; rewrite !isom_IirrE cfIsomK. Qed.
+
+Lemma isom_IirrKV : cancel (isom_Iirr (isom_sym isoGR)) (isom_Iirr isoGR).
+Proof. by move=> i; apply: irr_inj; rewrite !isom_IirrE cfIsomKV. Qed.
+
+End IsomInv.
+
Section Sdprod.
Variables (gT : finGroupType) (K H G : {group gT}).
Hypothesis defG : K ><| H = G.
+Let nKG: G \subset 'N(K). Proof. by have [/andP[]] := sdprod_context defG. Qed.
Lemma cfSdprod_char chi :
- chi \is a character -> cfSdprod defG chi \is a character.
-Proof. by move=> Nchi; rewrite unlock cfMorph_char ?cfIsom_char. Qed.
+ (cfSdprod defG chi \is a character) = (chi \is a character).
+Proof. by rewrite unlock cfMorph_charE // cfIsom_char. Qed.
Lemma cfSdprod_lin_char chi :
- chi \is a linear_char -> cfSdprod defG chi \is a linear_char.
-Proof. by move=> Nphi; rewrite unlock cfMorph_lin_char ?cfIsom_lin_char. Qed.
+ (cfSdprod defG chi \is a linear_char) = (chi \is a linear_char).
+Proof. by rewrite qualifE cfSdprod_char cfSdprod1. Qed.
-Lemma cfSdprod_irr chi : chi \in irr H -> cfSdprod defG chi \in irr G.
-Proof.
-have [/andP[_ nKG] _ _ _ _] := sdprod_context defG.
-by move=> Nphi; rewrite unlock cfMorph_irr ?cfIsom_irr.
-Qed.
+Lemma cfSdprod_irr chi : (cfSdprod defG chi \in irr G) = (chi \in irr H).
+Proof. by rewrite !irrEchar cfSdprod_char cfSdprod_iso. Qed.
Definition sdprod_Iirr j := cfIirr (cfSdprod defG 'chi_j).
@@ -1707,17 +1951,17 @@ Lemma cfDprodKr_abelian i : abelian K -> cancel (cfDprod KxH 'chi_i) 'Res.
Proof. by move=> cKK; apply: cfDprodKr; apply/lin_char1/char_abelianP. Qed.
Lemma cfDprodl_char phi :
- phi \is a character -> cfDprodl KxH phi \is a character.
+ (cfDprodl KxH phi \is a character) = (phi \is a character).
Proof. exact: cfSdprod_char. Qed.
Lemma cfDprodr_char psi :
- psi \is a character -> cfDprodr KxH psi \is a character.
+ (cfDprodr KxH psi \is a character) = (psi \is a character).
Proof. exact: cfSdprod_char. Qed.
Lemma cfDprod_char phi psi :
phi \is a character -> psi \is a character ->
cfDprod KxH phi psi \is a character.
-Proof. by move=> /cfDprodl_char Nphi /cfDprodr_char; apply: rpredM. Qed.
+Proof. by move=> Nphi Npsi; rewrite rpredM ?cfDprodl_char ?cfDprodr_char. Qed.
Lemma cfDprod_eq1 phi psi :
phi \is a character -> psi \is a character ->
@@ -1732,22 +1976,22 @@ by rewrite !rmorph1.
Qed.
Lemma cfDprodl_lin_char phi :
- phi \is a linear_char -> cfDprodl KxH phi \is a linear_char.
+ (cfDprodl KxH phi \is a linear_char) = (phi \is a linear_char).
Proof. exact: cfSdprod_lin_char. Qed.
Lemma cfDprodr_lin_char psi :
- psi \is a linear_char -> cfDprodr KxH psi \is a linear_char.
+ (cfDprodr KxH psi \is a linear_char) = (psi \is a linear_char).
Proof. exact: cfSdprod_lin_char. Qed.
Lemma cfDprod_lin_char phi psi :
phi \is a linear_char -> psi \is a linear_char ->
cfDprod KxH phi psi \is a linear_char.
-Proof. by move=> /cfDprodl_lin_char Lphi /cfDprodr_lin_char; apply: rpredM. Qed.
+Proof. by move=> Nphi Npsi; rewrite rpredM ?cfSdprod_lin_char. Qed.
-Lemma cfDprodl_irr chi : chi \in irr K -> cfDprodl KxH chi \in irr G.
+Lemma cfDprodl_irr chi : (cfDprodl KxH chi \in irr G) = (chi \in irr K).
Proof. exact: cfSdprod_irr. Qed.
-Lemma cfDprodr_irr chi : chi \in irr H -> cfDprodr KxH chi \in irr G.
+Lemma cfDprodr_irr chi : (cfDprodr KxH chi \in irr G) = (chi \in irr H).
Proof. exact: cfSdprod_irr. Qed.
Definition dprodl_Iirr i := cfIirr (cfDprodl KxH 'chi_i).
@@ -1834,10 +2078,10 @@ Qed.
Definition inv_dprod_Iirr i := iinv (dprod_Iirr_onto i).
Lemma dprod_IirrK : cancel dprod_Iirr inv_dprod_Iirr.
-Proof. by move=> p; exact: (iinv_f dprod_Iirr_inj). Qed.
+Proof. by move=> p; apply: (iinv_f dprod_Iirr_inj). Qed.
Lemma inv_dprod_IirrK : cancel inv_dprod_Iirr dprod_Iirr.
-Proof. by move=> i; exact: f_iinv. Qed.
+Proof. by move=> i; apply: f_iinv. Qed.
Lemma inv_dprod_Iirr0 : inv_dprod_Iirr 0 = (0, 0).
Proof. by apply/(canLR dprod_IirrK); rewrite dprod_Iirr0. Qed.
@@ -1862,7 +2106,11 @@ Proof. by move=> Pi; rewrite -(bigdprodWY defG) (bigD1 i) ?joing_subl. Qed.
Lemma cfBigdprodi_char i (phi : 'CF(A i)) :
phi \is a character -> cfBigdprodi defG phi \is a character.
-Proof. by move=> Nphi; rewrite cfDprodl_char ?cfRes_char. Qed.
+Proof. by move=> Nphi; rewrite cfDprodl_char cfRes_char. Qed.
+
+Lemma cfBigdprodi_charE i (phi : 'CF(A i)) :
+ P i -> (cfBigdprodi defG phi \is a character) = (phi \is a character).
+Proof. by move=> Pi; rewrite cfDprodl_char Pi cfRes_id. Qed.
Lemma cfBigdprod_char phi :
(forall i, P i -> phi i \is a character) ->
@@ -1875,6 +2123,10 @@ Lemma cfBigdprodi_lin_char i (phi : 'CF(A i)) :
phi \is a linear_char -> cfBigdprodi defG phi \is a linear_char.
Proof. by move=> Lphi; rewrite cfDprodl_lin_char ?cfRes_lin_char. Qed.
+Lemma cfBigdprodi_lin_charE i (phi : 'CF(A i)) :
+ P i -> (cfBigdprodi defG phi \is a linear_char) = (phi \is a linear_char).
+Proof. by move=> Pi; rewrite qualifE cfBigdprodi_charE // cfBigdprodi1. Qed.
+
Lemma cfBigdprod_lin_char phi :
(forall i, P i -> phi i \is a linear_char) ->
cfBigdprod defG phi \is a linear_char.
@@ -1883,8 +2135,8 @@ by move=> Lphi; apply/rpred_prod=> i /Lphi; apply: cfBigdprodi_lin_char.
Qed.
Lemma cfBigdprodi_irr i chi :
- P i -> chi \in irr (A i) -> cfBigdprodi defG chi \in irr G.
-Proof. by move=> Pi Nchi; rewrite cfDprodl_irr // Pi cfRes_id. Qed.
+ P i -> (cfBigdprodi defG chi \in irr G) = (chi \in irr (A i)).
+Proof. by move=> Pi; rewrite !irrEchar cfBigdprodi_charE ?cfBigdprodi_iso. Qed.
Lemma cfBigdprod_irr chi :
(forall i, P i -> chi i \in irr (A i)) -> cfBigdprod defG chi \in irr G.
@@ -1946,7 +2198,7 @@ Lemma conjC_charAut u (chi : 'CF(G)) x :
Proof.
have [Gx | /cfun0->] := boolP (x \in G); last by rewrite !rmorph0.
case/char_reprP=> rG ->; have [e [_ [en1 _] [-> _] _]] := repr_rsim_diag rG Gx.
-by rewrite !rmorph_sum; apply: eq_bigr => i _; exact: aut_unity_rootC (en1 i).
+by rewrite !rmorph_sum; apply: eq_bigr => i _; apply: aut_unity_rootC (en1 i).
Qed.
Lemma conjC_irrAut u i x : (u ('chi[G]_i x))^* = u ('chi_i x)^*.
@@ -1960,17 +2212,17 @@ Lemma cfdot_aut_irr u phi i :
'[cfAut u phi, cfAut u 'chi[G]_i] = u '[phi, 'chi_i].
Proof. exact: cfdot_aut_char (irr_char i). Qed.
-Lemma cfAut_irr u chi : chi \in irr G -> cfAut u chi \in irr G.
+Lemma cfAut_irr u chi : (cfAut u chi \in irr G) = (chi \in irr G).
Proof.
-case/irrP=> i ->; rewrite irrEchar cfAut_char ?irr_char //=.
-by rewrite cfdot_aut_irr // cfdot_irr eqxx rmorph1.
+rewrite !irrEchar cfAut_char; apply/andb_id2l=> /cfdot_aut_char->.
+exact: fmorph_eq1.
Qed.
Lemma cfConjC_irr i : (('chi_i)^*)%CF \in irr G.
-Proof. by rewrite cfAut_irr ?mem_irr. Qed.
+Proof. by rewrite cfAut_irr mem_irr. Qed.
Lemma irr_aut_closed u : cfAut_closed u (irr G).
-Proof. exact: cfAut_irr. Qed.
+Proof. by move=> chi; rewrite /= cfAut_irr. Qed.
Definition aut_Iirr u i := cfIirr (cfAut u 'chi[G]_i).
@@ -2002,255 +2254,10 @@ Proof.
by move=> i j eq_ij; apply/irr_inj/(cfAut_inj u); rewrite -!aut_IirrE eq_ij.
Qed.
-Lemma char_aut u (chi : 'CF(G)) :
- (cfAut u chi \is a character) = (chi \is a character).
-Proof.
-apply/idP/idP=> [Nuchi|]; last exact: cfAut_char.
-rewrite [chi]cfun_sum_cfdot rpred_sum // => i _.
-rewrite rpredZ_Cnat ?irr_char // -(Cnat_aut u) -cfdot_aut_irr.
-by rewrite -aut_IirrE Cnat_cfdot_char_irr.
-Qed.
-
-Lemma irr_aut u chi : (cfAut u chi \in irr G) = (chi \in irr G).
-Proof.
-rewrite !irrEchar char_aut; apply/andb_id2l=> /cfdot_aut_char->.
-by rewrite fmorph_eq1.
-Qed.
-
End Aut.
-Section IrrConstt.
-
-Variable (gT : finGroupType) (G H : {group gT}).
-
-Lemma char1_ge_norm (chi : 'CF(G)) x :
- chi \is a character -> `|chi x| <= chi 1%g.
-Proof.
-case/char_reprP=> rG ->; case Gx: (x \in G); last first.
- by rewrite cfunE cfRepr1 Gx normr0 ler0n.
-by have [e [_ _ []]] := repr_rsim_diag rG Gx.
-Qed.
-
-Lemma max_cfRepr_norm_scalar n (rG : mx_representation algCF G n) x :
- x \in G -> `|cfRepr rG x| = cfRepr rG 1%g ->
- exists2 c, `|c| = 1 & rG x = c%:M.
-Proof.
-move=> Gx; have [e [[B uB def_x] [_ e1] [-> _] _]] := repr_rsim_diag rG Gx.
-rewrite cfRepr1 -[n in n%:R]card_ord -sumr_const -(eq_bigr _ (in1W e1)).
-case/normC_sum_eq1=> [i _ | c /eqP norm_c_1 def_e]; first by rewrite e1.
-have{def_e} def_e: e = const_mx c by apply/rowP=> i; rewrite mxE def_e ?andbT.
-by exists c => //; rewrite def_x def_e diag_const_mx scalar_mxC mulmxKV.
-Qed.
-
-Lemma max_cfRepr_mx1 n (rG : mx_representation algCF G n) x :
- x \in G -> cfRepr rG x = cfRepr rG 1%g -> rG x = 1%:M.
-Proof.
-move=> Gx kerGx; have [|c _ def_x] := @max_cfRepr_norm_scalar n rG x Gx.
- by rewrite kerGx cfRepr1 normr_nat.
-move/eqP: kerGx; rewrite cfRepr1 cfunE Gx {rG}def_x mxtrace_scalar.
-case: n => [_|n]; first by rewrite ![_%:M]flatmx0.
-rewrite mulrb -subr_eq0 -mulrnBl -mulr_natl mulf_eq0 pnatr_eq0 /=.
-by rewrite subr_eq0 => /eqP->.
-Qed.
-
-Definition irr_constt (B : {set gT}) phi := [pred i | '[phi, 'chi_i]_B != 0].
-
-Lemma irr_consttE i phi : (i \in irr_constt phi) = ('[phi, 'chi_i]_G != 0).
-Proof. by []. Qed.
-
-Lemma constt_charP (i : Iirr G) chi :
- chi \is a character ->
- reflect (exists2 chi', chi' \is a character & chi = 'chi_i + chi')
- (i \in irr_constt chi).
-Proof.
-move=> Nchi; apply: (iffP idP) => [i_in_chi| [chi' Nchi' ->]]; last first.
- rewrite inE /= cfdotDl cfdot_irr eqxx -(eqP (Cnat_cfdot_char_irr i Nchi')).
- by rewrite -natrD pnatr_eq0.
-exists (chi - 'chi_i); last by rewrite addrC subrK.
-apply/forallP=> j; rewrite coord_cfdot cfdotBl cfdot_irr.
-have [<- | _] := eqP; last by rewrite subr0 Cnat_cfdot_char_irr.
-have := i_in_chi; rewrite inE /= -(eqP (Cnat_cfdot_char_irr i Nchi)) pnatr_eq0.
-by case: (truncC _) => // n _; rewrite mulrSr addrK ?isNatC_nat.
-Qed.
-
-Lemma cfun_sum_constt (phi : 'CF(G)) :
- phi = \sum_(i in irr_constt phi) '[phi, 'chi_i] *: 'chi_i.
-Proof.
-rewrite {1}[phi]cfun_sum_cfdot (bigID [pred i | '[phi, 'chi_i] == 0]) /=.
-by rewrite big1 ?add0r // => i /eqP->; rewrite scale0r.
-Qed.
-
-Lemma neq0_has_constt (phi : 'CF(G)) :
- phi != 0 -> exists i, i \in irr_constt phi.
-Proof.
-move=> nz_phi; apply/existsP; apply: contra nz_phi => /pred0P phi0.
-by rewrite [phi]cfun_sum_constt big_pred0.
-Qed.
-
-Lemma constt_irr i : irr_constt 'chi[G]_i =i pred1 i.
-Proof.
-by move=> j; rewrite !inE cfdot_irr pnatr_eq0 (eq_sym j); case: (i == j).
-Qed.
-
-Lemma char1_ge_constt (i : Iirr G) chi :
- chi \is a character -> i \in irr_constt chi -> 'chi_i 1%g <= chi 1%g.
-Proof.
-move=> {chi} _ /constt_charP[// | chi Nchi ->].
-by rewrite cfunE addrC -subr_ge0 addrK char1_ge0.
-Qed.
-
-Lemma constt_ortho_char (phi psi : 'CF(G)) i j :
- phi \is a character -> psi \is a character ->
- i \in irr_constt phi -> j \in irr_constt psi ->
- '[phi, psi] = 0 -> '['chi_i, 'chi_j] = 0.
-Proof.
-move=> _ _ /constt_charP[//|phi1 Nphi1 ->] /constt_charP[//|psi1 Npsi1 ->].
-rewrite cfdot_irr; case: eqP => // -> /eqP/idPn[].
-rewrite cfdotDl !cfdotDr cfnorm_irr -addrA gtr_eqF ?ltr_paddr ?ltr01 //.
-by rewrite Cnat_ge0 ?rpredD ?Cnat_cfdot_char ?irr_char.
-Qed.
-
-End IrrConstt.
-
-Arguments Scope irr_constt [_ group_scope cfun_scope].
Implicit Arguments aut_Iirr_inj [gT G x1 x2].
-Section MoreConstt.
-
-Variables (gT : finGroupType) (G H : {group gT}).
-
-Lemma constt_Ind_Res i j :
- i \in irr_constt ('Ind[G] 'chi_j) = (j \in irr_constt ('Res[H] 'chi_i)).
-Proof. by rewrite !irr_consttE cfdotC conjC_eq0 -cfdot_Res_l. Qed.
-
-Lemma cfdot_Res_ge_constt i j psi :
- psi \is a character -> j \in irr_constt psi ->
- '['Res[H, G] 'chi_j, 'chi_i] <= '['Res[H] psi, 'chi_i].
-Proof.
-move=> {psi} _ /constt_charP[// | psi Npsi ->].
-rewrite linearD cfdotDl addrC -subr_ge0 addrK Cnat_ge0 //=.
-by rewrite Cnat_cfdot_char_irr // cfRes_char.
-Qed.
-
-Lemma constt_Res_trans j psi :
- psi \is a character -> j \in irr_constt psi ->
- {subset irr_constt ('Res[H, G] 'chi_j) <= irr_constt ('Res[H] psi)}.
-Proof.
-move=> Npsi Cj i; apply: contraNneq; rewrite eqr_le => {1}<-.
-rewrite cfdot_Res_ge_constt ?Cnat_ge0 ?Cnat_cfdot_char_irr //.
-by rewrite cfRes_char ?irr_char.
-Qed.
-
-End MoreConstt.
-
-Section Kernel.
-
-Variable (gT : finGroupType) (G : {group gT}).
-Implicit Types (phi chi xi : 'CF(G)) (H : {group gT}).
-
-Lemma cfker_repr n (rG : mx_representation algCF G n) :
- cfker (cfRepr rG) = rker rG.
-Proof.
-apply/esym/setP=> x; rewrite inE mul1mx /=.
-case Gx: (x \in G); last by rewrite inE Gx.
-apply/eqP/idP=> Kx; last by rewrite max_cfRepr_mx1 // cfker1.
-rewrite inE Gx; apply/forallP=> y; rewrite !cfunE !mulrb groupMl //.
-by case: ifP => // Gy; rewrite repr_mxM // Kx mul1mx.
-Qed.
-
-Lemma cfkerEchar chi :
- chi \is a character -> cfker chi = [set x in G | chi x == chi 1%g].
-Proof.
-move=> Nchi; apply/setP=> x; apply/idP/setIdP=> [Kx | [Gx /eqP chi_x]].
- by rewrite (subsetP (cfker_sub chi)) // cfker1.
-case/char_reprP: Nchi => rG -> in chi_x *; rewrite inE Gx; apply/forallP=> y.
-rewrite !cfunE groupMl // !mulrb; case: ifP => // Gy.
-by rewrite repr_mxM // max_cfRepr_mx1 ?mul1mx.
-Qed.
-
-Lemma cfker_nzcharE chi :
- chi \is a character -> chi != 0 -> cfker chi = [set x | chi x == chi 1%g].
-Proof.
-move=> Nchi nzchi; apply/setP=> x; rewrite cfkerEchar // !inE andb_idl //.
-by apply: contraLR => /cfun0-> //; rewrite eq_sym char1_eq0.
-Qed.
-
-Lemma cfkerEirr i : cfker 'chi[G]_i = [set x | 'chi_i x == 'chi_i 1%g].
-Proof. by rewrite cfker_nzcharE ?irr_char ?irr_neq0. Qed.
-
-Lemma cfker_irr0 : cfker 'chi[G]_0 = G.
-Proof. by rewrite irr0 cfker_cfun1. Qed.
-
-Lemma cfaithful_reg : cfaithful (cfReg G).
-Proof.
-apply/subsetP=> x; rewrite cfkerEchar ?cfReg_char // !inE !cfRegE eqxx.
-by case/andP=> _; apply: contraLR => /negbTE->; rewrite eq_sym neq0CG.
-Qed.
-
-Lemma cfkerE chi :
- chi \is a character ->
- cfker chi = G :&: \bigcap_(i in irr_constt chi) cfker 'chi_i.
-Proof.
-move=> Nchi; rewrite cfkerEchar //; apply/setP=> x; rewrite !inE.
-apply: andb_id2l => Gx; rewrite {1 2}[chi]cfun_sum_constt !sum_cfunE.
-apply/eqP/bigcapP=> [Kx i Ci | Kx]; last first.
- by apply: eq_bigr => i /Kx Kx_i; rewrite !cfunE cfker1.
-rewrite cfkerEirr inE /= -(inj_eq (mulfI Ci)).
-have:= (normC_sum_upper _ Kx) i; rewrite !cfunE => -> // {i Ci} i _.
-have chi_i_ge0: 0 <= '[chi, 'chi_i].
- by rewrite Cnat_ge0 ?Cnat_cfdot_char_irr.
-by rewrite !cfunE normrM (normr_idP _) ?ler_wpmul2l ?char1_ge_norm ?irr_char.
-Qed.
-
-Lemma TI_cfker_irr : \bigcap_i cfker 'chi[G]_i = [1].
-Proof.
-apply/trivgP; apply: subset_trans cfaithful_reg; rewrite cfkerE ?cfReg_char //.
-rewrite subsetI (bigcap_min 0) //=; last by rewrite cfker_irr0.
-by apply/bigcapsP=> i _; rewrite bigcap_inf.
-Qed.
-
-Lemma cfker_constt i chi :
- chi \is a character -> i \in irr_constt chi ->
- cfker chi \subset cfker 'chi[G]_i.
-Proof. by move=> Nchi Ci; rewrite cfkerE ?subIset ?(bigcap_min i) ?orbT. Qed.
-
-Section KerLin.
-
-Variable xi : 'CF(G).
-Hypothesis lin_xi : xi \is a linear_char.
-Let Nxi: xi \is a character. Proof. by have [] := andP lin_xi. Qed.
-
-Lemma lin_char_der1 : G^`(1)%g \subset cfker xi.
-Proof.
-rewrite gen_subG /=; apply/subsetP=> _ /imset2P[x y Gx Gy ->].
-rewrite cfkerEchar // inE groupR //= !lin_charM ?lin_charV ?in_group //.
-by rewrite mulrCA mulKf ?mulVf ?lin_char_neq0 // lin_char1.
-Qed.
-
-Lemma cforder_lin_char : #[xi]%CF = exponent (G / cfker xi)%g.
-Proof.
-apply/eqP; rewrite eqn_dvd; apply/andP; split.
- apply/dvdn_cforderP=> x Gx; rewrite -lin_charX // -cfQuoEker ?groupX //.
- rewrite morphX ?(subsetP (cfker_norm xi)) //= expg_exponent ?mem_quotient //.
- by rewrite cfQuo1 ?cfker_normal ?lin_char1.
-have abGbar: abelian (G / cfker xi) := sub_der1_abelian lin_char_der1.
-have [_ /morphimP[x Nx Gx ->] ->] := exponent_witness (abelian_nil abGbar).
-rewrite order_dvdn -morphX //= coset_id cfkerEchar // !inE groupX //=.
-by rewrite lin_charX ?lin_char1 // (dvdn_cforderP _ _ _).
-Qed.
-
-Lemma cforder_lin_char_dvdG : #[xi]%CF %| #|G|.
-Proof.
-by rewrite cforder_lin_char (dvdn_trans (exponent_dvdn _)) ?dvdn_morphim.
-Qed.
-
-Lemma cforder_lin_char_gt0 : (0 < #[xi]%CF)%N.
-Proof. by rewrite cforder_lin_char exponent_gt0. Qed.
-
-End KerLin.
-
-End Kernel.
-
Section Coset.
Variable (gT : finGroupType).
@@ -2260,27 +2267,18 @@ Implicit Types G H : {group gT}.
Lemma cfQuo_char G H (chi : 'CF(G)) :
chi \is a character -> (chi / H)%CF \is a character.
Proof.
-move=> Nchi; case KchiH: (H \subset cfker chi); last first.
+move=> Nchi; without loss kerH: / H \subset cfker chi.
+ move/contraNF=> IHchi; apply/wlog_neg=> N'chiH.
suffices ->: (chi / H)%CF = (chi 1%g)%:A.
by rewrite rpredZ_Cnat ?Cnat_char1 ?rpred1.
- by apply/cfunP=> x; rewrite cfunE cfun1E mulr_natr cfunElock KchiH.
-have sHG := subset_trans KchiH (cfker_sub _).
-pose N := 'N_G(H); pose phi := 'Res[N] chi.
-have nsHN: H <| N by [rewrite normal_subnorm]; have [sHN nHN] := andP nsHN.
-have{Nchi} Nphi: phi \is a character by apply: cfRes_char.
-have KphiH: H \subset cfker phi.
- apply/subsetP=> x Hx; have [Kx Nx] := (subsetP KchiH x Hx, subsetP sHN x Hx).
- by rewrite cfkerEchar // inE Nx cfRes1 cfResE ?subsetIl //= cfker1.
-pose psi := 'Res[(N / H)%g] (chi / H)%CF.
-have ->: (chi / H)%CF = 'Res psi by rewrite /psi quotientInorm !cfRes_id.
-have{KchiH} ->: psi = (phi / H)%CF.
- apply/cfun_inP => _ /morphimP[x nHx Nx ->]; have [Gx _] := setIP Nx.
- rewrite cfResE ?mem_quotient ?quotientS ?subsetIl // cfQuoEnorm //.
- by rewrite cfQuoE ?cfResE ?subsetIl.
-have [rG Dphi] := char_reprP Nphi; rewrite {phi Nphi}Dphi cfker_repr in KphiH *.
-apply/cfRes_char/char_reprP; exists (Representation (quo_repr KphiH nHN)).
-apply/cfun_inP=> _ /morphimP[x nHx Nx ->]; rewrite cfQuoE ?cfker_repr //=.
-by rewrite !cfunE Nx quo_repr_coset ?mem_quotient.
+ by apply/cfunP=> x; rewrite cfunE cfun1E mulr_natr cfunElock IHchi.
+without loss nsHG: G chi Nchi kerH / H <| G.
+ move=> IHchi; have nsHN := normalSG (subset_trans kerH (cfker_sub chi)).
+ by rewrite cfQuoInorm ?(cfRes_char, IHchi) ?sub_cfker_Res // ?normal_sub.
+have [rG Dchi] := char_reprP Nchi; rewrite Dchi cfker_repr in kerH.
+apply/char_reprP; exists (Representation (quo_repr kerH (normal_norm nsHG))).
+apply/cfun_inP=> _ /morphimP[x nHx Gx ->]; rewrite Dchi cfQuoE ?cfker_repr //=.
+by rewrite !cfunE Gx quo_repr_coset ?mem_quotient.
Qed.
Lemma cfQuo_lin_char G H (chi : 'CF(G)) :
@@ -2295,8 +2293,26 @@ Lemma cfMod_lin_char G H (chi : 'CF(G / H)) :
chi \is a linear_char -> (chi %% H)%CF \is a linear_char.
Proof. exact: cfMorph_lin_char. Qed.
+Lemma cfMod_charE G H (chi : 'CF(G / H)) :
+ H <| G -> (chi %% H \is a character)%CF = (chi \is a character).
+Proof. by case/andP=> _; apply: cfMorph_charE. Qed.
+
+Lemma cfMod_lin_charE G H (chi : 'CF(G / H)) :
+ H <| G -> (chi %% H \is a linear_char)%CF = (chi \is a linear_char).
+Proof. by case/andP=> _; apply: cfMorph_lin_charE. Qed.
+
+Lemma cfQuo_charE G H (chi : 'CF(G)) :
+ H <| G -> H \subset cfker chi ->
+ (chi / H \is a character)%CF = (chi \is a character).
+Proof. by move=> nsHG kerH; rewrite -cfMod_charE ?cfQuoK. Qed.
+
+Lemma cfQuo_lin_charE G H (chi : 'CF(G)) :
+ H <| G -> H \subset cfker chi ->
+ (chi / H \is a linear_char)%CF = (chi \is a linear_char).
+Proof. by move=> nsHG kerH; rewrite -cfMod_lin_charE ?cfQuoK. Qed.
+
Lemma cfMod_irr G H chi :
- H <| G -> chi \in irr (G / H) -> (chi %% H)%CF \in irr G.
+ H <| G -> (chi %% H \in irr G)%CF = (chi \in irr (G / H)).
Proof. by case/andP=> _; apply: cfMorph_irr. Qed.
Definition mod_Iirr G H i := cfIirr ('chi[G / H]_i %% H)%CF.
@@ -2312,16 +2328,9 @@ Lemma mod_Iirr_eq0 G H i :
Proof. by case/andP=> _ /morph_Iirr_eq0->. Qed.
Lemma cfQuo_irr G H chi :
- H <| G -> H \subset cfker chi -> chi \in irr G ->
- (chi / H)%CF \in irr (G / H).
-Proof.
-move=> nsHG sHK /irr_reprP[rG irrG Dchi]; have [sHG nHG] := andP nsHG.
-have sHKr: H \subset rker rG by rewrite -cfker_repr -Dchi.
-apply/irr_reprP; exists (Representation (quo_repr sHKr nHG)).
- exact/quo_mx_irr.
-apply/cfun_inP=> _ /morphimP[x Nx Gx ->].
-by rewrite cfQuoE //= Dchi !cfunE Gx quo_repr_coset ?mem_quotient.
-Qed.
+ H <| G -> H \subset cfker chi ->
+ ((chi / H)%CF \in irr (G / H)) = (chi \in irr G).
+Proof. by move=> nsHG kerH; rewrite -cfMod_irr ?cfQuoK. Qed.
Definition quo_Iirr G H i := cfIirr ('chi[G]_i / H)%CF.
@@ -2359,7 +2368,7 @@ Qed.
Lemma mod_Iirr_bij H G :
H <| G -> {on [pred i | H \subset cfker 'chi_i], bijective (@mod_Iirr G H)}.
Proof.
-by exists (quo_Iirr H) => [i _ | i]; [exact: mod_IirrK | exact: quo_IirrK].
+by exists (quo_Iirr H) => [i _ | i]; [apply: mod_IirrK | apply: quo_IirrK].
Qed.
Lemma sum_norm_irr_quo H G x :
@@ -2394,7 +2403,7 @@ Qed.
End Coset.
-Section Derive.
+Section DerivedGroup.
Variable gT : finGroupType.
Implicit Types G H : {group gT}.
@@ -2405,7 +2414,7 @@ Proof.
apply/idP/idP=> [|sG'K]; first by apply: lin_char_der1.
have nsG'G: G^`(1) <| G := der_normal 1 G.
rewrite qualifE irr_char -[i](quo_IirrK nsG'G) // mod_IirrE //=.
-by rewrite cfModE // morph1 lin_char1 //; exact/char_abelianP/der_abelian.
+by rewrite cfModE // morph1 lin_char1 //; apply/char_abelianP/der_abelian.
Qed.
Lemma subGcfker G i : (G \subset cfker 'chi[G]_i) = (i == 0).
@@ -2447,7 +2456,7 @@ by apply: eq_card => i; rewrite !inE mod_IirrE ?cfker_mod.
(* Alternative: use the equivalent result in modular representation theory
transitivity #|@socle_of_Iirr _ G @^-1: linear_irr _|; last first.
rewrite (on_card_preimset (socle_of_Iirr_bij _)).
- by rewrite card_linear_irr ?algC'G; last exact: groupC.
+ by rewrite card_linear_irr ?algC'G; last apply: groupC.
by apply: eq_card => i; rewrite !inE /lin_char irr_char irr1_degree -eqC_nat.
*)
Qed.
@@ -2466,7 +2475,7 @@ Qed.
(* A combinatorial group isommorphic to the linear characters. *)
Lemma lin_char_group G :
- {linG : finGroupType & {cF : linG -> 'CF(G) |
+ {linG : finGroupType & {cF : linG -> 'CF(G) |
[/\ injective cF, #|linG| = #|G : G^`(1)|,
forall u, cF u \is a linear_char
& forall phi, phi \is a linear_char -> exists u, phi = cF u]
@@ -2542,7 +2551,7 @@ rewrite (bigID (fun i => H \subset cfker 'chi[G]_i)) //= addrC addKr.
by apply: sumr_ge0 => i _; rewrite normCK mul_conjC_ge0.
Qed.
-End Derive.
+End DerivedGroup.
Implicit Arguments irr_prime_injP [gT G i].
@@ -2789,7 +2798,7 @@ have [-> | nz_chi] := eqVneq chi 0.
by apply/subsetP=> x /setIdP[Gx _]; rewrite inE Gx /= !cfunE.
have [xi Lxi def_chi] := cfcenter_Res chi.
set Z := ('Z(_))%CF in xi Lxi def_chi *.
-have sZG: Z \subset G by exact: cfcenter_sub.
+have sZG: Z \subset G by apply: cfcenter_sub.
have ->: cfker chi = cfker xi.
rewrite -(setIidPr (normal_sub (cfker_center_normal _))) -/Z.
rewrite !cfkerEchar // ?lin_charW //= -/Z.
@@ -2797,7 +2806,7 @@ have ->: cfker chi = cfker xi.
rewrite (subsetP sZG) //= -!(cfResE chi sZG) ?group1 // def_chi !cfunE.
by rewrite (inj_eq (mulfI _)) ?char1_eq0.
have: abelian (Z / cfker xi) by rewrite sub_der1_abelian ?lin_char_der1.
-have [rG irrG ->] := irr_reprP _ (lin_char_irr Lxi); rewrite cfker_repr.
+have /irr_reprP[rG irrG ->] := lin_char_irr Lxi; rewrite cfker_repr.
apply: mx_faithful_irr_abelian_cyclic (kquo_mx_faithful rG) _.
exact/quo_mx_irr.
Qed.
@@ -2824,7 +2833,7 @@ apply/subsetP=> _ /setIP[/morphimP[x /= _ Gx ->] cGx]; rewrite mem_quotient //=.
rewrite -irrRepr cfker_repr cfcenter_repr inE Gx in cGx *.
apply: mx_abs_irr_cent_scalar 'Chi_i _ _ _.
by apply: groupC; apply: socle_irr.
-have nKG: G \subset 'N(rker 'Chi_i) by exact: rker_norm.
+have nKG: G \subset 'N(rker 'Chi_i) by apply: rker_norm.
(* GG -- locking here is critical to prevent Coq kernel divergence. *)
apply/centgmxP=> y Gy; rewrite [eq]lock -2?(quo_repr_coset (subxx _) nKG) //.
move: (quo_repr _ _) => rG; rewrite -2?repr_mxM ?mem_quotient // -lock.
@@ -2915,10 +2924,10 @@ Lemma pgroup_cyclic_faithful (p : nat) :
p.-group G -> cyclic 'Z(G) -> exists i, cfaithful 'chi[G]_i.
Proof.
pose Z := 'Ohm_1('Z(G)) => pG cycZG; have nilG := pgroup_nil pG.
-have [-> | ntG] := eqsVneq G [1]; first by exists 0; exact: cfker_sub.
+have [-> | ntG] := eqsVneq G [1]; first by exists 0; apply: cfker_sub.
have{pG} [[p_pr _ _] pZ] := (pgroup_pdiv pG ntG, pgroupS (center_sub G) pG).
have ntZ: 'Z(G) != [1] by rewrite center_nil_eq1.
-have{pZ} oZ: #|Z| = p by exact: Ohm1_cyclic_pgroup_prime.
+have{pZ} oZ: #|Z| = p by apply: Ohm1_cyclic_pgroup_prime.
apply/existsP; apply: contraR ntZ; rewrite negb_exists => /forallP-not_ffulG.
rewrite -Ohm1_eq1 -subG1 /= -/Z -(TI_cfker_irr G); apply/bigcapsP=> i _.
rewrite prime_meetG ?oZ // setIC meet_Ohm1 // meet_center_nil ?cfker_normal //.
@@ -2973,7 +2982,7 @@ move=> sHG Nchi nzchi; rewrite !cfker_nzcharE ?cfInd_char ?cfInd_eq0 //.
apply/setP=> x; rewrite inE cfIndE // (can2_eq (mulVKf _) (mulKf _)) ?neq0CG //.
rewrite cfInd1 // mulrA -natrM Lagrange // mulr_natl -sumr_const.
apply/eqP/bigcapP=> [/normC_sum_upper ker_chiG_x y Gy | ker_chiG_x].
- by rewrite mem_conjg inE ker_chiG_x ?groupV // => z _; exact: char1_ge_norm.
+ by rewrite mem_conjg inE ker_chiG_x ?groupV // => z _; apply: char1_ge_norm.
by apply: eq_bigr => y /groupVr/ker_chiG_x; rewrite mem_conjgV inE => /eqP.
Qed.
diff --git a/mathcomp/character/classfun.v b/mathcomp/character/classfun.v
index 32eeabb..3b3d894 100644
--- a/mathcomp/character/classfun.v
+++ b/mathcomp/character/classfun.v
@@ -1,25 +1,23 @@
(* (c) Copyright Microsoft Corporation and Inria. All rights reserved. *)
Require Import mathcomp.ssreflect.ssreflect.
-From mathcomp.ssreflect
-Require Import ssreflect ssrbool ssrfun eqtype ssrnat seq.
-From mathcomp.discrete
-Require Import path div choice fintype tuple finfun bigop prime finset.
-From mathcomp.fingroup
-Require Import fingroup morphism perm automorphism quotient action gproduct.
-From mathcomp.algebra
-Require Import ssralg poly finalg zmodp cyclic vector ssrnum matrix vector.
-From mathcomp.solvable
-Require Import commutator center pgroup sylow.
-From mathcomp.field
-Require Import falgebra algC algnum.
+From mathcomp
+Require Import ssrbool ssrfun eqtype ssrnat seq path div choice.
+From mathcomp
+Require Import fintype tuple finfun bigop prime ssralg poly finset.
+From mathcomp
+Require Import fingroup morphism perm automorphism quotient finalg action.
+From mathcomp
+Require Import gproduct zmodp commutator cyclic center pgroup sylow.
+From mathcomp
+Require Import matrix vector falgebra ssrnum algC algnum.
(******************************************************************************)
(* This file contains the basic theory of class functions: *)
(* 'CF(G) == the type of class functions on G : {group gT}, i.e., *)
(* which map gT to the type algC of complex algebraics, *)
(* have support in G, and are constant on each conjugacy *)
-(* class of G. 'CF(G) implements the algebraType interface *)
-(* of finite-dimensional F-algebras. *)
+(* class of G. 'CF(G) implements the FalgType interface of *)
+(* finite-dimensional F-algebras. *)
(* The identity 1 : 'CF(G) is the indicator function of G, *)
(* and (later) the principal character. *)
(* --> The %CF scope (cfun_scope) is bound to the 'CF(_) types. *)
@@ -28,7 +26,7 @@ Require Import falgebra algC algnum.
(* phi x == the image of x : gT under phi : 'CF(G). *)
(* #[phi]%CF == the multiplicative order of phi : 'CF(G). *)
(* cfker phi == the kernel of phi : 'CF(G); note that cfker phi <| G. *)
-(* cfaithful phi <=> phi : 'CF(G) is faithful (has a trivial kernel). *)
+(* cfaithful phi <=> phi : 'CF(G) is faithful (has a trivial kernel). *)
(* '1_A == the indicator function of A as a function of 'CF(G). *)
(* (Provided A <| G; G is determined by the context.) *)
(* phi^*%CF == the function conjugate to phi : 'CF(G). *)
@@ -52,10 +50,10 @@ Require Import falgebra algC algnum.
(* whose range is contained in CR. *)
(* cfReal phi <=> phi is real, i.e., phi^* == phi. *)
(* cfAut_closed u S <-> S : seq 'CF(G) is closed under conjugation by u. *)
-(* conjC_closed S <-> S : seq 'CF(G) is closed under complex conjugation. *)
+(* cfConjC_closed S <-> S : seq 'CF(G) is closed under complex conjugation. *)
(* conjC_subset S1 S2 <-> S1 : seq 'CF(G) represents a subset of S2 closed *)
(* under complex conjugation. *)
-(* := [/\ uniq S1, {subset S1 <= S2} & conjC_closed S1]. *)
+(* := [/\ uniq S1, {subset S1 <= S2} & cfConjC_closed S1]. *)
(* 'Res[H] phi == the restriction of phi : 'CF(G) to a function of 'CF(H) *)
(* 'Res[H, G] phi 'Res[H] phi x = phi x if x \in H (when H \subset G), *)
(* 'Res phi 'Res[H] phi x = 0 if x \notin H. The syntax variants *)
@@ -88,7 +86,7 @@ Require Import falgebra algC algnum.
(* cfBigdprodi defG phi == for phi : 'CF(A i) s.t. P i, the class function *)
(* of 'CF(G) that maps x to phi x_i, where x_i is the *)
(* (A i)-component of x : G. *)
-(* cfBigdprodi defG phi == for phi : forall i, 'CF(A i), the class function *)
+(* cfBigdprod defG phi == for phi : forall i, 'CF(A i), the class function *)
(* of 'CF(G) that maps x to \prod_(i | P i) phi i x_i, *)
(* where x_i is the (A i)-component of x : G. *)
(******************************************************************************)
@@ -181,7 +179,7 @@ Lemma cfunP phi psi : phi =1 psi <-> phi = psi.
Proof. by split=> [/ffunP/val_inj | ->]. Qed.
Lemma cfun0gen phi x : x \notin G -> phi x = 0.
-Proof. by case: phi => f fP; case: (andP fP) => _ /supportP; exact. Qed.
+Proof. by case: phi => f fP; case: (andP fP) => _ /supportP; apply. Qed.
Lemma cfun_in_genP phi psi : {in G, phi =1 psi} -> phi = psi.
Proof.
@@ -335,8 +333,8 @@ Proof. by apply/cfunP=> x; rewrite !cfunE rmorphM. Qed.
Lemma cfAut_is_rmorphism : rmorphism cfAut.
Proof.
-by do 2?split=> [phi psi|]; last exact: cfAut_cfun1i;
- apply/cfunP=> x; rewrite !cfunE (rmorphB, rmorphM).
+by do 2?split=> [phi psi|]; apply/cfunP=> x;
+ rewrite ?cfAut_cfun1i // !cfunE (rmorphB, rmorphM).
Qed.
Canonical cfAut_additive := Additive cfAut_is_rmorphism.
Canonical cfAut_rmorphism := RMorphism cfAut_is_rmorphism.
@@ -409,7 +407,7 @@ Notation "''CF' ( G , A )" := (classfun_on G A) : ring_scope.
Notation "1" := (@GRing.one (cfun_ringType _)) (only parsing) : cfun_scope.
Notation "phi ^*" := (cfAut conjC phi) : cfun_scope.
-Notation conjC_closed := (cfAut_closed conjC).
+Notation cfConjC_closed := (cfAut_closed conjC).
Prenex Implicits cfReal.
(* Workaround for overeager projection reduction. *)
Notation eqcfP := (@eqP (cfun_eqType _) _ _) (only parsing).
@@ -482,7 +480,7 @@ Lemma cfunJ phi x y : y \in G -> phi (x ^ y) = phi x.
Proof. by rewrite -{1}(genGid G) => /(cfunJgen phi)->. Qed.
Lemma cfun_repr phi x : phi (repr (x ^: G)) = phi x.
-Proof. by have [y Gy ->] := repr_class G x; exact: cfunJ. Qed.
+Proof. by have [y Gy ->] := repr_class G x; apply: cfunJ. Qed.
Lemma cfun_inP phi psi : {in G, phi =1 psi} -> phi = psi.
Proof. by rewrite -{1}genGid => /cfun_in_genP. Qed.
@@ -500,7 +498,7 @@ Lemma eq_mul_cfuni A phi : A <| G -> {in A, phi * '1_A =1 phi}.
Proof. by move=> nsAG x Ax; rewrite cfunE cfuniE // Ax mulr1. Qed.
Lemma eq_cfuni A : A <| G -> {in A, '1_A =1 (1 : 'CF(G))}.
-Proof. by rewrite -['1_A]mul1r; exact: eq_mul_cfuni. Qed.
+Proof. by rewrite -['1_A]mul1r; apply: eq_mul_cfuni. Qed.
Lemma cfuniG : '1_G = 1.
Proof. by rewrite -[G in '1_G]genGid. Qed.
@@ -556,12 +554,12 @@ apply/cfun_inP=> x Gx; rewrite sum_cfunE (bigD1 (x ^: G)) ?mem_classes //=.
rewrite cfunE cfun_repr cfun_classE Gx class_refl mulr1.
rewrite big1 ?addr0 // => _ /andP[/imsetP[y Gy ->]]; apply: contraNeq.
rewrite cfunE cfun_repr cfun_classE Gy mulf_eq0 => /norP[_].
-by rewrite pnatr_eq0 -lt0n lt0b => /class_transr->.
+by rewrite pnatr_eq0 -lt0n lt0b => /class_eqP->.
Qed.
Implicit Arguments cfun_onP [A phi].
Lemma cfun_on0 A phi x : phi \in 'CF(G, A) -> x \notin A -> phi x = 0.
-Proof. by move/cfun_onP; exact. Qed.
+Proof. by move/cfun_onP; apply. Qed.
Lemma sum_by_classes (R : ringType) (F : gT -> R) :
{in G &, forall g h, F (g ^ h) = F g} ->
@@ -571,7 +569,7 @@ move=> FJ; rewrite {1}(partition_big _ _ ((@mem_classes gT)^~ G)) /=.
apply: eq_bigr => _ /imsetP[x Gx ->]; have [y Gy ->] := repr_class G x.
rewrite mulr_natl -sumr_const FJ {y Gy}//; apply/esym/eq_big=> y /=.
apply/idP/andP=> [xGy | [Gy /eqP<-]]; last exact: class_refl.
- by rewrite (class_transr xGy) (subsetP (class_subG Gx (subxx _))).
+ by rewrite (class_eqP xGy) (subsetP (class_subG Gx (subxx _))).
by case/imsetP=> z Gz ->; rewrite FJ.
Qed.
@@ -587,7 +585,7 @@ apply: contraNeq; rewrite b_i !cfunE mulf_eq0 => /norP[_].
rewrite -(inj_eq enum_val_inj).
have /setIdP[/imsetP[x _ ->] _] := enum_valP i; rewrite cfun_repr.
have /setIdP[/imsetP[y Gy ->] _] := enum_valP j; rewrite cfun_classE Gy.
-by rewrite pnatr_eq0 -lt0n lt0b => /class_transr->.
+by rewrite pnatr_eq0 -lt0n lt0b => /class_eqP->.
Qed.
Lemma dim_cfun : \dim 'CF(G) = #|classes G|.
@@ -895,7 +893,7 @@ Proof. by rewrite -cfdot_conjC cfConjCK. Qed.
Lemma cfnorm_ge0 phi : 0 <= '[phi].
Proof.
-by rewrite mulr_ge0 ?invr_ge0 ?ler0n ?sumr_ge0 // => x _; exact: mul_conjC_ge0.
+by rewrite mulr_ge0 ?invr_ge0 ?ler0n ?sumr_ge0 // => x _; apply: mul_conjC_ge0.
Qed.
Lemma cfnorm_eq0 phi : ('[phi] == 0) = (phi == 0).
@@ -903,7 +901,7 @@ Proof.
apply/idP/eqP=> [|->]; last by rewrite cfdot0r.
rewrite mulf_eq0 invr_eq0 (negbTE (neq0CG G)) /= => /eqP/psumr_eq0P phi0.
apply/cfun_inP=> x Gx; apply/eqP; rewrite cfunE -mul_conjC_eq0.
-by rewrite phi0 // => y _; exact: mul_conjC_ge0.
+by rewrite phi0 // => y _; apply: mul_conjC_ge0.
Qed.
Lemma cfnorm_gt0 phi : ('[phi] > 0) = (phi != 0).
@@ -995,7 +993,7 @@ Lemma orthogonal_cons phi R S :
Proof. by rewrite /orthogonal /= andbT. Qed.
Lemma orthoP phi psi : reflect ('[phi, psi] = 0) (orthogonal phi psi).
-Proof. by rewrite /orthogonal /= !andbT; exact: eqP. Qed.
+Proof. by rewrite /orthogonal /= !andbT; apply: eqP. Qed.
Lemma orthogonalP S R :
reflect {in S & R, forall phi psi, '[phi, psi] = 0} (orthogonal S R).
@@ -1028,7 +1026,7 @@ Lemma eq_orthogonal R1 R2 S1 S2 :
R1 =i R2 -> S1 =i S2 -> orthogonal R1 S1 = orthogonal R2 S2.
Proof.
move=> eqR eqS; rewrite [orthogonal _ _](eq_all_r eqR).
-by apply: eq_all => psi /=; exact: eq_all_r.
+by apply: eq_all => psi /=; apply: eq_all_r.
Qed.
Lemma orthogonal_catl R1 R2 S :
@@ -1083,7 +1081,7 @@ Qed.
Lemma orthogonal_oppr S R : orthogonal S (map -%R R) = orthogonal S R.
Proof.
wlog suffices IH: S R / orthogonal S R -> orthogonal S (map -%R R).
- apply/idP/idP=> /IH; rewrite ?mapK //; exact: opprK.
+ by apply/idP/idP=> /IH; rewrite ?mapK //; apply: opprK.
move/orthogonalP=> oSR; apply/orthogonalP=> xi1 _ Sxi1 /mapP[xi2 Rxi2 ->].
by rewrite cfdotNr oSR ?oppr0.
Qed.
@@ -1104,7 +1102,7 @@ have [opS | not_opS] := allP; last first.
by rewrite opS ?mem_head 1?mem_behead // (memPnC notSp).
rewrite (contra (opS _)) /= ?cfnorm_eq0 //.
apply: (iffP IH) => [] [uniqS oSS]; last first.
- by split=> //; apply: sub_in2 oSS => psi Spsi; exact: mem_behead.
+ by split=> //; apply: sub_in2 oSS => psi Spsi; apply: mem_behead.
split=> // psi xi; rewrite !inE => /predU1P[-> // | Spsi].
by case/predU1P=> [-> | /opS] /eqP.
case/predU1P=> [-> _ | Sxi /oSS-> //].
@@ -1134,14 +1132,14 @@ Lemma sub_pairwise_orthogonal S1 S2 :
Proof.
move=> sS12 uniqS1 /pairwise_orthogonalP[/andP[notS2_0 _] oS2].
apply/pairwise_orthogonalP; rewrite /= (contra (sS12 0)) //.
-by split=> //; exact: sub_in2 oS2.
+by split=> //; apply: sub_in2 oS2.
Qed.
Lemma orthogonal_free S : pairwise_orthogonal S -> free S.
Proof.
case/pairwise_orthogonalP=> [/=/andP[notS0 uniqS] oSS].
rewrite -(in_tupleE S); apply/freeP => a aS0 i.
-have S_i: S`_i \in S by exact: mem_nth.
+have S_i: S`_i \in S by apply: mem_nth.
have /eqP: '[S`_i, 0]_G = 0 := cfdot0r _.
rewrite -{2}aS0 raddf_sum /= (bigD1 i) //= big1 => [|j neq_ji]; last 1 first.
by rewrite cfdotZr oSS ?mulr0 ?mem_nth // eq_sym nth_uniq.
@@ -1202,7 +1200,7 @@ Lemma sub_orthonormal S1 S2 :
{subset S1 <= S2} -> uniq S1 -> orthonormal S2 -> orthonormal S1.
Proof.
move=> sS12 uniqS1 /orthonormalP[_ oS1].
-by apply/orthonormalP; split; last exact: sub_in2 sS12 _ _.
+by apply/orthonormalP; split; last apply: sub_in2 sS12 _ _.
Qed.
Lemma orthonormal2P phi psi :
@@ -1214,7 +1212,7 @@ by apply: (iffP and3P) => [] []; do 3!move/eqP->.
Qed.
Lemma conjC_pair_orthogonal S chi :
- conjC_closed S -> ~~ has cfReal S -> pairwise_orthogonal S -> chi \in S ->
+ cfConjC_closed S -> ~~ has cfReal S -> pairwise_orthogonal S -> chi \in S ->
pairwise_orthogonal (chi :: chi^*%CF).
Proof.
move=> ccS /hasPn nrS oSS Schi; apply: sub_pairwise_orthogonal oSS.
@@ -1225,6 +1223,16 @@ Qed.
Lemma cfdot_real_conjC phi psi : cfReal phi -> '[phi, psi^*]_G = '[phi, psi]^*.
Proof. by rewrite -cfdot_conjC => /eqcfP->. Qed.
+Lemma extend_cfConjC_subset S X phi :
+ cfConjC_closed S -> ~~ has cfReal S -> phi \in S -> phi \notin X ->
+ cfConjC_subset X S -> cfConjC_subset [:: phi, phi^* & X]%CF S.
+Proof.
+move=> ccS nrS Sphi X'phi [uniqX /allP-sXS ccX].
+split; last 1 [by apply/allP; rewrite /= Sphi ccS | apply/allP]; rewrite /= inE.
+ by rewrite negb_or X'phi eq_sym (hasPn nrS) // (contra (ccX _)) ?cfConjCK.
+by rewrite cfConjCK !mem_head orbT; apply/allP=> xi Xxi; rewrite !inE ccX ?orbT.
+Qed.
+
(* Note: other isometry lemmas, and the dot product lemmas for orthogonal *)
(* and orthonormal sequences are in vcharacter, because we need the 'Z[S] *)
(* notation for the isometry domains. Alternatively, this could be moved to *)
@@ -1291,7 +1299,22 @@ Lemma sub_iso_to U1 U2 W1 W2 tau :
{subset U2 <= U1} -> {subset W1 <= W2} ->
{in U1, isometry tau, to W1} -> {in U2, isometry tau, to W2}.
Proof.
-by move=> sU sW [Itau Wtau]; split=> [|u /sU/Wtau/sW //]; exact: sub_in2 Itau.
+by move=> sU sW [Itau Wtau]; split=> [|u /sU/Wtau/sW //]; apply: sub_in2 Itau.
+Qed.
+
+Lemma isometry_of_free S f :
+ free S -> {in S &, isometry f} ->
+ {tau : {linear 'CF(L) -> 'CF(G)} |
+ {in S, tau =1 f} & {in <<S>>%VS &, isometry tau}}.
+Proof.
+move=> freeS If; have defS := free_span freeS.
+have [tau /(_ freeS (size_map f S))Dtau] := linear_of_free S (map f S).
+have{Dtau} Dtau: {in S, tau =1 f}.
+ by move=> _ /(nthP 0)[i ltiS <-]; rewrite -!(nth_map 0 0) ?Dtau.
+exists tau => // _ _ /defS[a -> _] /defS[b -> _].
+rewrite !{1}linear_sum !{1}cfdot_suml; apply/eq_big_seq=> xi1 Sxi1.
+rewrite !{1}cfdot_sumr; apply/eq_big_seq=> xi2 Sxi2.
+by rewrite !linearZ /= !Dtau // !cfdotZl !cfdotZr If.
Qed.
Lemma isometry_of_cfnorm S tauS :
@@ -1302,16 +1325,15 @@ Lemma isometry_of_cfnorm S tauS :
Proof.
move=> oS oT eq_nST; have freeS := orthogonal_free oS.
have eq_sz: size tauS = size S by have:= congr1 size eq_nST; rewrite !size_map.
-have [tau /(_ freeS eq_sz) defT] := linear_of_free S tauS.
-rewrite -[S]/(tval (in_tuple S)).
-exists tau => // u v /coord_span-> /coord_span->; rewrite !raddf_sum /=.
+have [tau defT] := linear_of_free S tauS; rewrite -[S]/(tval (in_tuple S)).
+exists tau => [|u v /coord_span-> /coord_span->]; rewrite ?raddf_sum ?defT //=.
apply: eq_bigr => i _ /=; rewrite linearZ !cfdotZr !cfdot_suml; congr (_ * _).
apply: eq_bigr => j _ /=; rewrite linearZ !cfdotZl; congr (_ * _).
-rewrite -!((nth_map _ 0) tau) // defT; have [-> | neq_ji] := eqVneq j i.
- by rewrite -!['[_]]((nth_map _ 0) cfnorm) ?eq_sz // eq_nST.
+rewrite -!(nth_map 0 0 tau) ?{}defT //; have [-> | neq_ji] := eqVneq j i.
+ by rewrite -!['[_]](nth_map 0 0 cfnorm) ?eq_sz // eq_nST.
have{oS} [/=/andP[_ uS] oS] := pairwise_orthogonalP oS.
have{oT} [/=/andP[_ uT] oT] := pairwise_orthogonalP oT.
-by rewrite oS ?oT ?mem_nth ? nth_uniq ?eq_sz.
+by rewrite oS ?oT ?mem_nth ?nth_uniq ?eq_sz.
Qed.
Lemma isometry_raddf_inj U (tau : {additive 'CF(L) -> 'CF(G)}) :
@@ -1628,7 +1650,7 @@ Local Notation "phi %% 'B'" := (cfMod phi) (at level 40) : cfun_scope.
(* stronger results are needed. *)
Lemma cfModE phi x : B <| G -> x \in G -> (phi %% B)%CF x = phi (coset B x).
-Proof. by move/normal_norm=> nBG; exact: cfMorphE. Qed.
+Proof. by move/normal_norm=> nBG; apply: cfMorphE. Qed.
Lemma cfMod1 phi : (phi %% B)%CF 1%g = phi 1%g. Proof. exact: cfMorph1. Qed.
@@ -2115,7 +2137,7 @@ apply: eq_bigr => _ /morphimP[x Dx Gx ->].
rewrite -(card_rcoset _ x) mulr_natl -sumr_const.
apply/eq_big => [y | y /andP[Gy /eqP <-]]; last by rewrite !cfMorphE.
rewrite mem_rcoset inE groupMr ?groupV // -mem_rcoset.
-by apply: andb_id2l => /(subsetP sGD) Dy; exact: sameP eqP (rcoset_kerP f _ _).
+by apply: andb_id2l => /(subsetP sGD) Dy; apply: sameP eqP (rcoset_kerP f _ _).
Qed.
Lemma cfIsom_iso rT G (R : {group rT}) (f : {morphism G >-> rT}) :
@@ -2374,11 +2396,14 @@ Proof. exact: raddfZ_Cnat. Qed.
Lemma cfAutZ_Cint z phi : z \in Cint -> (z *: phi)^u = z *: phi^u.
Proof. exact: raddfZ_Cint. Qed.
+Lemma cfAutK : cancel (@cfAut gT G u) (cfAut (algC_invaut_rmorphism u)).
+Proof. by move=> phi; apply/cfunP=> x; rewrite !cfunE /= algC_autK. Qed.
+
+Lemma cfAutVK : cancel (cfAut (algC_invaut_rmorphism u)) (@cfAut gT G u).
+Proof. by move=> phi; apply/cfunP=> x; rewrite !cfunE /= algC_invautK. Qed.
+
Lemma cfAut_inj : injective (@cfAut gT G u).
-Proof.
-move=> phi psi /cfunP eqfg; apply/cfunP=> x.
-by have := eqfg x; rewrite !cfunE => /fmorph_inj.
-Qed.
+Proof. exact: can_inj cfAutK. Qed.
Lemma cfAut_eq1 phi : (cfAut u phi == 1) = (phi == 1).
Proof. by rewrite rmorph_eq1 //; apply: cfAut_inj. Qed.
@@ -2460,6 +2485,8 @@ Proof. by rewrite rmorphM /= cfAutDprodl cfAutDprodr. Qed.
End FieldAutomorphism.
+Implicit Arguments cfAutK [[gT] [G]].
+Implicit Arguments cfAutVK [[gT] [G]].
Implicit Arguments cfAut_inj [gT G x1 x2].
Definition conj_cfRes := cfAutRes conjC.
diff --git a/mathcomp/character/finfield.v b/mathcomp/character/finfield.v
index 05b4a31..467449a 100644
--- a/mathcomp/character/finfield.v
+++ b/mathcomp/character/finfield.v
@@ -1,23 +1,14 @@
(* (c) Copyright Microsoft Corporation and Inria. All rights reserved. *)
Require Import mathcomp.ssreflect.ssreflect.
-From mathcomp.ssreflect
-Require Import ssreflect ssrbool ssrfun eqtype ssrnat seq.
-From mathcomp.discrete
-Require Import div choice fintype tuple bigop prime finset.
-From mathcomp.fingroup
-Require Import fingroup morphism action.
-From mathcomp.algebra
-Require Import ssralg poly polydiv finalg zmodp cyclic.
-From mathcomp.algebra
-Require Import matrix vector.
-From mathcomp.solvable
-Require Import center pgroup abelian.
-From mathcomp.field
-Require Import falgebra fieldext separable galois.
-Require Import mxabelem.
-
-From mathcomp.algebra Require ssrnum ssrint.
-From mathcomp.field Require algC cyclotomic.
+From mathcomp
+Require Import ssrfun ssrbool eqtype ssrnat seq choice fintype div.
+From mathcomp
+Require Import tuple bigop prime finset fingroup ssralg poly polydiv.
+From mathcomp
+Require Import morphism action finalg zmodp cyclic center pgroup abelian.
+From mathcomp
+Require Import matrix mxabelem vector falgebra fieldext separable galois.
+Require ssrnum ssrint algC cyclotomic.
(******************************************************************************)
(* Additional constructions and results on finite fields. *)
@@ -498,7 +489,7 @@ have [p p_pr charRp]: exists2 p, prime p & p \in [char R].
rewrite big_seq; elim/big_rec: _ => [|[p m] /= n]; first by rewrite oner_eq0.
case/mem_prime_decomp=> p_pr _ _ IHn.
elim: m => [|m IHm]; rewrite ?mul1n {IHn}// expnS -mulnA natrM.
- by case/eqP/domR/orP=> //; exists p; last exact/andP.
+ by case/eqP/domR/orP=> //; exists p; last apply/andP.
pose Rp := PrimeCharType charRp; pose L : {vspace Rp} := fullv.
pose G := [set: {unit R}]; pose ofG : {unit R} -> Rp := val.
pose projG (E : {vspace Rp}) := [preim ofG of E].
diff --git a/mathcomp/character/inertia.v b/mathcomp/character/inertia.v
index 9a795e8..c6ddf44 100644
--- a/mathcomp/character/inertia.v
+++ b/mathcomp/character/inertia.v
@@ -1,20 +1,17 @@
(* (c) Copyright Microsoft Corporation and Inria. All rights reserved. *)
Require Import mathcomp.ssreflect.ssreflect.
-From mathcomp.ssreflect
-Require Import ssreflect ssrbool ssrfun eqtype ssrnat seq.
-From mathcomp.discrete
-Require Import path div choice fintype tuple finfun bigop prime finset.
-From mathcomp.fingroup
-Require Import fingroup morphism perm automorphism quotient action gproduct.
-From mathcomp.algebra
-Require Import ssralg ssrnum zmodp cyclic matrix mxalgebra vector.
-From mathcomp.solvable
-Require Import center commutator gseries nilpotent pgroup sylow maximal.
-From mathcomp.solvable
+From mathcomp
+Require Import ssrfun ssrbool eqtype ssrnat seq path choice div.
+From mathcomp
+Require Import fintype tuple finfun bigop prime ssralg ssrnum finset fingroup.
+From mathcomp
+Require Import morphism perm automorphism quotient action zmodp cyclic center.
+From mathcomp
+Require Import gproduct commutator gseries nilpotent pgroup sylow maximal.
+From mathcomp
Require Import frobenius.
-From mathcomp.field
-Require Import algC.
-Require Import mxrepresentation classfun character.
+From mathcomp
+Require Import matrix mxalgebra mxrepresentation vector algC classfun character.
Set Implicit Arguments.
Unset Strict Implicit.
@@ -105,7 +102,7 @@ Qed.
(* Isaacs' 6.1.b *)
Lemma cfConjgM L phi :
G <| L -> {in L &, forall y z, phi ^ (y * z) = (phi ^ y) ^ z}%CF.
-Proof. by case/andP=> _ /subsetP nGL; exact: sub_in2 (cfConjgMnorm phi). Qed.
+Proof. by case/andP=> _ /subsetP nGL; apply: sub_in2 (cfConjgMnorm phi). Qed.
Lemma cfConjgJ1 phi : (phi ^ 1)%CF = phi.
Proof. by apply/cfunP=> x; rewrite cfConjgE ?group1 // invg1 conjg1. Qed.
@@ -403,7 +400,7 @@ apply: (iffP imageP) => [[_ /rcosetsP[y Ay ->] ->] | [y Ay ->]].
by case: repr_rcosetP => z /setIdP[Az _]; exists (z * y)%g; rewrite ?groupM.
without loss nHy: y Ay / y \in 'N(H).
have [nHy | /cfConjgEout->] := boolP (y \in 'N(H)); first exact.
- by move/(_ 1%g); rewrite !group1 !cfConjgJ1; exact.
+ by move/(_ 1%g); rewrite !group1 !cfConjgJ1; apply.
exists ('I_A[phi] :* y); first by rewrite -rcosetE mem_imset.
case: repr_rcosetP => z /setIP[_ /setIdP[nHz /eqP Tz]].
by rewrite cfConjgMnorm ?Tz.
@@ -414,25 +411,25 @@ Proof.
move=> xi; apply/cfclassP/cfclassP=> [[x /setIP[Gx _] ->] | [x Gx ->]].
by exists x.
have [Nx | /cfConjgEout-> //] := boolP (x \in 'N(H)).
- by exists x; first exact/setIP.
+ by exists x; first apply/setIP.
by exists 1%g; rewrite ?group1 ?cfConjgJ1.
Qed.
Lemma cfclass_refl phi : phi \in (phi ^: G)%CF.
Proof. by apply/cfclassP; exists 1%g => //; rewrite cfConjgJ1. Qed.
-Lemma cfclass_transl phi psi :
+Lemma cfclass_transr phi psi :
(psi \in phi ^: G)%CF -> (phi ^: G =i psi ^: G)%CF.
Proof.
rewrite -cfclassInorm; case/cfclassP=> x Gx -> xi; rewrite -!cfclassInorm.
-have nHN: {subset 'N_G(H) <= 'N(H)} by apply/subsetP; exact: subsetIr.
+have nHN: {subset 'N_G(H) <= 'N(H)} by apply/subsetP; apply: subsetIr.
apply/cfclassP/cfclassP=> [[y Gy ->] | [y Gy ->]].
by exists (x^-1 * y)%g; rewrite -?cfConjgMnorm ?groupM ?groupV ?nHN // mulKVg.
by exists (x * y)%g; rewrite -?cfConjgMnorm ?groupM ?nHN.
Qed.
Lemma cfclass_sym phi psi : (psi \in phi ^: G)%CF = (phi \in psi ^: G)%CF.
-Proof. by apply/idP/idP=> /cfclass_transl <-; exact: cfclass_refl. Qed.
+Proof. by apply/idP/idP=> /cfclass_transr <-; apply: cfclass_refl. Qed.
Lemma cfclass_uniq phi : H <| G -> uniq (phi ^: G)%CF.
Proof.
@@ -440,7 +437,7 @@ move=> nsHG; rewrite map_inj_in_uniq ?enum_uniq // => Ty Tz; rewrite !mem_enum.
move=> {Ty}/rcosetsP[y Gy ->] {Tz}/rcosetsP[z Gz ->] /eqP.
case: repr_rcosetP => u Iphi_u; case: repr_rcosetP => v Iphi_v.
have [[Gu _] [Gv _]] := (setIdP Iphi_u, setIdP Iphi_v).
-rewrite cfConjg_eqE ?groupM // => /rcoset_transl.
+rewrite cfConjg_eqE ?groupM // => /rcoset_eqP.
by rewrite !rcosetM (rcoset_id Iphi_v) (rcoset_id Iphi_u).
Qed.
@@ -466,7 +463,7 @@ Lemma eq_cfclass_IirrE i j :
(cfclass_Iirr G j == cfclass_Iirr G i) = (j \in cfclass_Iirr G i).
Proof.
apply/eqP/idP=> [<- | iGj]; first by rewrite cfclass_IirrE cfclass_refl.
-by apply/setP=> k; rewrite !cfclass_IirrE in iGj *; apply/esym/cfclass_transl.
+by apply/setP=> k; rewrite !cfclass_IirrE in iGj *; apply/esym/cfclass_transr.
Qed.
Lemma im_cfclass_Iirr i :
@@ -1581,7 +1578,7 @@ apply: contraR => notKx; apply/cards1P; exists 1%g; apply/esym/eqP.
rewrite eqEsubset !(sub1set, inE) classes1 /= conjs1g eqxx /=.
apply/subsetP=> _ /setIP[/imsetP[y Ky ->] /afix1P /= cyKx].
have /imsetP[z Kz def_yx]: y ^ x \in y ^: K.
- by rewrite -cyKx; apply: mem_imset; exact: class_refl.
+ by rewrite -cyKx; apply: mem_imset; apply: class_refl.
rewrite inE classG_eq1; apply: contraR notKx => nty.
rewrite -(groupMr x (groupVr Kz)).
apply: (subsetP (regK y _)); first exact/setD1P.
@@ -1606,7 +1603,7 @@ Proof.
have [_ _ nsKG _] := Frobenius_kerP frobGK; have [sKG nKG] := andP nsKG.
apply: (iffP idP) => [not_chijK1 | [i nzi ->]]; last first.
by rewrite cfker_Ind_irr ?sub_gcore // subGcfker.
-have /neq0_has_constt[i chijKi]: 'Res[K] 'chi_j != 0 by exact: Res_irr_neq0.
+have /neq0_has_constt[i chijKi]: 'Res[K] 'chi_j != 0 by apply: Res_irr_neq0.
have nz_i: i != 0.
by apply: contraNneq not_chijK1 => i0; rewrite constt0_Res_cfker // -i0.
have /irrP[k def_chik] := irr_induced_Frobenius_ker nz_i.
diff --git a/mathcomp/character/integral_char.v b/mathcomp/character/integral_char.v
index 14ae4fc..1770335 100644
--- a/mathcomp/character/integral_char.v
+++ b/mathcomp/character/integral_char.v
@@ -1,19 +1,18 @@
(* (c) Copyright Microsoft Corporation and Inria. All rights reserved. *)
Require Import mathcomp.ssreflect.ssreflect.
-From mathcomp.ssreflect
-Require Import ssreflect ssrbool ssrfun eqtype ssrnat seq.
-From mathcomp.discrete
-Require Import path div choice fintype tuple finfun bigop prime finset.
-From mathcomp.fingroup
-Require Import fingroup morphism perm automorphism quotient action gproduct.
-From mathcomp.algebra
-Require Import ssralg poly polydiv finalg zmodp cyclic matrix mxalgebra mxpoly.
-From mathcomp.solvable
-Require Import commutator center pgroup sylow gseries nilpotent abelian.
-From mathcomp.algebra
-Require Import ssrnum ssrint polydiv rat matrix mxalgebra intdiv mxpoly vector.
-From mathcomp.field
-Require Import fieldext separable galois algC cyclotomic algnum falgebra.
+From mathcomp
+Require Import ssrbool ssrfun eqtype ssrnat seq path div choice.
+From mathcomp
+Require Import fintype tuple finfun bigop prime ssralg poly finset.
+From mathcomp
+Require Import fingroup morphism perm automorphism quotient action finalg zmodp.
+From mathcomp
+Require Import commutator cyclic center pgroup sylow gseries nilpotent abelian.
+From mathcomp
+Require Import ssrnum ssrint polydiv rat matrix mxalgebra intdiv mxpoly.
+From mathcomp
+Require Import vector falgebra fieldext separable galois algC cyclotomic algnum.
+From mathcomp
Require Import mxrepresentation classfun character.
(******************************************************************************)
@@ -31,7 +30,7 @@ Require Import mxrepresentation classfun character.
(* gring_classM_coef_set A B z == the set of all (x, y) in setX A B such *)
(* that x * y = z; if A and B are respectively the ith and jth *)
(* conjugacy class of G, and z is in the kth conjugacy class, then *)
-(* gring_classM_coef i j k is exactly the cadinal of this set. *)
+(* gring_classM_coef i j k is exactly the cardinal of this set. *)
(* 'omega_i[A] == the mode of 'chi[G]_i on (A \in 'Z(group_ring algC G))%MS, *)
(* i.e., the z such that gring_op 'Chi_i A = z%:M. *)
(******************************************************************************)
@@ -73,7 +72,7 @@ exists (SplittingFieldType _ _ Qn_ax).
apply: separable_Xn_sub_1; rewrite -(fmorph_eq0 QnC) rmorph_nat.
by rewrite pnatr_eq0 -lt0n cardG_gt0.
exists QnC => [// nuQn|].
- by exact: (extend_algC_subfield_aut QnC [rmorphism of nuQn]).
+ by apply: (extend_algC_subfield_aut QnC [rmorphism of nuQn]).
rewrite span_seq1 in genQn.
exists w => // hT H phi Nphi x x_dv_n.
apply: sig_eqW; have [rH ->] := char_reprP Nphi.
@@ -146,7 +145,7 @@ rewrite scaler_sumr; apply: eq_bigr => g Kk_g; rewrite scaler_nat.
rewrite (set_gring_classM_coef _ _ Kk_g) -sumr_const; apply: eq_big => [] [x y].
rewrite !inE /= dKi dKj /h1 /h2 /=; apply: andb_id2r => /eqP ->.
have /imsetP[zk Gzk dKk] := enum_valP k; rewrite dKk in Kk_g.
- by rewrite (class_transr Kk_g) -dKk enum_valK_in eqxx andbT.
+ by rewrite (class_eqP Kk_g) -dKk enum_valK_in eqxx andbT.
by rewrite /h2 /= => /andP[_ /eqP->].
Qed.
@@ -179,7 +178,7 @@ exact/unity_rootP.
Qed.
Lemma Aint_irr i x : 'chi[G]_i x \in Aint.
-Proof. by apply: Aint_char; exact: irr_char. Qed.
+Proof. exact/Aint_char/irr_char. Qed.
Local Notation R_G := (group_ring algCfield G).
Local Notation a := gring_classM_coef.
@@ -240,9 +239,9 @@ Qed.
Lemma Aint_gring_mode_class_sum k : 'omega_i['K_k] \in Aint.
Proof.
move: k; pose X := [tuple 'omega_i['K_k] | k < #|classes G| ].
-have memX k: 'omega_i['K_k] \in X by apply: map_f; exact: mem_enum.
+have memX k: 'omega_i['K_k] \in X by apply: image_f.
have S_P := Cint_spanP X; set S := Cint_span X in S_P.
-have S_X: {subset X <= S} by exact: mem_Cint_span.
+have S_X: {subset X <= S} by apply: mem_Cint_span.
have S_1: 1 \in S.
apply: S_X; apply/codomP; exists (enum_rank_in (classes1 G) 1%g).
rewrite (@gring_mode_class_sum_eq _ 1%g) ?enum_rankK_in ?classes1 //.
@@ -383,7 +382,7 @@ rewrite ltnS => leGn piGle2; have [simpleG | ] := boolP (simple G); last first.
exact: solvable1.
rewrite [N == G]eqEproper sNG eqbF_neg !negbK => ltNG /and3P[grN].
case/isgroupP: grN => {N}N -> in sNG ltNG *; rewrite /= genGid => ntN nNG.
- have nsNG: N <| G by exact/andP.
+ have nsNG: N <| G by apply/andP.
have dv_le_pi m: (m %| #|G| -> size (primes m) <= 2)%N.
move=> m_dv_G; apply: leq_trans piGle2.
by rewrite uniq_leq_size ?primes_uniq //; apply: pi_of_dvd.
@@ -498,7 +497,7 @@ move=> a /= Kg1 Kg2 Kg; rewrite mulrAC; apply: canRL (mulfK (neq0CG G)) _.
transitivity (\sum_j (#|G| * a j)%:R *+ (j == k) : algC).
by rewrite (bigD1 k) //= eqxx -natrM mulnC big1 ?addr0 // => j /negPf->.
have defK (j : 'I_#|classes G|) x: x \in enum_val j -> enum_val j = x ^: G.
- by have /imsetP[y Gy ->] := enum_valP j => /class_transr.
+ by have /imsetP[y Gy ->] := enum_valP j => /class_eqP.
have Gg: g \in G.
by case/imsetP: (enum_valP k) Kg => x Gx -> /imsetP[y Gy ->]; apply: groupJ.
transitivity (\sum_j \sum_i 'omega_i['K_j] * 'chi_i 1%g * ('chi_i g)^* *+ a j).
@@ -680,7 +679,7 @@ have{Qpi1} Zpi1: pi1 \in Cint.
have{pi1 Zpi1} pi2_ge1: 1 <= pi2.
have ->: pi2 = `|pi1| ^+ 2.
by rewrite (big_morph Num.norm (@normrM _) (@normr1 _)) -prodrXl.
- by rewrite Cint_normK // sqr_Cint_ge1 //; exact/prodf_neq0.
+ by rewrite Cint_normK // sqr_Cint_ge1 //; apply/prodf_neq0.
have Sgt0: (#|S| > 0)%N by rewrite (cardD1 g) [g \in S]Sg.
rewrite -mulr_natr -ler_pdivl_mulr ?ltr0n //.
have n2chi_ge0 s: s \in S -> 0 <= `|chi s| ^+ 2 by rewrite exprn_ge0 ?normr_ge0.
@@ -693,7 +692,7 @@ Theorem nonlinear_irr_vanish gT (G : {group gT}) i :
'chi[G]_i 1%g > 1 -> exists2 x, x \in G & 'chi_i x = 0.
Proof.
move=> chi1gt1; apply/exists_eq_inP; apply: contraFT (ltr_geF chi1gt1).
-rewrite negb_exists_in => /forall_inP nz_chi.
+rewrite negb_exists_in => /forall_inP-nz_chi.
rewrite -(norm_Cnat (Cnat_irr1 i)) -(@expr_le1 _ 2) ?normr_ge0 //.
rewrite -(ler_add2r (#|G|%:R * '['chi_i])) {1}cfnorm_irr mulr1.
rewrite (cfnormE (cfun_onG _)) mulVKf ?neq0CG // (big_setD1 1%g) //=.
diff --git a/mathcomp/character/mxabelem.v b/mathcomp/character/mxabelem.v
index 377cb72..8685796 100644
--- a/mathcomp/character/mxabelem.v
+++ b/mathcomp/character/mxabelem.v
@@ -1,18 +1,15 @@
(* (c) Copyright Microsoft Corporation and Inria. All rights reserved. *)
Require Import mathcomp.ssreflect.ssreflect.
-From mathcomp.ssreflect
-Require Import ssreflect ssrbool ssrfun eqtype ssrnat seq.
-From mathcomp.discrete
-Require Import path div choice fintype tuple finfun bigop prime finset.
-From mathcomp.fingroup
+From mathcomp
+Require Import ssrbool ssrfun eqtype ssrnat seq path div choice.
+From mathcomp
+Require Import fintype tuple finfun bigop prime ssralg poly finset.
+From mathcomp
Require Import fingroup morphism perm automorphism quotient gproduct action.
-From mathcomp.algebra
-Require Import ssralg poly finalg zmodp cyclic matrix mxalgebra.
-From mathcomp.solvable
-Require Import commutator center pgroup gseries nilpotent.
-From mathcomp.solvable
-Require Import sylow maximal abelian.
-Require Import mxrepresentation.
+From mathcomp
+Require Import finalg zmodp commutator cyclic center pgroup gseries nilpotent.
+From mathcomp
+Require Import sylow maximal abelian matrix mxalgebra mxrepresentation.
(******************************************************************************)
(* This file completes the theory developed in mxrepresentation.v with the *)
@@ -145,7 +142,7 @@ Proof. by rewrite inE. Qed.
Fact rowg_group_set m A : group_set (@rowg m A).
Proof.
-by apply/group_setP; split=> [|u v]; rewrite !inE ?sub0mx //; exact: addmx_sub.
+by apply/group_setP; split=> [|u v]; rewrite !inE ?sub0mx //; apply: addmx_sub.
Qed.
Canonical rowg_group m A := Group (@rowg_group_set m A).
@@ -157,7 +154,7 @@ Lemma rowgS m1 m2 (A : 'M_(m1, n)) (B : 'M_(m2, n)) :
Proof.
apply/subsetP/idP=> sAB => [| u].
by apply/row_subP=> i; have:= sAB (row i A); rewrite !inE row_sub => ->.
-by rewrite !inE => suA; exact: submx_trans sAB.
+by rewrite !inE => suA; apply: submx_trans sAB.
Qed.
Lemma eq_rowg m1 m2 (A : 'M_(m1, n)) (B : 'M_(m2, n)) :
@@ -214,8 +211,8 @@ Proof. by apply/eqP; rewrite -submx0 -(rowg0 0) rowgK sub0mx. Qed.
Lemma rowg_mx_eq0 (L : {group rVn}) : (rowg_mx L == 0) = (L :==: 1%g).
Proof.
-rewrite -trivg_rowg; apply/idP/idP=> [|/eqP->]; last by rewrite rowg_mx1 rowg0.
-by rewrite !(sameP eqP trivgP); apply: subset_trans; exact: sub_rowg_mx.
+rewrite -trivg_rowg; apply/idP/eqP=> [|->]; last by rewrite rowg_mx1 rowg0.
+exact/contraTeq/subG1_contra/sub_rowg_mx.
Qed.
Lemma rowgI m1 m2 (A : 'M_(m1, n)) (B : 'M_(m2, n)) :
@@ -312,7 +309,7 @@ Lemma astabs_rowg_repr m (A : 'M_(m, n)) : 'N(rowg A | 'MR rG) = rstabs rG A.
Proof.
apply/setP=> x; rewrite !inE /=; apply: andb_id2l => Gx.
apply/subsetP/idP=> nAx => [|u]; last first.
- rewrite !inE mx_repr_actE // => Au; exact: (submx_trans (submxMr _ Au)).
+ by rewrite !inE mx_repr_actE // => Au; apply: (submx_trans (submxMr _ Au)).
apply/row_subP=> i; move/implyP: (nAx (row i A)).
by rewrite !inE row_sub mx_repr_actE //= row_mul.
Qed.
@@ -449,13 +446,13 @@ Variables p n : nat.
Local Notation rVn := 'rV['F_p]_n.
Lemma rowg_mxK (L : {group rVn}) : rowg (rowg_mx L) = L.
-Proof. by apply: stable_rowg_mxK; exact: mx_Fp_stable. Qed.
+Proof. by apply: stable_rowg_mxK; apply: mx_Fp_stable. Qed.
Lemma rowg_mxSK (L : {set rVn}) (M : {group rVn}) :
(rowg_mx L <= rowg_mx M)%MS = (L \subset M).
Proof.
apply/idP/idP; last exact: rowg_mxS.
-by rewrite -rowgS rowg_mxK; apply: subset_trans; exact: sub_rowg_mx.
+by rewrite -rowgS rowg_mxK; apply/subset_trans/sub_rowg_mx.
Qed.
Lemma mxrank_rowg (L : {group rVn}) :
@@ -508,7 +505,7 @@ Proof. by case/misomP: (xchooseP ab_rV_P). Qed.
Lemma abelem_rV_injm : 'injm ErV. Proof. by case/isomP: abelem_rV_isom. Qed.
Lemma abelem_rV_inj : {in E &, injective ErV}.
-Proof. by apply/injmP; exact: abelem_rV_injm. Qed.
+Proof. by apply/injmP; apply: abelem_rV_injm. Qed.
Lemma im_abelem_rV : ErV @* E = setT. Proof. by case/isomP: abelem_rV_isom. Qed.
@@ -701,7 +698,7 @@ Qed.
Lemma abelem_mx_irrP : reflect (mx_irreducible rG) (minnormal E G).
Proof.
-by rewrite -[E in minnormal E G]im_rVabelem -rowg1; exact: mxsimple_abelemP.
+by rewrite -[E in minnormal E G]im_rVabelem -rowg1; apply: mxsimple_abelemP.
Qed.
Lemma rfix_abelem (H : {set gT}) :
@@ -850,7 +847,7 @@ Let p_gt1 := prime_gt1 p_pr.
Let oZp := card_center_extraspecial pS esS.
Let modIp' (i : 'I_p.-1) : (i.+1 %% p = i.+1)%N.
-Proof. by case: i => i; rewrite /= -ltnS prednK //; exact: modn_small. Qed.
+Proof. by case: i => i; rewrite /= -ltnS prednK //; apply: modn_small. Qed.
(* This is Aschbacher (34.9), parts (1)-(4). *)
Theorem extraspecial_repr_structure (sS : irrType F S) :
@@ -873,7 +870,7 @@ have nb_irr: #|sS| = (p ^ n.*2 + p.-1)%N.
pose Zcl := classes S ::&: 'Z(S).
have cardZcl: #|Zcl| = p.
transitivity #|[set [set z] | z in 'Z(S)]|; last first.
- by rewrite card_imset //; exact: set1_inj.
+ by rewrite card_imset //; apply: set1_inj.
apply: eq_card => zS; apply/setIdP/imsetP=> [[] | [z]].
case/imsetP=> z Sz ->{zS} szSZ.
have Zz: z \in 'Z(S) by rewrite (subsetP szSZ) ?class_refl.
@@ -900,7 +897,7 @@ have nb_irr: #|sS| = (p ^ n.*2 + p.-1)%N.
apply: contra notZxS => Zxy; rewrite -{1}(lcoset_id Sy) class_lcoset.
rewrite ((_ ^: _ =P [set x ^ y])%g _) ?sub1set // eq_sym eqEcard.
rewrite sub1set class_refl cards1 -index_cent1 (setIidPl _) ?indexgg //.
- by rewrite sub_cent1; apply: subsetP Zxy; exact: subsetIr.
+ by rewrite sub_cent1; apply: subsetP Zxy; apply: subsetIr.
rewrite sum_nat_dep_const mulnC eqn_pmul2l //; move/eqP <-.
rewrite addSnnS prednK // -cardZcl -[card _](cardsID Zcl) /= addnC.
by congr (_ + _)%N; apply: eq_card => t; rewrite !inE andbC // andbAC andbb.
@@ -954,11 +951,10 @@ have alpha_i_z i: ((alpha ^+ ephi i) z = z ^+ i.+1)%g.
by rewrite autE ?cycle_id //= val_Zp_nat ozp ?modIp'.
have rphiP i: S :==: autm (groupX (ephi i) Aut_alpha) @* S by rewrite im_autm.
pose rphi i := morphim_repr (eqg_repr phi (rphiP i)) (subxx S).
-have rphi_irr i: mx_irreducible (rphi i).
- by apply/morphim_mx_irr; exact/eqg_mx_irr.
+have rphi_irr i: mx_irreducible (rphi i) by apply/morphim_mx_irr/eqg_mx_irr.
have rphi_fful i: mx_faithful (rphi i).
rewrite /mx_faithful rker_morphim rker_eqg.
- by rewrite (trivgP (fful_nlin _ nlin_i0)) morphpreIdom; exact: injm_autm.
+ by rewrite (trivgP (fful_nlin _ nlin_i0)) morphpreIdom; apply: injm_autm.
have rphi_z i: rphi i z = (w ^+ i.+1)%:M.
by rewrite /rphi [phi]lock /= /morphim_mx autmE alpha_i_z -lock phi_ze.
pose iphi i := irr_comp sS (rphi i); pose phi_ i := irr_repr (iphi i).
@@ -1021,7 +1017,7 @@ suffices IH V: mxsimple rS V -> mx_iso rZ U V ->
- split=> [|/= V simV isoUV].
by case/andP: (IH U simU (mx_iso_refl _ _)) => /eqP.
by case/andP: (IH V simV isoUV) => _ /(mxsimple_isoP simU).
-move=> simV isoUV; wlog sS: / irrType F S by exact: socle_exists.
+move=> simV isoUV; wlog sS: / irrType F S by apply: socle_exists.
have [[_ defS'] prZ] := esS.
have{prZ} ntZ: 'Z(S) :!=: 1%g by case: eqP prZ => // ->; rewrite cards1.
have [_ [iphi]] := extraspecial_repr_structure sS.
@@ -1030,13 +1026,13 @@ have [modU nzU _]:= simU; pose rU := submod_repr modU.
have nlinU: \rank U != 1%N.
apply/eqP=> /(rker_linear rU); apply/negP; rewrite /rker rstab_submod.
by rewrite (eqmx_rstab _ (val_submod1 _)) (eqP ffulU) defS' subG1.
-have irrU: mx_irreducible rU by exact/submod_mx_irr.
+have irrU: mx_irreducible rU by apply/submod_mx_irr.
have rsimU := rsim_irr_comp sS F'S irrU.
set iU := irr_comp sS rU in rsimU; have [_ degU _ _]:= rsimU.
have phiUP: iU \in codom iphi by rewrite im_phi !inE -degU.
rewrite degU -(f_iinv phiUP) dim_phi eqxx /=; apply/(mxsimple_isoP simU).
have [modV _ _]:= simV; pose rV := submod_repr modV.
-have irrV: mx_irreducible rV by exact/submod_mx_irr.
+have irrV: mx_irreducible rV by apply/submod_mx_irr.
have rsimV := rsim_irr_comp sS F'S irrV.
set iV := irr_comp sS rV in rsimV; have [_ degV _ _]:= rsimV.
have phiVP: iV \in codom iphi by rewrite im_phi !inE -degV -(mxrank_iso isoUV).
@@ -1045,7 +1041,7 @@ have [z Zz ntz]:= trivgPn _ ntZ.
have [|w prim_w phi_z] := phiZ z; first by rewrite 2!inE ntz.
suffices eqjUV: jU == jV.
apply/(mx_rsim_iso modU modV); apply: mx_rsim_trans rsimU _.
- by rewrite -(f_iinv phiUP) -/jU (eqP eqjUV) f_iinv; exact: mx_rsim_sym.
+ by rewrite -(f_iinv phiUP) -/jU (eqP eqjUV) f_iinv; apply: mx_rsim_sym.
have rsimUV: mx_rsim (subg_repr (phi jU) sZS) (subg_repr (phi jV) sZS).
have [bU _ bUfree bUhom] := mx_rsim_sym rsimU.
have [bV _ bVfree bVhom] := rsimV.
diff --git a/mathcomp/character/mxrepresentation.v b/mathcomp/character/mxrepresentation.v
index e947fe0..7ceae6e 100644
--- a/mathcomp/character/mxrepresentation.v
+++ b/mathcomp/character/mxrepresentation.v
@@ -1,15 +1,13 @@
(* (c) Copyright Microsoft Corporation and Inria. All rights reserved. *)
Require Import mathcomp.ssreflect.ssreflect.
-From mathcomp.ssreflect
-Require Import ssreflect ssrbool ssrfun eqtype ssrnat seq.
-From mathcomp.discrete
-Require Import path div choice fintype tuple finfun bigop prime finset.
-From mathcomp.fingroup
-Require Import fingroup morphism perm automorphism quotient action gproduct.
-From mathcomp.algebra
-Require Import ssralg poly polydiv finalg zmodp cyclic matrix mxalgebra mxpoly.
-From mathcomp.solvable
-Require Import commutator center pgroup.
+From mathcomp
+Require Import ssrbool ssrfun eqtype ssrnat seq path div choice.
+From mathcomp
+Require Import fintype tuple finfun bigop prime ssralg poly polydiv finset.
+From mathcomp
+Require Import fingroup morphism perm automorphism quotient finalg action zmodp.
+From mathcomp
+Require Import commutator cyclic center pgroup matrix mxalgebra mxpoly.
(******************************************************************************)
(* This file provides linkage between classic Group Theory and commutative *)
@@ -308,7 +306,7 @@ Qed.
Lemma repr_mxKV m x :
x \in G -> cancel ((@mulmx _ m n n)^~ (rG x^-1)) (mulmx^~ (rG x)).
-Proof. by rewrite -groupV -{3}[x]invgK; exact: repr_mxK. Qed.
+Proof. by rewrite -groupV -{3}[x]invgK; apply: repr_mxK. Qed.
Lemma repr_mx_unit x : x \in G -> rG x \in unitmx.
Proof. by move=> Gx; case/mulmx1_unit: (repr_mxKV Gx 1%:M). Qed.
@@ -923,7 +921,7 @@ Proof. by case/setIdP=> _ /eqP cUx /submxP[w ->]; rewrite -mulmxA cUx. Qed.
Lemma rstabs_act x m1 (W : 'M_(m1, n)) :
x \in rstabs -> (W <= U)%MS -> (W *m rG x <= U)%MS.
Proof.
-by case/setIdP=> [_ nUx] sWU; apply: submx_trans nUx; exact: submxMr.
+by case/setIdP=> [_ nUx] sWU; apply: submx_trans nUx; apply: submxMr.
Qed.
Definition mxmodule := G \subset rstabs.
@@ -964,7 +962,7 @@ Proof. by apply/mxmoduleP=> x _; rewrite submx1. Qed.
Lemma mxmodule_trans m1 m2 (U : 'M_(m1, n)) (W : 'M_(m2, n)) x :
mxmodule U -> x \in G -> (W <= U -> W *m rG x <= U)%MS.
Proof.
-by move=> modU Gx sWU; apply: submx_trans (mxmoduleP modU x Gx); exact: submxMr.
+by move=> modU Gx sWU; apply: submx_trans (mxmoduleP modU x Gx); apply: submxMr.
Qed.
Lemma mxmodule_eigenvector m (U : 'M_(m, n)) :
@@ -989,7 +987,7 @@ Qed.
Lemma sumsmx_module I r (P : pred I) U :
(forall i, P i -> mxmodule (U i)) -> mxmodule (\sum_(i <- r | P i) U i)%MS.
Proof.
-by move=> modU; elim/big_ind: _; [exact: mxmodule0 | exact: addsmx_module | ].
+by move=> modU; elim/big_ind: _; [apply: mxmodule0 | apply: addsmx_module | ].
Qed.
Lemma capmx_module m1 m2 U V :
@@ -1002,7 +1000,7 @@ Qed.
Lemma bigcapmx_module I r (P : pred I) U :
(forall i, P i -> mxmodule (U i)) -> mxmodule (\bigcap_(i <- r | P i) U i)%MS.
Proof.
-by move=> modU; elim/big_ind: _; [exact: mxmodule1 | exact: capmx_module | ].
+by move=> modU; elim/big_ind: _; [apply: mxmodule1 | apply: capmx_module | ].
Qed.
(* Sub- and factor representations induced by a (sub)module. *)
@@ -1023,7 +1021,7 @@ Lemma in_submodE m W : @in_submod m W = W *m in_submod 1%:M.
Proof. by rewrite mulmxA mulmx1. Qed.
Lemma val_submod1 : (val_submod 1%:M :=: U)%MS.
-Proof. by rewrite /val_submod /= mul1mx; exact: eq_row_base. Qed.
+Proof. by rewrite /val_submod /= mul1mx; apply: eq_row_base. Qed.
Lemma val_submodP m W : (@val_submod m W <= U)%MS.
Proof. by rewrite mulmx_sub ?eq_row_base. Qed.
@@ -1128,7 +1126,7 @@ Lemma in_factmod_addsK m (W : 'M_(m, n)) :
(in_factmod (U + W)%MS :=: in_factmod W)%MS.
Proof.
apply: eqmx_trans (addsmxMr _ _ _) _.
-by rewrite ((_ *m _ =P 0) _) ?in_factmod_eq0 //; exact: adds0mx.
+by rewrite ((_ *m _ =P 0) _) ?in_factmod_eq0 //; apply: adds0mx.
Qed.
Lemma add_sub_fact_mod m (W : 'M_(m, n)) :
@@ -1151,7 +1149,7 @@ Lemma in_factmodsK m (W : 'M_(m, n)) :
(U <= W)%MS -> (U + val_factmod (in_factmod W) :=: W)%MS.
Proof.
move/addsmx_idPr; apply: eqmx_trans (eqmx_sym _).
-by rewrite -{1}[W]add_sub_fact_mod; apply: addsmx_addKl; exact: val_submodP.
+by rewrite -{1}[W]add_sub_fact_mod; apply: addsmx_addKl; apply: val_submodP.
Qed.
Lemma mxrank_in_factmod m (W : 'M_(m, n)) :
@@ -1245,7 +1243,7 @@ Lemma envelop_mxP A :
reflect (exists a, A = \sum_(x in G) a x *: rG x) (A \in E_G)%MS.
Proof.
have G_1 := group1 G; have bijG := enum_val_bij_in G_1.
-set h := enum_val in bijG; have Gh: h _ \in G by exact: enum_valP.
+set h := enum_val in bijG; have Gh: h _ \in G by apply: enum_valP.
apply: (iffP submxP) => [[u defA] | [a ->]].
exists (fun x => u 0 (enum_rank_in G_1 x)); apply: (can_inj mxvecK).
rewrite defA mulmx_sum_row linear_sum (reindex h) //=.
@@ -1374,7 +1372,7 @@ Proof. exact/rfix_mxP. Qed.
Lemma rfix_mxS (H K : {set gT}) : H \subset K -> (rfix_mx K <= rfix_mx H)%MS.
Proof.
-by move=> sHK; apply/rfix_mxP=> x Hx; exact: rfix_mxP (subsetP sHK x Hx).
+by move=> sHK; apply/rfix_mxP=> x Hx; apply: rfix_mxP (subsetP sHK x Hx).
Qed.
Lemma rfix_mx_conjsg (H : {set gT}) x :
@@ -1437,7 +1435,7 @@ Proof. by apply/cyclic_mxP; exists 1%:M; rewrite ?mulmx1 ?envelop_mx1. Qed.
Lemma cyclic_mx_eq0 u : (cyclic_mx u == 0) = (u == 0).
Proof.
rewrite -!submx0; apply/idP/idP.
- by apply: submx_trans; exact: cyclic_mx_id.
+ by apply: submx_trans; apply: cyclic_mx_id.
move/submx0null->; rewrite genmxE; apply/row_subP=> i.
by rewrite row_mul mul_rV_lin1 /= mul0mx ?sub0mx.
Qed.
@@ -1529,7 +1527,7 @@ Lemma mx_iso_sym U V : mx_iso U V -> mx_iso V U.
Proof.
case=> f injf homUf defV; exists (invmx f); first by rewrite unitmx_inv.
by rewrite dom_hom_invmx // -defV submxMr.
-by rewrite -[U](mulmxK injf); exact: eqmxMr (eqmx_sym _).
+by rewrite -[U](mulmxK injf); apply: eqmxMr (eqmx_sym _).
Qed.
Lemma mx_iso_trans U V W : mx_iso U V -> mx_iso V W -> mx_iso U W.
@@ -1537,7 +1535,7 @@ Proof.
case=> f injf homUf defV [g injg homVg defW].
exists (f *m g); first by rewrite unitmx_mul injf.
by apply/hom_mxP=> x Gx; rewrite !mulmxA 2?(hom_mxP _) ?defV.
-by rewrite mulmxA; exact: eqmx_trans (eqmxMr g defV) defW.
+by rewrite mulmxA; apply: eqmx_trans (eqmxMr g defV) defW.
Qed.
Lemma mxrank_iso U V : mx_iso U V -> \rank U = \rank V.
@@ -1545,7 +1543,7 @@ Proof. by case=> f injf _ <-; rewrite mxrankMfree ?row_free_unit. Qed.
Lemma mx_iso_module U V : mx_iso U V -> mxmodule U -> mxmodule V.
Proof.
-by case=> f _ homUf defV; rewrite -(eqmx_module defV); exact: hom_mxmodule.
+by case=> f _ homUf defV; rewrite -(eqmx_module defV); apply: hom_mxmodule.
Qed.
(* Simple modules (we reserve the term "irreducible" for representations). *)
@@ -1562,7 +1560,7 @@ Lemma mxsimpleP U :
Proof.
do [split => [] [modU nzU simU]; split] => // [V modV sVU nzV | [V]].
apply/idPn; rewrite -(ltn_leqif (mxrank_leqif_sup sVU)) => ltVU.
- by case: simU; exists V; exact/and4P.
+ by case: simU; exists V; apply/and4P.
by case/and4P=> modV sVU nzV; apply/negP; rewrite -leqNgt mxrankS ?simU.
Qed.
@@ -1578,7 +1576,7 @@ have genU := genmxE U; apply simU; exists <<U>>%MS; last by rewrite genU.
apply/mxsimpleP; split; rewrite ?(eqmx_eq0 genU) ?(eqmx_module genU) //.
case=> V; rewrite !genU=> /and4P[modV sVU nzV ltVU]; case: notF.
apply: IHr nzV _ => // [|[W simW sWV]]; first exact: leq_trans ltVU _.
-by apply: simU; exists W => //; exact: submx_trans sWV sVU.
+by apply: simU; exists W => //; apply: submx_trans sWV sVU.
Qed.
Lemma mx_iso_simple U V : mx_iso U V -> mxsimple U -> mxsimple V.
@@ -1663,19 +1661,19 @@ apply: (iffP and3P) => [[modV] | isoUV]; last first.
by case: (mx_iso_simple isoUV simU).
have [f injf homUf defV] := isoUV; apply/rowV0Pn; exists (u *m f).
rewrite sub_capmx -defV submxMr //.
- by apply/row_hom_mxP; exists f; first exact: (submx_trans Uu).
+ by apply/row_hom_mxP; exists f; first apply: (submx_trans Uu).
by rewrite -(mul0mx _ f) (can_eq (mulmxK injf)) nz_u.
case/rowV0Pn=> v; rewrite sub_capmx => /andP[Vv].
case/row_hom_mxP => f homMf def_v nz_v eqrUV.
pose uG := cyclic_mx u; pose vG := cyclic_mx v.
-have def_vG: (uG *m f :=: vG)%MS by rewrite /vG -def_v; exact: hom_cyclic_mx.
-have defU: (U :=: uG)%MS by exact: mxsimple_cyclic.
+have def_vG: (uG *m f :=: vG)%MS by rewrite /vG -def_v; apply: hom_cyclic_mx.
+have defU: (U :=: uG)%MS by apply: mxsimple_cyclic.
have mod_uG: mxmodule uG by rewrite cyclic_mx_module.
have homUf: (U <= dom_hom_mx f)%MS.
by rewrite defU cyclic_mx_sub ?dom_hom_mx_module.
have isoUf: mx_iso U (U *m f).
apply: mx_Schur_inj_iso => //; apply: contra nz_v; rewrite -!submx0.
- by rewrite (eqmxMr f defU) def_vG; exact: submx_trans (cyclic_mx_id v).
+ by rewrite (eqmxMr f defU) def_vG; apply: submx_trans (cyclic_mx_id v).
apply: mx_iso_trans (isoUf) (eqmx_iso _); apply/eqmxP.
have sUfV: (U *m f <= V)%MS by rewrite (eqmxMr f defU) def_vG cyclic_mx_sub.
by rewrite -mxrank_leqif_eq ?eqn_leq 1?mxrankS // -(mxrank_iso isoUf).
@@ -1684,7 +1682,7 @@ Qed.
Lemma mxsimple_iso_simple U V :
mxsimple_iso U V -> mxsimple U -> mxsimple V.
Proof.
-by move=> isoUV simU; apply: mx_iso_simple (simU); exact/mxsimple_isoP.
+by move=> isoUV simU; apply: mx_iso_simple (simU); apply/mxsimple_isoP.
Qed.
(* For us, "semisimple" means "sum of simple modules"; this is classically, *)
@@ -1713,7 +1711,7 @@ exists J; split=> //; apply/eqmxP; rewrite addsmx_sub sUV; apply/andP; split.
by apply/sumsmx_subP=> i Ji; rewrite (sumsmx_sup i).
rewrite -/(V_ J); apply/sumsmx_subP=> i _.
case Ji: (i \in J).
- by apply: submx_trans (addsmxSr _ _); exact: (sumsmx_sup i).
+ by apply: submx_trans (addsmxSr _ _); apply: (sumsmx_sup i).
have [modWi nzWi simWi] := simW i.
rewrite (sameP capmx_idPl eqmxP) simWi ?capmxSl ?capmx_module ?addsmx_module //.
apply: contraFT (Ji); rewrite negbK => dxWiUVJ.
@@ -1754,7 +1752,7 @@ rewrite addsmxC big1 ?adds0mx_id => [|i /andP[_ /eqP] //].
set tI := 'I_(_); set r_ := nth _ _ => defV.
have{simW} simWr (i : tI) : mxsimple (W (r_ i)).
case: i => m /=; set Pr := fun i => _ => lt_m_r /=.
- suffices: (Pr (r_ m)) by case/andP; exact: simW.
+ suffices: (Pr (r_ m)) by case/andP; apply: simW.
apply: all_nthP m lt_m_r; apply/all_filterP.
by rewrite -filter_predI; apply: eq_filter => i; rewrite /= andbb.
have [J []] := sum_mxsimple_direct_sub simWr defV.
@@ -1763,7 +1761,7 @@ case: (set_0Vmem J) => [-> V0 | [j0 Jj0]].
pose K := {j | j \in J}; pose k0 : K := Sub j0 Jj0.
have bij_KJ: {on J, bijective (sval : K -> _)}.
by exists (insubd k0) => [k _ | j Jj]; rewrite ?valKd ?insubdK.
-have J_K (k : K) : sval k \in J by exact: valP k.
+have J_K (k : K) : sval k \in J by apply: valP k.
rewrite mxdirectE /= !(reindex _ bij_KJ) !(eq_bigl _ _ J_K) -mxdirectE /= -/tI.
exact: MxSemisimple.
Qed.
@@ -1779,7 +1777,7 @@ Lemma addsmx_semisimple U V :
Proof.
case=> [I W /= simW defU _] [J T /= simT defV _].
have defUV: (\sum_ij sum_rect (fun _ => 'M_n) W T ij :=: U + V)%MS.
- by rewrite big_sumType /=; exact: adds_eqmx.
+ by rewrite big_sumType /=; apply: adds_eqmx.
by apply: intro_mxsemisimple defUV _; case=> /=.
Qed.
@@ -1792,7 +1790,7 @@ Qed.
Lemma eqmx_semisimple U V : (U :=: V)%MS -> mxsemisimple U -> mxsemisimple V.
Proof.
-by move=> eqUV [I W S simW defU dxS]; exists I W => //; exact: eqmx_trans eqUV.
+by move=> eqUV [I W S simW defU dxS]; exists I W => //; apply: eqmx_trans eqUV.
Qed.
Lemma hom_mxsemisimple (V f : 'M_n) :
@@ -1800,7 +1798,7 @@ Lemma hom_mxsemisimple (V f : 'M_n) :
Proof.
case=> I W /= simW defV _; rewrite -defV => /sumsmx_subP homWf.
have{defV} defVf: (\sum_i W i *m f :=: V *m f)%MS.
- by apply: eqmx_trans (eqmx_sym _) (eqmxMr f defV); exact: sumsmxMr.
+ by apply: eqmx_trans (eqmx_sym _) (eqmxMr f defV); apply: sumsmxMr.
apply: (intro_mxsemisimple defVf) => i _ nzWf.
by apply: mx_iso_simple (simW i); apply: mx_Schur_inj_iso; rewrite ?homWf.
Qed.
@@ -1872,7 +1870,7 @@ Proof.
move=> modV redV [] // nssimV; move: {-1}_.+1 (ltnSn (\rank V)) => r leVr.
elim: r => // r IHr in V leVr modV redV nssimV.
have [V0 | nzV] := eqVneq V 0.
- by rewrite nssimV ?V0 //; exact: mxsemisimple0.
+ by rewrite nssimV ?V0 //; apply: mxsemisimple0.
apply (mxsimple_exists modV nzV) => [[U simU sUV]]; have [modU nzU _] := simU.
have [W modW defUW dxUW] := redV U modU sUV.
have sWV: (W <= V)%MS by rewrite -defUW addsmxSr.
@@ -1964,7 +1962,7 @@ rewrite [in compU]unlock; apply/genmxP/andP; split; last first.
by apply/sumsmx_subP => i _; rewrite (sumsmx_sup (sval i)).
apply/sumsmx_subP => i _.
case i0: (r_nz i); first by rewrite (sumsmx_sup (Sub i i0)).
-by move/negbFE: i0; rewrite -cyclic_mx_eq0 => /eqP->; exact: sub0mx.
+by move/negbFE: i0; rewrite -cyclic_mx_eq0 => /eqP->; apply: sub0mx.
Qed.
Lemma component_mx_semisimple : mxsemisimple compU.
@@ -2027,7 +2025,7 @@ move=> simU simV; apply: (iffP eqP) => isoUV.
by apply: component_mx_iso; rewrite ?isoUV ?component_mx_id.
rewrite -(genmx_component U) -(genmx_component V); apply/genmxP.
wlog suffices: U V simU simV isoUV / (component_mx U <= component_mx V)%MS.
- by move=> IH; rewrite !IH //; exact: mx_iso_sym.
+ by move=> IH; rewrite !IH //; apply: mx_iso_sym.
have [I [W isoWU ->]] := component_mx_def simU.
apply/sumsmx_subP => i _; apply: mx_iso_component => //.
exact: mx_iso_trans (mx_iso_sym isoUV) (isoWU i).
@@ -2041,7 +2039,7 @@ move=> simU simV neUV; apply: contraNeq neUV => ntUV.
apply: (mxsimple_exists _ ntUV) => [|[W simW]].
by rewrite capmx_module ?component_mx_module.
rewrite sub_capmx => /andP[sWU sWV]; apply/component_mx_isoP=> //.
-by apply: mx_iso_trans (_ : mx_iso U W) (mx_iso_sym _); exact: component_mx_iso.
+by apply: mx_iso_trans (_ : mx_iso U W) (mx_iso_sym _); apply: component_mx_iso.
Qed.
Section Socle.
@@ -2054,7 +2052,7 @@ Record socleType := EnumSocle {
Lemma socle_exists : classically socleType.
Proof.
-pose V : 'M[F]_n := 0; have: mxsemisimple V by exact: mxsemisimple0.
+pose V : 'M[F]_n := 0; have: mxsemisimple V by apply: mxsemisimple0.
have: n - \rank V < n.+1 by rewrite mxrank0 subn0.
elim: _.+1 V => // n' IHn' V; rewrite ltnS => le_nV_n' ssimV.
case=> // maxV; apply: (maxV); have [I /= U simU defV _] := ssimV.
@@ -2063,12 +2061,12 @@ suffices sMV: (M <= V)%MS.
rewrite -defV -(mulmx1 (\sum_i _)%MS) in sMV.
have [//| i _] := hom_mxsemisimple_iso simM _ (scalar_mx_hom _ _) sMV.
move/mx_iso_sym=> isoM; apply/hasP.
- exists (U i); [exact: codom_f | exact/mxsimple_isoP].
+ by exists (U i); [apply: codom_f | apply/mxsimple_isoP].
have ssimMV := addsmx_semisimple (mxsimple_semisimple simM) ssimV.
apply: contraLR isT => nsMV; apply: IHn' ssimMV _ maxV.
apply: leq_trans le_nV_n'; rewrite ltn_sub2l //.
rewrite ltn_neqAle rank_leq_row andbT -[_ == _]sub1mx.
- apply: contra nsMV; apply: submx_trans; exact: submx1.
+ by apply: contra nsMV; apply: submx_trans; apply: submx1.
rewrite (ltn_leqif (mxrank_leqif_sup _)) ?addsmxSr //.
by rewrite addsmx_sub submx_refl andbT.
Qed.
@@ -2083,7 +2081,7 @@ Lemma component_socle M : mxsimple M -> component_mx M \in socle_enum.
Proof.
rewrite /socle_enum; case: sG0 => e0 /= sim_e mem_e simM.
have /hasP[M' e0M' isoMM'] := mem_e M simM; apply/mapP; exists M' => //.
-by apply/eqP/component_mx_isoP; [|exact: sim_e | exact/mxsimple_isoP].
+by apply/eqP/component_mx_isoP; [|apply: sim_e | apply/mxsimple_isoP].
Qed.
Inductive socle_sort : predArgType := PackSocle W of W \in socle_enum.
@@ -2110,7 +2108,7 @@ Definition socle_repr W := submod_repr (socle_module W).
Lemma nz_socle (W : sG) : W != 0 :> 'M_n.
Proof.
have simW := socle_simple W; have [_ nzW _] := simW; apply: contra nzW.
-by rewrite -!submx0; exact: submx_trans (component_mx_id simW).
+by rewrite -!submx0; apply: submx_trans (component_mx_id simW).
Qed.
Lemma socle_mem (W : sG) : (W : 'M_n) \in socle_enum.
@@ -2129,7 +2127,7 @@ Definition socle_choiceMixin := Eval hnf in [choiceMixin of sG by <:].
Canonical socle_choiceType := ChoiceType sG socle_choiceMixin.
Lemma socleP (W W' : sG) : reflect (W = W') (W == W')%MS.
-Proof. by rewrite (sameP genmxP eqP) !{1}genmx_component; exact: (W =P _). Qed.
+Proof. by rewrite (sameP genmxP eqP) !{1}genmx_component; apply: (W =P _). Qed.
Fact socle_finType_subproof :
cancel (fun W => SeqSub (socle_mem W)) (fun s => PackSocle (valP s)).
@@ -2154,7 +2152,7 @@ Variable P : pred sG.
Notation S := (\sum_(W : sG | P W) socle_val W)%MS.
Lemma subSocle_module : mxmodule S.
-Proof. by rewrite sumsmx_module // => W _; exact: component_mx_module. Qed.
+Proof. by rewrite sumsmx_module // => W _; apply: component_mx_module. Qed.
Lemma subSocle_semisimple : mxsemisimple S.
Proof.
@@ -2203,7 +2201,7 @@ Proof.
apply/mxdirect_sumsP=> W _; apply/eqP.
rewrite -submx0 capmx_subSocle ?component_mx_module //.
apply/sumsmx_subP=> W' /andP[_ neWW'].
-by rewrite capmxC component_mx_disjoint //; exact: socle_simple.
+by rewrite capmxC component_mx_disjoint //; apply: socle_simple.
Qed.
Definition Socle := (\sum_(W : sG) W)%MS.
@@ -2216,7 +2214,7 @@ Qed.
Lemma semisimple_Socle U : mxsemisimple U -> (U <= Socle)%MS.
Proof.
-by case=> I M /= simM <- _; apply/sumsmx_subP=> i _; exact: simple_Socle.
+by case=> I M /= simM <- _; apply/sumsmx_subP=> i _; apply: simple_Socle.
Qed.
Lemma reducible_Socle U :
@@ -2273,7 +2271,7 @@ by rewrite -mulmxA -cGf // mulmxA mulmx_ker mul0mx.
Qed.
Lemma centgmx_hom m (U : 'M_(m, n)) : centgmx rG f -> (U <= dom_hom_mx f)%MS.
-Proof. by rewrite -row_full_dom_hom -sub1mx; exact: submx_trans (submx1 _). Qed.
+Proof. by rewrite -row_full_dom_hom -sub1mx; apply: submx_trans (submx1 _). Qed.
End CentHom.
@@ -2307,7 +2305,7 @@ Lemma mx_abs_irrP :
mx_absolutely_irreducible.
Proof.
have G_1 := group1 G; have bijG := enum_val_bij_in G_1.
-set h := enum_val in bijG; have Gh : h _ \in G by exact: enum_valP.
+set h := enum_val in bijG; have Gh : h _ \in G by apply: enum_valP.
rewrite /mx_absolutely_irreducible; case: (n > 0); last by right; case.
apply: (iffP row_fullP) => [[E' E'G] | [_ [a_ a_G]]].
split=> //; exists (fun x B => (mxvec B *m E') 0 (enum_rank_in G_1 x)) => B.
@@ -2391,7 +2389,7 @@ Variable rG : mx_representation F G n.
Lemma envelop_mx_ring : mxring (enveloping_algebra_mx rG).
Proof.
-apply/andP; split; first by apply/mulsmx_subP; exact: envelop_mxM.
+apply/andP; split; first by apply/mulsmx_subP; apply: envelop_mxM.
apply/mxring_idP; exists 1%:M; split=> *; rewrite ?mulmx1 ?mul1mx //.
by rewrite -mxrank_eq0 mxrank1.
exact: envelop_mx1.
@@ -2500,17 +2498,17 @@ Lemma rstabs_subg : rstabs rH U = H :&: rstabs rG U.
Proof. by apply/setP=> x; rewrite !inE andbA -in_setI (setIidPl sHG). Qed.
Lemma mxmodule_subg : mxmodule rG U -> mxmodule rH U.
-Proof. by rewrite /mxmodule rstabs_subg subsetI subxx; exact: subset_trans. Qed.
+Proof. by rewrite /mxmodule rstabs_subg subsetI subxx; apply: subset_trans. Qed.
End Stabilisers.
Lemma mxsimple_subg M : mxmodule rG M -> mxsimple rH M -> mxsimple rG M.
Proof.
-by move=> modM [_ nzM minM]; split=> // U /mxmodule_subg; exact: minM.
+by move=> modM [_ nzM minM]; split=> // U /mxmodule_subg; apply: minM.
Qed.
Lemma subg_mx_irr : mx_irreducible rH -> mx_irreducible rG.
-Proof. by apply: mxsimple_subg; exact: mxmodule1. Qed.
+Proof. by apply: mxsimple_subg; apply: mxmodule1. Qed.
Lemma subg_mx_abs_irr :
mx_absolutely_irreducible rH -> mx_absolutely_irreducible rG.
@@ -2734,7 +2732,7 @@ by rewrite val_factmod_module (eqmx_module _ (in_factmod_addsK _ _)).
Qed.
Lemma rker_submod : rker rU = rstab rG U.
-Proof. by rewrite /rker rstab_submod; exact: eqmx_rstab (val_submod1 U). Qed.
+Proof. by rewrite /rker rstab_submod; apply: eqmx_rstab (val_submod1 U). Qed.
Lemma rstab_norm : G \subset 'N(rstab rG U).
Proof. by rewrite -rker_submod rker_norm. Qed.
@@ -2807,7 +2805,7 @@ Proof.
have Bfree: row_free B by rewrite row_free_unit.
split => /mx_irrP[n_gt0 irrG]; apply/mx_irrP; split=> // U.
rewrite -[U](mulmxKV uB) -mxmodule_conj -mxrank_eq0 /row_full mxrankMfree //.
- by rewrite mxrank_eq0; exact: irrG.
+ by rewrite mxrank_eq0; apply: irrG.
rewrite -mxrank_eq0 /row_full -(mxrankMfree _ Bfree) mxmodule_conj mxrank_eq0.
exact: irrG.
Qed.
@@ -2882,7 +2880,7 @@ Lemma quotient_splitting_field gT (G : {group gT}) (H : {set gT}) :
G \subset 'N(H) -> group_splitting_field G -> group_splitting_field (G / H).
Proof.
move=> nHG splitG n rGH irrGH.
-by rewrite -(morphim_mx_abs_irr _ nHG) splitG //; exact/morphim_mx_irr.
+by rewrite -(morphim_mx_abs_irr _ nHG) splitG //; apply/morphim_mx_irr.
Qed.
Lemma coset_splitting_field gT (H : {set gT}) :
@@ -2890,7 +2888,7 @@ Lemma coset_splitting_field gT (H : {set gT}) :
Proof.
move=> split_gT Gbar; have ->: Gbar = (coset H @*^-1 Gbar / H)%G.
by apply: val_inj; rewrite /= /quotient morphpreK ?sub_im_coset.
-by apply: quotient_splitting_field; [exact: subsetIl | exact: split_gT].
+by apply: quotient_splitting_field; [apply: subsetIl | apply: split_gT].
Qed.
End SplittingField.
@@ -2958,9 +2956,9 @@ Lemma der1_sub_rker :
group_splitting_field G -> mx_irreducible rG ->
(G^`(1) \subset rker rG)%g = (n == 1)%N.
Proof.
-move=> splitG irrG; apply/idP/idP; last by move/eqP; exact: rker_linear.
+move=> splitG irrG; apply/idP/idP; last by move/eqP; apply: rker_linear.
move/sub_der1_abelian; move/(abelian_abs_irr (kquo_repr rG))=> <-.
-by apply: (quotient_splitting_field (rker_norm _) splitG); exact/quo_mx_irr.
+by apply: (quotient_splitting_field (rker_norm _) splitG); apply/quo_mx_irr.
Qed.
End AbelianQuotient.
@@ -3086,7 +3084,7 @@ Proof.
move=> addUV dxUV.
have eqUV: \rank U = \rank (cokermx V).
by rewrite mxrank_coker -{3}(mxrank1 F n) -addUV (mxdirectP dxUV) addnK.
-have{dxUV} dxUV: (U :&: V = 0)%MS by exact/mxdirect_addsP.
+have{dxUV} dxUV: (U :&: V = 0)%MS by apply/mxdirect_addsP.
exists (in_submod U (val_factmod 1%:M *m proj_mx U V)) => // [|x Gx].
rewrite /row_free -{6}eqUV -[_ == _]sub1mx -val_submodS val_submod1.
rewrite in_submodK ?proj_mx_sub // -{1}[U](proj_mx_id dxUV) //.
@@ -3121,13 +3119,13 @@ Variables (gT : finGroupType) (G : {group gT}).
Variables (n : nat) (rG : mx_representation F G n) (sG : socleType rG).
Lemma socle_irr (W : sG) : mx_irreducible (socle_repr W).
-Proof. by apply/submod_mx_irr; exact: socle_simple. Qed.
+Proof. by apply/submod_mx_irr; apply: socle_simple. Qed.
Lemma socle_rsimP (W1 W2 : sG) :
reflect (mx_rsim (socle_repr W1) (socle_repr W2)) (W1 == W2).
Proof.
have [simW1 simW2] := (socle_simple W1, socle_simple W2).
-by apply: (iffP (component_mx_isoP simW1 simW2)); move/mx_rsim_iso; exact.
+by apply: (iffP (component_mx_isoP simW1 simW2)); move/mx_rsim_iso; apply.
Qed.
Local Notation mG U := (mxmodule rG U).
@@ -3160,7 +3158,7 @@ Qed.
Lemma mxtrace_submod1 U (modU : mG U) :
(U :=: 1%:M)%MS -> {in G, forall x, \tr (sr modU x) = \tr (rG x)}.
-Proof. by move=> defU; exact: mxtrace_rsim (rsim_submod1 modU defU). Qed.
+Proof. by move=> defU; apply: mxtrace_rsim (rsim_submod1 modU defU). Qed.
Lemma mxtrace_dadd_mod U V W (modU : mG U) (modV : mG V) (modW : mG W) :
(U + V :=: W)%MS -> mxdirect (U + V) ->
@@ -3213,9 +3211,9 @@ have isoW i: mx_iso rG U (W i).
have ->: (\rank V %/ \rank U)%N = #|I|.
symmetry; rewrite -(mulnK #|I| rankU_gt0); congr (_ %/ _)%N.
rewrite -defV (mxdirectP dxV) /= -sum_nat_const.
- by apply: eq_bigr => i _; exact: mxrank_iso.
+ by apply: eq_bigr => i _; apply: mxrank_iso.
rewrite -sumr_const; apply: eq_bigr => i _; symmetry.
-by apply: mxtrace_rsim Gx; apply/mx_rsim_iso; exact: isoW.
+by apply: mxtrace_rsim Gx; apply/mx_rsim_iso; apply: isoW.
Qed.
Lemma mxtrace_Socle : let modS := Socle_module sG in
@@ -3271,7 +3269,7 @@ Lemma Clifford_iso2 x U V :
Proof.
case=> [f injf homUf defV] Gx; have Gx' := groupVr Gx.
pose fx := rG (x^-1)%g *m f *m rG x; exists fx; last 1 first.
-- by rewrite !mulmxA repr_mxK //; exact: eqmxMr.
+- by rewrite !mulmxA repr_mxK //; apply: eqmxMr.
- by rewrite !unitmx_mul andbC !repr_mx_unit.
apply/hom_mxP=> h Hh; have Gh := subsetP sHG h Hh.
rewrite -(mulmxA U) -repr_mxM // conjgCV repr_mxM ?groupJ // !mulmxA.
@@ -3287,10 +3285,10 @@ set simH := mxsimple rH; set cH := component_mx rH.
have actG: {in G, forall y M, simH M -> cH M *m rG y <= cH (M *m rG y)}%MS.
move=> {M} y Gy /= M simM; have [I [U isoU def_cHM]] := component_mx_def simM.
rewrite /cH def_cHM sumsmxMr; apply/sumsmx_subP=> i _.
- by apply: mx_iso_component; [exact: Clifford_simple | exact: Clifford_iso2].
+ by apply: mx_iso_component; [apply: Clifford_simple | apply: Clifford_iso2].
move=> simM Gx; apply/eqmxP; rewrite actG // -/cH.
rewrite -{1}[cH _](repr_mxKV rG Gx) submxMr // -{2}[M](repr_mxK rG Gx).
-by rewrite actG ?groupV //; exact: Clifford_simple.
+by rewrite actG ?groupV //; apply: Clifford_simple.
Qed.
Hypothesis irrG : mx_irreducible rG.
@@ -3300,7 +3298,7 @@ Lemma Clifford_basis M : mxsimple rH M ->
let S := \sum_(x in X) M *m rG x in S :=: 1%:M /\ mxdirect S}%MS.
Proof.
move=> simM. have simMG (g : [subg G]) : mxsimple rH (M *m rG (val g)).
- by case: g => x Gx; exact: Clifford_simple.
+ by case: g => x Gx; apply: Clifford_simple.
have [|XG [defX1 dxX1]] := sum_mxsimple_direct_sub simMG (_ : _ :=: 1%:M)%MS.
apply/eqmxP; case irrG => _ _ ->; rewrite ?submx1 //; last first.
rewrite -submx0; apply/sumsmx_subP; move/(_ 1%g (erefl _)); apply: negP.
@@ -3333,7 +3331,8 @@ Proof.
split=> [x W W' eqWW' | W x y Gx Gy].
pose Gx := subgP (subg G x); apply/socleP; apply/eqmxP.
rewrite -(repr_mxK rG Gx W) -(repr_mxK rG Gx W'); apply: eqmxMr.
- apply: eqmx_trans (eqmx_sym _) (valWact _ _); rewrite -eqWW'; exact: valWact.
+ apply: eqmx_trans (eqmx_sym _) (valWact _ _).
+ by rewrite -eqWW'; apply: valWact.
apply/socleP; rewrite !{1}valWact 2!{1}(eqmxMr _ (valWact _ _)).
by rewrite !subgK ?groupM ?repr_mxM ?mulmxA ?andbb.
Qed.
@@ -3361,7 +3360,7 @@ have Gx := sXG x Xx; apply/imsetP; exists x => //; apply/socleP/eqmxP/eqmx_sym.
apply: eqmx_trans (val_Clifford_act _ Gx) _; rewrite PackSocleK.
apply: eqmx_trans (eqmx_sym (Clifford_componentJ simM Gx)) _.
apply/eqmxP; rewrite (sameP genmxP eqP) !{1}genmx_component.
-by apply/component_mx_isoP=> //; exact: Clifford_simple.
+by apply/component_mx_isoP=> //; apply: Clifford_simple.
Qed.
Lemma Clifford_Socle1 : Socle sH = 1%:M.
@@ -3431,15 +3430,15 @@ Proof.
rewrite join_subG !subsetI sHG subsetIl /=; apply/andP; split.
apply/subsetP=> h Hh; have Gh := subsetP sHG h Hh; rewrite inE.
apply/subsetP=> W _; have simW := socle_simple W; have [modW _ _] := simW.
- have simWh: mxsimple rH (socle_base W *m rG h) by exact: Clifford_simple.
+ have simWh: mxsimple rH (socle_base W *m rG h) by apply: Clifford_simple.
rewrite inE -val_eqE /= PackSocleK eq_sym.
apply/component_mx_isoP; rewrite ?subgK //; apply: component_mx_iso => //.
by apply: submx_trans (component_mx_id simW); move/mxmoduleP: modW => ->.
apply/subsetP=> z cHz; have [Gz _] := setIP cHz; rewrite inE.
apply/subsetP=> W _; have simW := socle_simple W; have [modW _ _] := simW.
-have simWz: mxsimple rH (socle_base W *m rG z) by exact: Clifford_simple.
+have simWz: mxsimple rH (socle_base W *m rG z) by apply: Clifford_simple.
rewrite inE -val_eqE /= PackSocleK eq_sym.
-by apply/component_mx_isoP; rewrite ?subgK //; exact: Clifford_iso.
+by apply/component_mx_isoP; rewrite ?subgK //; apply: Clifford_iso.
Qed.
Lemma Clifford_astab1 (W : sH) : 'C[W | 'Cl] = rstabs rG W.
@@ -3592,7 +3591,7 @@ split=> [ [/andP[modU modV] maxU] | [[modU maxU] modV maxV]].
by split=> // i ltiU; have:= maxU i (ltnW ltiU); rewrite !nth_rcons leqW ltiU.
rewrite modV; split=> // i; rewrite !nth_rcons ltnS leq_eqVlt.
case: eqP => [-> _ | /= _ ltiU]; first by rewrite ltnn ?eqxx -last_nth.
-by rewrite ltiU; exact: maxU.
+by rewrite ltiU; apply: maxU.
Qed.
Theorem mx_Schreier U :
@@ -3620,7 +3619,7 @@ set U' := take i U; set U'' := drop _ U; case/and3P=> incU' ltUi incU''.
split=> // W [modW ltUW ltWV]; case: notF.
apply: {IH_U}(IH_U (U' ++ W :: Ui :: U'')) noV; last 2 first.
- by rewrite /mx_subseries -drop_nth // all_cat /= modW -all_cat defU.
-- by rewrite cat_path /= -defU'i; exact/and4P.
+- by rewrite cat_path /= -defU'i; apply/and4P.
- by rewrite -drop_nth // size_cat /= addnS -size_cat defU addSnnS.
by rewrite (subseq_trans sU0U) // -defU cat_subseq // -drop_nth ?subseq_cons.
Qed.
@@ -3686,7 +3685,7 @@ Qed.
Lemma section_eqmx U1 U2 V1 V2 modU1 modU2 modV1 modV2
(eqU : (U1 :=: U2)%MS) (eqV : (V1 :=: V2)%MS) :
mx_rsim (@section_repr U1 V1 modU1 modV1) (@section_repr U2 V2 modU2 modV2).
-Proof. by apply: section_eqmx_add => //; exact: adds_eqmx. Qed.
+Proof. by apply: section_eqmx_add => //; apply: adds_eqmx. Qed.
Lemma mx_butterfly U V W modU modV modW :
~~ (U == V)%MS -> max_submod U W -> max_submod V W ->
@@ -3696,16 +3695,16 @@ Lemma mx_butterfly U V W modU modV modW :
Proof.
move=> neUV maxU maxV modUV; have{neUV maxU} defW: (U + V :=: W)%MS.
wlog{neUV modUV} ltUV: U V modU modV maxU maxV / ~~ (V <= U)%MS.
- by case/nandP: neUV => ?; first rewrite addsmxC; exact.
+ by case/nandP: neUV => ?; first rewrite addsmxC; apply.
apply/eqmxP/idPn=> neUVW; case: maxU => ltUW; case/(_ (U + V)%MS).
rewrite addsmx_module // ltmxE ltmxEneq neUVW addsmxSl !addsmx_sub.
by have [ltVW _] := maxV; rewrite submx_refl andbT ltUV !ltmxW.
have sUV_U := capmxSl U V; have sVW: (V <= W)%MS by rewrite -defW addsmxSr.
set goal := mx_rsim _ _; suffices{maxV} simUV: goal.
split=> //; apply/(max_submodP modUV modU sUV_U).
- by apply: mx_rsim_irr simUV _; exact/max_submodP.
+ by apply: mx_rsim_irr simUV _; apply/max_submodP.
apply: {goal}mx_rsim_sym.
-by apply: mx_rsim_trans (mx_second_rsim modU modV) _; exact: section_eqmx.
+by apply: mx_rsim_trans (mx_second_rsim modU modV) _; apply: section_eqmx.
Qed.
Lemma mx_JordanHolder_exists U V :
@@ -3719,7 +3718,7 @@ case eqUV: (last 0 U == V)%MS.
by rewrite andbC; move/eqmx0P->; exists [::].
rewrite last_rcons; move/eqmxP=> eqU'V; case/mx_series_rcons=> compU _ maxUm'.
exists (rcons U' V); last by rewrite last_rcons.
- apply/mx_series_rcons; split => //; exact: max_submod_eqmx maxUm'.
+ by apply/mx_series_rcons; split => //; apply: max_submod_eqmx maxUm'.
set Um' := last 0 U in maxUm eqUV; have [modU _] := compU.
have modUm': modG Um' by rewrite /Um' (last_nth 0) mx_subseries_module'.
have [|||W compW lastW] := IHU (V :&: Um')%MS; rewrite ?capmx_module //.
@@ -3771,12 +3770,12 @@ have [eqUVm' | neqUVm'] := altP (@eqmxP _ _ _ _ Um' Vm').
split; first by rewrite szV.
exists (lift_perm i_m i_m p) => i; case: (unliftP i_m i) => [j|] ->{i}.
apply: rsimT (rsimC _) (rsimT (sim_p j) _).
- by rewrite lift_max; exact: rsim_rcons.
+ by rewrite lift_max; apply: rsim_rcons.
by rewrite lift_perm_lift lift_max; apply: rsim_rcons; rewrite -szV.
have simUVm := section_eqmx modUm' modVm' modUm modVm eqUVm' eqUVm.
apply: rsimT (rsimC _) (rsimT simUVm _); first exact: rsim_last.
- by rewrite lift_perm_id /= szV; exact: rsim_last.
-have maxVUm: max_submod Vm' Um by exact: max_submod_eqmx (eqmx_sym _) maxVm.
+ by rewrite lift_perm_id /= szV; apply: rsim_last.
+have maxVUm: max_submod Vm' Um by apply: max_submod_eqmx (eqmx_sym _) maxVm.
have:= mx_butterfly modUm' modVm' modUm neqUVm' maxUm maxVUm.
move: (capmx_module _ _); set Wm := (Um' :&: Vm')%MS => modWm [maxWUm simWVm].
have:= mx_butterfly modVm' modUm' modUm _ maxVUm maxUm.
@@ -3795,19 +3794,19 @@ rewrite !permM; case: (unliftP i_m i) => [j {simWUm}|] ->{i}; last first.
rewrite lift_perm_id tpermL lift_perm_lift lift_max {simWVm}.
apply: rsimT (rsimT (pWV j_m) _); last by apply: rsim_rcons; rewrite -szV.
apply: rsimT (rsimC _) {simWUm}(rsimT simWUm _); first exact: rsim_last.
- by rewrite -lastW in modWm *; exact: rsim_last.
+ by rewrite -lastW in modWm *; apply: rsim_last.
apply: rsimT (rsimC _) {pUW}(rsimT (pUW j) _).
- by rewrite lift_max; exact: rsim_rcons.
+ by rewrite lift_max; apply: rsim_rcons.
rewrite lift_perm_lift; case: (unliftP j_m (pU j)) => [k|] ->{j pU}.
rewrite tpermD ?(inj_eq (@lift_inj _ _)) ?neq_lift //.
rewrite lift_perm_lift !lift_max; set j := lift j_m k.
have ltjW: j < size W by have:= ltn_ord k; rewrite -(lift_max k) /= {1 3}szW.
apply: rsimT (rsimT (pWV j) _); last by apply: rsim_rcons; rewrite -szV.
- by apply: rsimT (rsimC _) (rsim_rcons compW _ _); first exact: rsim_rcons.
+ by apply: rsimT (rsimC _) (rsim_rcons compW _ _); first apply: rsim_rcons.
apply: rsimT {simWVm}(rsimC (rsimT simWVm _)) _.
- by rewrite -lastW in modWm *; exact: rsim_last.
+ by rewrite -lastW in modWm *; apply: rsim_last.
rewrite tpermR lift_perm_id /= szV.
-by apply: rsimT (rsim_last modVm' modVm _); exact: section_eqmx.
+by apply: rsimT (rsim_last modVm' modVm _); apply: section_eqmx.
Qed.
Lemma mx_JordanHolder_max U (m := size U) V compU modV :
@@ -3818,7 +3817,7 @@ rewrite {}/m; set Um := last 0 U => Um1 irrV.
have modUm: modG Um := last_mod compU; have simV := rsimC (mx_factmod_sub modV).
have maxV: max_submod V Um.
move/max_submodP: (mx_rsim_irr simV irrV) => /(_ (submx1 _)).
- by apply: max_submod_eqmx; last exact: eqmx_sym.
+ by apply: max_submod_eqmx; last apply: eqmx_sym.
have [W compW lastW] := mx_JordanHolder_exists compU modV maxV.
have compWU: mx_series (rcons W Um) by apply/mx_series_rcons; rewrite lastW.
have:= mx_JordanHolder compU compWU; rewrite last_rcons size_rcons.
@@ -3920,7 +3919,7 @@ Proof.
move=> lastU; have [V [modV simGV]] := rsim_regular_factmod.
have irrV := mx_rsim_irr simGV irrG.
have [i simVU] := mx_JordanHolder_max compU lastU irrV.
-exists i; exact: mx_rsim_trans simGV simVU.
+by exists i; apply: mx_rsim_trans simGV simVU.
Qed.
Hypothesis F'G : [char F]^'.-group G.
@@ -3943,7 +3942,7 @@ Local Notation tG := #|pred_of_set (classes (gval G))|.
Definition classg_base := \matrix_(k < tG) mxvec (gset_mx (enum_val k)).
Let groupCl : {in G, forall x, {subset x ^: G <= G}}.
-Proof. by move=> x Gx; apply: subsetP; exact: class_subG. Qed.
+Proof. by move=> x Gx; apply: subsetP; apply: class_subG. Qed.
Lemma classg_base_free : row_free classg_base.
Proof.
@@ -3960,7 +3959,7 @@ rewrite rowK !linearZ /= mxvecK -(inj_eq enum_val_inj) def_k eq_sym.
have [z Gz ->] := imsetP (enum_valP k').
move/eqP=> not_Gxz; rewrite linear_sum big1 ?scaler0 //= => y zGy.
rewrite gring_projE ?(groupCl Gz zGy) //.
-by case: eqP zGy => // <- /class_transr.
+by case: eqP zGy => // <- /class_eqP.
Qed.
Lemma classg_base_center : (classg_base :=: 'Z(R_G))%MS.
@@ -4080,7 +4079,7 @@ Qed.
Lemma degree_irr1 : 'n_1 = 1%N.
Proof.
apply/eqP; rewrite eqn_leq irr_degree_gt0 -rank_irr1.
-by rewrite mxrankS ?component_mx_id //; exact: socle_simple.
+by rewrite mxrankS ?component_mx_id //; apply: socle_simple.
Qed.
Definition Wedderburn_subring (i : sG) := <<i *m R_G>>%MS.
@@ -4144,7 +4143,7 @@ Qed.
Hypothesis F'G : [char F]^'.-group G.
Lemma irr_mx_sum : (\sum_(i : sG) i = 1%:M)%MS.
-Proof. by apply: reducible_Socle1; exact: mx_Maschke. Qed.
+Proof. by apply: reducible_Socle1; apply: mx_Maschke. Qed.
Lemma Wedderburn_sum : (\sum_i 'R_i :=: R_G)%MS.
Proof. by apply: eqmx_trans sums_R _; rewrite /Socle irr_mx_sum mul1mx. Qed.
@@ -4195,7 +4194,7 @@ Qed.
Lemma Wedderburn_is_ring i : mxring 'R_i.
Proof.
rewrite /mxring /left_mx_ideal Wedderburn_closed submx_refl.
-by apply/mxring_idP; exists 'e_i; exact: Wedderburn_is_id.
+by apply/mxring_idP; exists 'e_i; apply: Wedderburn_is_id.
Qed.
Lemma Wedderburn_min_ideal m i (E : 'A_(m, nG)) :
@@ -4249,7 +4248,7 @@ transitivity (f *m in_submod _ (val_submod 1%:M *m A) *m f').
rewrite (_ : _ *m A = 0) ?(linear0, mul0mx) //.
apply/row_matrixP=> i; rewrite row_mul row0 -[row _ _]gring_mxK -gring_row_mul.
rewrite (Wedderburn_mulmx0 ne_iG_j) ?linear0 // genmxE mem_gring_mx.
-by rewrite (row_subP _) // val_submod1 component_mx_id //; exact: socle_simple.
+by rewrite (row_subP _) // val_submod1 component_mx_id //; apply: socle_simple.
Qed.
Definition irr_comp := odflt 1%irr [pick i | gring_op rG 'e_i != 0].
@@ -4285,7 +4284,7 @@ by move/eqP: (G0 j).
Qed.
Lemma irr_comp'_op0 j A : j != iG -> (A \in 'R_j)%MS -> gring_op rG A = 0.
-Proof. by rewrite eq_sym; exact: not_rsim_op0 rsim_irr_comp. Qed.
+Proof. by rewrite eq_sym; apply: not_rsim_op0 rsim_irr_comp. Qed.
Lemma irr_comp_envelop : ('R_iG *m lin_mx (gring_op rG) :=: E_G)%MS.
Proof.
@@ -4311,7 +4310,7 @@ case/sub_sumsmxP=> e ->; rewrite linear_sum mulmx_suml summx_sub // => j _.
rewrite -(in_submodK (submxMl _ (M j))); move: (in_submod _ _) => v.
have modMj: mxmodule aG (M j) by apply: mx_iso_module (isoM j) _; case: simMi.
have rsimMj: mx_rsim rG (submod_repr modMj).
- by apply: mx_rsim_trans rsim_irr_comp _; exact/mx_rsim_iso.
+ by apply: mx_rsim_trans rsim_irr_comp _; apply/mx_rsim_iso.
have [f [f' _ hom_f]] := mx_rsim_def (mx_rsim_sym rsimMj); rewrite submx0.
have <-: (gring_mx aG (val_submod (v *m (f *m gring_op rG A *m f')))) = 0.
by rewrite (eqP opA0) !(mul0mx, linear0).
@@ -4352,13 +4351,13 @@ Qed.
Lemma irr_reprK i : irr_comp (irr_repr i) = i.
Proof.
apply/eqP; apply/component_mx_isoP; try exact: socle_simple.
-by move/mx_rsim_iso: (rsim_irr_comp (socle_irr i)); exact: mx_iso_sym.
+by move/mx_rsim_iso: (rsim_irr_comp (socle_irr i)); apply: mx_iso_sym.
Qed.
Lemma irr_repr'_op0 i j A :
j != i -> (A \in 'R_j)%MS -> gring_op (irr_repr i) A = 0.
Proof.
-by move=> neq_ij /irr_comp'_op0-> //; [exact: socle_irr | rewrite irr_reprK].
+by move=> neq_ij /irr_comp'_op0-> //; [apply: socle_irr | rewrite irr_reprK].
Qed.
Lemma op_Wedderburn_id i : gring_op (irr_repr i) 'e_i = 1%:M.
@@ -4380,7 +4379,7 @@ Lemma irr1_repr x : x \in G -> irr_repr 1 x = 1%:M.
Proof.
move=> Gx; suffices: x \in rker (irr_repr 1) by case/rkerP.
apply: subsetP x Gx; rewrite rker_submod rfix_mx_rstabC // -irr1_rfix.
-by apply: component_mx_id; exact: socle_simple.
+by apply: component_mx_id; apply: socle_simple.
Qed.
Hypothesis splitG : group_splitting_field G.
@@ -4415,7 +4414,7 @@ Qed.
Definition linear_irr := [set i | 'n_i == 1%N].
Lemma irr_degree_abelian : abelian G -> forall i, 'n_i = 1%N.
-Proof. by move=> cGG i; exact: mxsimple_abelian_linear (socle_simple i). Qed.
+Proof. by move=> cGG i; apply: mxsimple_abelian_linear (socle_simple i). Qed.
Lemma linear_irr_comp i : 'n_i = 1%N -> (i :=: socle_base i)%MS.
Proof.
@@ -4539,25 +4538,25 @@ Lemma card_linear_irr (sG : irrType G) :
#|linear_irr sG| = #|G : G^`(1)|%g.
Proof.
move=> F'G splitG; apply/eqP.
-wlog sGq: / irrType (G / G^`(1))%G by exact: socle_exists.
+wlog sGq: / irrType (G / G^`(1))%G by apply: socle_exists.
have [_ nG'G] := andP (der_normal 1 G); apply/eqP; rewrite -card_quotient //.
-have cGqGq: abelian (G / G^`(1))%g by exact: sub_der1_abelian.
-have F'Gq: [char F]^'.-group (G / G^`(1))%g by exact: morphim_pgroup.
+have cGqGq: abelian (G / G^`(1))%g by apply: sub_der1_abelian.
+have F'Gq: [char F]^'.-group (G / G^`(1))%g by apply: morphim_pgroup.
have splitGq: group_splitting_field (G / G^`(1))%G.
exact: quotient_splitting_field.
rewrite -(sum_irr_degree sGq) // -sum1_card.
pose rG (j : sGq) := morphim_repr (socle_repr j) nG'G.
-have irrG j: mx_irreducible (rG j) by apply/morphim_mx_irr; exact: socle_irr.
+have irrG j: mx_irreducible (rG j) by apply/morphim_mx_irr; apply: socle_irr.
rewrite (reindex (fun j => irr_comp sG (rG j))) /=.
apply: eq_big => [j | j _]; last by rewrite irr_degree_abelian.
have [_ lin_j _ _] := rsim_irr_comp sG F'G (irrG j).
by rewrite inE -lin_j -irr_degreeE irr_degree_abelian.
pose sGlin := {i | i \in linear_irr sG}.
have sG'k (i : sGlin) : G^`(1)%g \subset rker (irr_repr (val i)).
- by case: i => i /=; rewrite !inE => lin; rewrite rker_linear //=; exact/eqP.
+ by case: i => i /=; rewrite !inE => lin; rewrite rker_linear //=; apply/eqP.
pose h' u := irr_comp sGq (quo_repr (sG'k u) nG'G).
have irrGq u: mx_irreducible (quo_repr (sG'k u) nG'G).
- by apply/quo_mx_irr; exact: socle_irr.
+ by apply/quo_mx_irr; apply: socle_irr.
exists (fun i => oapp h' [1 sGq]%irr (insub i)) => [j | i] lin_i.
rewrite (insubT (mem _) lin_i) /=; apply/esym/eqP/socle_rsimP.
apply: mx_rsim_trans (rsim_irr_comp sGq F'Gq (irrGq _)).
@@ -4585,7 +4584,7 @@ case: (pickP [pred x in G | ~~ is_scalar_mx (rG x)]) => [x | scalG].
rewrite big_nat_recr //= rmorphM mxrankMfree {IHi}//.
rewrite row_free_unit rmorphB /= horner_mx_X horner_mx_C.
rewrite (mx_Schur irrG) ?subr_eq0 //; last first.
- by apply: contraNneq nscal_rGx => ->; exact: scalar_mx_is_scalar.
+ by apply: contraNneq nscal_rGx => ->; apply: scalar_mx_is_scalar.
rewrite -memmx_cent_envelop linearB.
rewrite addmx_sub ?eqmx_opp ?scalar_mx_cent //= memmx_cent_envelop.
by apply/centgmxP=> j Zh_j; rewrite -!repr_mxM // (centsP cGG).
@@ -4628,13 +4627,13 @@ have /hasP[w _ prim_w]: has #[x].-primitive_root (map r (enum sG)).
by rewrite size_map -cardE card_sG.
by apply/allP=> _ /mapP[W _ ->]; rewrite unity_rootE rx1.
have iphi'P := prim_rootP prim_w (rx1 _); pose iphi' := sval (iphi'P _).
-have def_r W: r W = w ^+ iphi' W by exact: svalP (iphi'P W).
+have def_r W: r W = w ^+ iphi' W by apply: svalP (iphi'P W).
have inj_iphi': injective iphi'.
by move=> i j eq_ij; apply: inj_r; rewrite !def_r eq_ij.
have iphiP: codom iphi' =i 'I_#[x].
by apply/subset_cardP; rewrite ?subset_predT // card_ord card_image.
pose iphi i := iinv (iphiP i); exists w => //; exists iphi.
-have iphiK: cancel iphi iphi' by move=> i; exact: f_iinv.
+have iphiK: cancel iphi iphi' by move=> i; apply: f_iinv.
have r_iphi i: r (iphi i) = w ^+ i by rewrite def_r iphiK.
split=> // [|i]; last by rewrite scalX r_iphi.
by exists iphi' => // W; rewrite /iphi iinv_f.
@@ -4645,7 +4644,7 @@ Lemma splitting_cyclic_primitive_root :
classically {z : F | #|G|.-primitive_root z}.
Proof.
case/cyclicP=> x defG F'G splitF; case=> // IH.
-wlog sG: / irrType G by exact: socle_exists.
+wlog sG: / irrType G by apply: socle_exists.
have [w prim_w _] := cycle_repr_structure sG defG F'G splitF.
by apply: IH; exists w.
Qed.
@@ -4761,10 +4760,10 @@ Lemma dec_mxsimple_exists (U : 'M_n) :
Proof.
elim: {U}_.+1 {-2}U (ltnSn (\rank U)) => // m IHm U leUm modU nzU.
have [nsimU | simU] := mxnonsimpleP nzU; last first.
- by exists U; first exact/mxsimpleP.
+ by exists U; first apply/mxsimpleP.
move: (xchooseP nsimU); move: (xchoose _) => W /and4P[modW sWU nzW ltWU].
case: (IHm W) => // [|V simV sVW]; first exact: leq_trans ltWU _.
-by exists V; last exact: submx_trans sVW sWU.
+by exists V; last apply: submx_trans sVW sWU.
Qed.
Lemma dec_mx_reducible_semisimple U :
@@ -4815,7 +4814,7 @@ case haveU: (mx_sat (exU 0%N (fun U => mxmodule_form rG U /\ ~ meetUVf _ U)%T)).
by rewrite andbC -sub_capmx.
case/andP=> nzU tiUV; have [M simM sMU] := dec_mxsimple_exists modU nzU.
apply: (IHm (M :: Ms)) => [|M']; last first.
- by case/predU1P=> [-> //|]; exact: simMs.
+ by case/predU1P=> [-> //|]; apply: simMs.
have [_ nzM _] := simM.
suffices ltVMV: \rank V < \rank (span (M :: Ms)).
rewrite (leq_trans _ Ms_ge_n) // ltn_sub2l ?(leq_trans ltVMV) //.
@@ -4834,12 +4833,12 @@ have sMV: (M <= V)%MS.
apply: contra not_sMV => /and3P[nzW Vw Mw].
have{Vw Mw} [sWV sWM]: (W <= V /\ W <= M)%MS.
rewrite !cyclic_mx_sub ?(submx_trans (nz_row_sub _)) //.
- by rewrite sumsmx_module // => M' _; exact: component_mx_module.
+ by rewrite sumsmx_module // => M' _; apply: component_mx_module.
by rewrite (submx_trans _ sWV) // minM ?cyclic_mx_module.
-wlog sG: / socleType rG by exact: socle_exists.
+wlog sG: / socleType rG by apply: socle_exists.
have sVS: (V <= \sum_(W : sG | has (fun Mi => Mi <= W) Ms) W)%MS.
rewrite [V](big_nth 0) big_mkord; apply/sumsmx_subP=> i _.
- set Mi := Ms`_i; have MsMi: Mi \in Ms by exact: mem_nth.
+ set Mi := Ms`_i; have MsMi: Mi \in Ms by apply: mem_nth.
have simMi := simMs _ MsMi; have S_Mi := component_socle sG simMi.
rewrite (sumsmx_sup (PackSocle S_Mi)) ?PackSocleK //.
by apply/hasP; exists Mi; rewrite ?component_mx_id.
@@ -4874,12 +4873,12 @@ Qed.
Lemma rcent_map A : rcent rGf A^f = rcent rG A.
Proof.
-by apply/setP=> x; rewrite !inE -!map_mxM inj_eq //; exact: map_mx_inj.
+by apply/setP=> x; rewrite !inE -!map_mxM inj_eq //; apply: map_mx_inj.
Qed.
Lemma rstab_map m (U : 'M_(m, n)) : rstab rGf U^f = rstab rG U.
Proof.
-by apply/setP=> x; rewrite !inE -!map_mxM inj_eq //; exact: map_mx_inj.
+by apply/setP=> x; rewrite !inE -!map_mxM inj_eq //; apply: map_mx_inj.
Qed.
Lemma rstabs_map m (U : 'M_(m, n)) : rstabs rGf U^f = rstabs rG U.
@@ -4967,7 +4966,7 @@ have mf_i V: nth 0^f (mf V) i = (V`_i)^f.
case: (ltnP i (size V)) => [ltiV | leVi]; first exact: nth_map.
by rewrite !nth_default ?size_map.
rewrite -(map_mx0 f) mf_i (mf_i (0 :: U)) => modUi'f modUif modUi' modUi.
-by apply: map_section_repr; exact: map_regular_repr.
+by apply: map_section_repr; apply: map_regular_repr.
Qed.
Lemma extend_group_splitting_field :
@@ -4978,7 +4977,7 @@ have modU0: all ((mxmodule (regular_repr aF G)) #|G|) [::] by [].
apply: (mx_Schreier modU0 _) => // [[U [compU lastU _]]]; have [modU _]:= compU.
pose Uf := map ((map_mx f) _ _) U.
have{lastU} lastUf: (last 0 Uf :=: 1%:M)%MS.
- by rewrite -(map_mx0 f) -(map_mx1 f) last_map; exact/map_eqmx.
+ by rewrite -(map_mx0 f) -(map_mx1 f) last_map; apply/map_eqmx.
have modUf: mx_subseries (regular_repr rF G) Uf.
rewrite /mx_subseries all_map; apply: etrans modU; apply: eq_all => Ui /=.
rewrite -mxmodule_map; apply: eq_subset_r => x.
@@ -4986,7 +4985,7 @@ have modUf: mx_subseries (regular_repr rF G) Uf.
have absUf i: i < size U -> mx_absolutely_irreducible (subseries_repr i modUf).
move=> lt_i_U; rewrite -(mx_rsim_abs_irr (map_regular_subseries i modU _)).
rewrite map_mx_abs_irr; apply: splitG.
- by apply: mx_rsim_irr (mx_series_repr_irr compU lt_i_U); exact: section_eqmx.
+ by apply: mx_rsim_irr (mx_series_repr_irr compU lt_i_U); apply: section_eqmx.
have compUf: mx_composition_series (regular_repr rF G) Uf.
split=> // i; rewrite size_map => ltiU.
move/max_submodP: (mx_abs_irrW (absUf i ltiU)); apply.
@@ -4994,7 +4993,7 @@ have compUf: mx_composition_series (regular_repr rF G) Uf.
by rewrite map_submx // ltmxW // (pathP _ (mx_series_lt compU)).
have [[i ltiU] simUi] := rsim_regular_series irrG compUf lastUf.
have{simUi} simUi: mx_rsim rG (subseries_repr i modUf).
- by apply: mx_rsim_trans simUi _; exact: section_eqmx.
+ by apply: mx_rsim_trans simUi _; apply: section_eqmx.
by rewrite (mx_rsim_abs_irr simUi) absUf; rewrite size_map in ltiU.
Qed.
@@ -5138,7 +5137,7 @@ Proof. by move=> x y; rewrite mxvalD mxvalN. Qed.
Canonical mxval_additive := Additive mxval_sub.
Lemma mxval_is_multiplicative : multiplicative mxval.
-Proof. by split; [exact: mxvalM | exact: mxval1]. Qed.
+Proof. by split; [apply: mxvalM | apply: mxval1]. Qed.
Canonical mxval_rmorphism := AddRMorphism mxval_is_multiplicative.
Lemma mxval_centg x : centgmx rG (mxval x).
@@ -5196,7 +5195,7 @@ Lemma map_mxminpoly_groot : (map_poly gen pA).[groot] = 0.
Proof. (* The [_ groot] prevents divergence of simpl. *)
apply: mxval_inj; rewrite -horner_map [_ groot]/= mxval_groot mxval0.
rewrite -(mx_root_minpoly A); congr ((_ : {poly _}).[A]).
-by apply/polyP=> i; rewrite 3!coef_map; exact: genK.
+by apply/polyP=> i; rewrite 3!coef_map; apply: genK.
Qed.
(* Plugging the extension morphism gen into the ext_repr construction *)
@@ -5666,11 +5665,11 @@ Lemma sat_gen_form e f : GRing.rformula f ->
Proof.
have ExP := Exists_rowP; have set_val := set_nth_map_rVval.
elim: f e => //.
-- by move=> b e _; exact: (iffP satP).
+- by move=> b e _; apply: (iffP satP).
- rewrite /gen_form => t1 t2 e rt_t; set t := (_ - _)%T.
have:= GRing.qf_evalP (gen_env e) (mxrank_form_qf 0 (gen_term t)).
rewrite eval_mxrank mxrank_eq0 eval_gen_term // => tP.
- by rewrite (sameP satP tP) /= subr_eq0 val_eqE; exact: eqP.
+ by rewrite (sameP satP tP) /= subr_eq0 val_eqE; apply: eqP.
- move=> f1 IH1 f2 IH2 s /= /andP[/(IH1 s)f1P /(IH2 s)f2P].
by apply: (iffP satP) => [[/satP/f1P ? /satP/f2P] | [/f1P/satP ? /f2P/satP]].
- move=> f1 IH1 f2 IH2 s /= /andP[/(IH1 s)f1P /(IH2 s)f2P].
@@ -5785,7 +5784,7 @@ exists F => //; case=> [|n] rG irrG; first by case/mx_irrP: irrG.
apply/idPn=> nabsG; pose cG := ('C(enveloping_algebra_mx rG))%MS.
have{nabsG} [A]: exists2 A, (A \in cG)%MS & ~~ is_scalar_mx A.
apply/has_non_scalar_mxP; rewrite ?scalar_mx_cent // ltnNge.
- by apply: contra nabsG; exact: cent_mx_scalar_abs_irr.
+ by apply: contra nabsG; apply: cent_mx_scalar_abs_irr.
rewrite {cG}memmx_cent_envelop -mxminpoly_linear_is_scalar -ltnNge => cGA.
move/(non_linear_gen_reducible irrG cGA).
set F' := gen_fieldType _ _; set rG' := @map_repr _ F' _ _ _ _ rG.
@@ -5813,7 +5812,7 @@ have{sUV'} defV': V' = U'; last rewrite {V'}defV' in compV'.
suffices{irrG'}: mx_irreducible rG' by case/mxsimpleP=> _ _ [].
have ltiU': i < size U' by rewrite size_map.
apply: mx_rsim_irr (mx_rsim_sym _ ) (mx_series_repr_irr compV' ltiU').
-apply: mx_rsim_trans (mx_rsim_map f' rsimVi) _; exact: map_regular_subseries.
+by apply: mx_rsim_trans (mx_rsim_map f' rsimVi) _; apply: map_regular_subseries.
Qed.
Lemma group_closure_field_exists gT F :
@@ -5824,17 +5823,17 @@ set n := #|{group gT}|.
suffices: classically {Fs : fieldType & {rmorphism F -> Fs}
& forall G : {group gT}, enum_rank G < n -> group_splitting_field Fs G}.
- apply: classic_bind => [[Fs f splitFs]] _ -> //.
- by exists Fs => // G; exact: splitFs.
+ by exists Fs => // G; apply: splitFs.
elim: (n) => [|i IHi]; first by move=> _ -> //; exists F => //; exists id.
apply: classic_bind IHi => [[F' f splitF']].
have [le_n_i _ -> // | lt_i_n] := leqP n i.
- by exists F' => // G _; apply: splitF'; exact: leq_trans le_n_i.
+ by exists F' => // G _; apply: splitF'; apply: leq_trans le_n_i.
have:= @group_splitting_field_exists _ (enum_val (Ordinal lt_i_n)) F'.
apply: classic_bind => [[Fs f' splitFs]] _ -> //.
exists Fs => [|G]; first exact: [rmorphism of (f' \o f)].
rewrite ltnS leq_eqVlt -{1}[i]/(val (Ordinal lt_i_n)) val_eqE.
case/predU1P=> [defG | ltGi]; first by rewrite -[G]enum_rankK defG.
-by apply: (extend_group_splitting_field f'); exact: splitF'.
+by apply: (extend_group_splitting_field f'); apply: splitF'.
Qed.
Lemma group_closure_closed_field (F : closedFieldType) gT :
@@ -5854,7 +5853,7 @@ have [a]: exists a, eigenvalue A a.
by rewrite coefN Pd1 mulN1r /= subrr.
case/negP; rewrite kermx_eq0 row_free_unit (mx_Schur irrG) ?subr_eq0 //.
by rewrite -memmx_cent_envelop -raddfN linearD addmx_sub ?scalar_mx_cent.
-by apply: contraNneq nscalA => ->; exact: scalar_mx_is_scalar.
+by apply: contraNneq nscalA => ->; apply: scalar_mx_is_scalar.
Qed.
End BuildSplittingField.
diff --git a/mathcomp/character/vcharacter.v b/mathcomp/character/vcharacter.v
index 9071740..922a73c 100644
--- a/mathcomp/character/vcharacter.v
+++ b/mathcomp/character/vcharacter.v
@@ -1,17 +1,16 @@
(* (c) Copyright Microsoft Corporation and Inria. All rights reserved. *)
Require Import mathcomp.ssreflect.ssreflect.
-From mathcomp.ssreflect
-Require Import ssreflect ssrbool ssrfun eqtype ssrnat seq.
-From mathcomp.discrete
-Require Import path div choice fintype tuple finfun bigop prime finset.
-From mathcomp.fingroup
-Require Import fingroup morphism perm automorphism quotient action gproduct.
-From mathcomp.algebra
-Require Import ssralg poly finalg zmodp cyclic vector ssrnum ssrint intdiv.
-From mathcomp.solvable
-Require Import sylow pgroup center frobenius.
-From mathcomp.field
-Require Import algnum algC.
+From mathcomp
+Require Import ssrbool ssrfun eqtype ssrnat seq path div choice.
+From mathcomp
+Require Import fintype tuple finfun bigop prime ssralg poly finset.
+From mathcomp
+Require Import fingroup morphism perm automorphism quotient finalg action.
+From mathcomp
+Require Import gproduct zmodp commutator cyclic center pgroup sylow frobenius.
+From mathcomp
+Require Import vector ssrnum ssrint intdiv algC algnum.
+From mathcomp
Require Import classfun character integral_char.
Set Implicit Arguments.
@@ -195,11 +194,11 @@ Qed.
Lemma zchar_subseq S1 S2 A :
subseq S1 S2 -> {subset 'Z[S1, A] <= 'Z[S2, A]}.
-Proof. move=> sS12; exact: zchar_subset (mem_subseq sS12). Qed.
+Proof. by move/mem_subseq; apply: zchar_subset. Qed.
Lemma zchar_filter S A (p : pred 'CF(G)) :
{subset 'Z[filter p S, A] <= 'Z[S, A]}.
-Proof. by apply: zchar_subset=> f; rewrite mem_filter => /andP[]. Qed.
+Proof. by apply: zchar_subset=> f; apply/mem_subseq/filter_subseq. Qed.
End Zchar.
@@ -297,7 +296,7 @@ Hypotheses (Inu : {in 'Z[S] &, isometry nu}) (oSS : pairwise_orthogonal S).
Let freeS := orthogonal_free oSS.
Let uniqS : uniq S := free_uniq freeS.
-Let Z_S : {subset S <= 'Z[S]}. Proof. by move=> phi; exact: mem_zchar. Qed.
+Let Z_S : {subset S <= 'Z[S]}. Proof. by move=> phi; apply: mem_zchar. Qed.
Let notS0 : 0 \notin S. Proof. by case/andP: oSS. Qed.
Let dotSS := proj2 (pairwise_orthogonalP oSS).
@@ -311,7 +310,7 @@ have notSnu0: 0 \notin map nu S.
by rewrite -cfnorm_eq0 Inu ?Z_S // cfnorm_eq0 => /eqP <-.
apply/pairwise_orthogonalP; split; first by rewrite /= notSnu0 map_inj_in_uniq.
move=>_ _ /mapP[phi Sphi ->] /mapP[psi Spsi ->].
-by rewrite (inj_in_eq inj_nu) // Inu ?Z_S //; exact: dotSS.
+by rewrite (inj_in_eq inj_nu) // Inu ?Z_S //; apply: dotSS.
Qed.
Lemma cfproj_sum_orthogonal P z phi :
@@ -410,7 +409,7 @@ Lemma cfnorm_orthonormal S :
orthonormal S -> '[\sum_(xi <- S) xi] = (size S)%:R.
Proof. exact: cfnorm_map_orthonormal. Qed.
-Lemma zchar_orthonormalP S :
+Lemma vchar_orthonormalP S :
{subset S <= 'Z[irr G]} ->
reflect (exists I : {set Iirr G}, exists b : Iirr G -> bool,
perm_eq S [seq (-1) ^+ b i *: 'chi_i | i in I])
@@ -457,7 +456,7 @@ Lemma vchar_norm1P phi :
Proof.
move=> Zphi phiN1.
have: orthonormal phi by rewrite /orthonormal/= phiN1 eqxx.
-case/zchar_orthonormalP=> [xi /predU1P[->|] // | I [b def_phi]].
+case/vchar_orthonormalP=> [xi /predU1P[->|] // | I [b def_phi]].
have: phi \in (phi : seq _) := mem_head _ _.
by rewrite (perm_eq_mem def_phi) => /mapP[i _ ->]; exists (b i), i.
Qed.
@@ -484,7 +483,7 @@ have orthS: orthonormal S.
rewrite (leq_exp2r _ 1) // -ltnS -(@ltn_exp2r _ _ 2) //.
apply: leq_ltn_trans lt_n_4; rewrite -leC_nat -def_n natrX.
rewrite cfdot_sum_irr (bigD1 i) //= -normCK def_m addrC -subr_ge0 addrK.
- by rewrite sumr_ge0 // => ? _; exact: mul_conjC_ge0.
+ by rewrite sumr_ge0 // => ? _; apply: mul_conjC_ge0.
have <-: size S = n.
by apply/eqP; rewrite -eqC_nat -def_n def_phi cfnorm_orthonormal.
exists (in_tuple S); split=> // _ /mapP[i _ ->].
@@ -535,24 +534,14 @@ by rewrite linearZ scale_zchar ?Z_T // -defT map_f ?mem_nth.
Qed.
Lemma Zisometry_of_iso f :
- pairwise_orthogonal S -> {in S, isometry f, to 'Z[irr G]} ->
+ free S -> {in S, isometry f, to 'Z[irr G]} ->
{tau : {linear 'CF(L) -> 'CF(G)} | {in S, tau =1 f}
& {in 'Z[S], isometry tau, to 'Z[irr G]}}.
Proof.
-move=> oS [If Zf]; have [/=/andP[S'0 uS] oSS] := pairwise_orthogonalP oS.
-have injf: {in S &, injective f}.
- move=> xi1 xi2 Sxi1 Sxi2 /=/(congr1 (cfdot (f xi1)))/eqP; rewrite !If //.
- by apply: contraTeq => /oSS-> //; rewrite cfnorm_eq0 (memPn S'0).
-have{injf} oSf: pairwise_orthogonal (map f S).
- apply/pairwise_orthogonalP; split=> /=.
- rewrite map_inj_in_uniq // uS (contra _ S'0) // => /mapP[chi Schi /eqP].
- by rewrite eq_sym -cfnorm_eq0 If // cfnorm_eq0 => /eqP <-.
- move=> _ _ /mapP[xi1 Xxi1 ->] /mapP[xi2 Xxi2 ->].
- by rewrite If ?(inj_in_eq injf) // => /oSS->.
-have{If} nSf: map cfnorm (map f S) = map cfnorm S.
- by rewrite -map_comp; apply/eq_in_map=> xi Sxi; rewrite /= If.
-have{Zf} ZSf: {subset map f S <= 'Z[irr G]} by move=> _ /mapP[xi /Zf Zfxi ->].
-by have [tau /eq_in_map] := Zisometry_of_cfnorm oS oSf nSf ZSf; exists tau.
+move=> freeS [If Zf]; have [tau Dtau Itau] := isometry_of_free freeS If.
+exists tau => //; split; first by apply: sub_in2 Itau; apply: zchar_span.
+move=> _ /zchar_nth_expansion[a Za ->]; rewrite linear_sum rpred_sum // => i _.
+by rewrite linearZ rpredZ_Cint ?Dtau ?Zf ?mem_nth.
Qed.
Lemma Zisometry_inj A nu :
@@ -584,7 +573,7 @@ by rewrite cfAutZ_Cint // scale_zchar // mem_zchar ?SuS ?mem_nth.
Qed.
Lemma cfAut_vchar A psi : psi \in 'Z[irr G, A] -> psi^u \in 'Z[irr G, A].
-Proof. by apply: cfAut_zchar; exact: irr_aut_closed. Qed.
+Proof. by apply: cfAut_zchar; apply: irr_aut_closed. Qed.
Lemma sub_aut_zchar S A psi :
{subset S <= 'Z[irr G]} -> psi \in 'Z[S, A] -> psi^u \in 'Z[S, A] ->
@@ -797,11 +786,9 @@ Proof. by rewrite /dchi scale1r irr0. Qed.
Lemma dirr_dchi i : dchi i \in dirr G.
Proof. by apply/dirrP; exists i.1; exists i.2. Qed.
-Lemma dIrrP (phi : 'CF(G)) :
- reflect (exists i , phi = dchi i) (phi \in dirr G).
+Lemma dIrrP phi : reflect (exists i, phi = dchi i) (phi \in dirr G).
Proof.
-by apply: (iffP idP)=> [/dirrP [b [i ->]]| [i ->]];
- [exists (b, i) | exact: dirr_dchi].
+by apply: (iffP idP)=> [/dirrP[b]|] [i ->]; [exists (b, i) | apply: dirr_dchi].
Qed.
Lemma dchi_ndirrE (i : dIirr G) : dchi (ndirr i) = - dchi i.
@@ -840,7 +827,7 @@ Qed.
Lemma dirr_dIirrE J (f : J -> 'CF(G)) :
(forall j, f j \in dirr G) -> forall j, dchi (dirr_dIirr f j) = f j.
-Proof. by move=> dirrGf j; exact: (@dirr_dIirrPE _ _ xpredT). Qed.
+Proof. by move=> dirrGf j; apply: (@dirr_dIirrPE _ _ xpredT). Qed.
Definition dirr_constt (B : {set gT}) (phi: 'CF(B)) : {set (dIirr B)} :=
[set i | 0 < '[phi, dchi i]].
@@ -909,7 +896,7 @@ Proof.
move=> PiZ; rewrite [X in X = _]cfun_sum_constt. *)
move=> PiZ; rewrite {1}[phi]cfun_sum_constt.
rewrite (reindex (to_dirr phi))=> [/= |]; last first.
- by exists (@of_irr _)=> //; exact: of_irrK .
+ by exists (@of_irr _)=> //; apply: of_irrK .
by apply: eq_big=> i; rewrite ?irr_constt_to_dirr // cfdot_todirrE.
Qed.