diff options
| author | Cyril Cohen | 2015-03-24 12:23:33 +0100 |
|---|---|---|
| committer | Cyril Cohen | 2015-03-24 12:23:33 +0100 |
| commit | c7ddacdfc43ba25c9fbd9505b3960047c13596d0 (patch) | |
| tree | 2b3e5624a90027352667518de0f434908e2e349d /mathcomp/odd_order | |
| parent | 0d2a1e7388d45776700c4400781e1aa71a0f0060 (diff) | |
metadata for solvable and field
Diffstat (limited to 'mathcomp/odd_order')
| -rw-r--r-- | mathcomp/odd_order/wielandt_fixpoint.v | 651 |
1 files changed, 651 insertions, 0 deletions
diff --git a/mathcomp/odd_order/wielandt_fixpoint.v b/mathcomp/odd_order/wielandt_fixpoint.v new file mode 100644 index 0000000..beebc3d --- /dev/null +++ b/mathcomp/odd_order/wielandt_fixpoint.v @@ -0,0 +1,651 @@ +(* (c) Copyright Microsoft Corporation and Inria. All rights reserved. *) +Require Import ssreflect ssrbool ssrfun eqtype ssrnat seq path div. +Require Import fintype bigop prime binomial finset ssralg fingroup finalg. +Require Import morphism perm automorphism quotient action commutator gproduct. +Require Import zmodp cyclic center pgroup gseries nilpotent sylow finalg. +Require Import finmodule abelian frobenius maximal extremal hall finmodule. +Require Import matrix mxalgebra mxrepresentation mxabelem BGsection1. + +(******************************************************************************) +(* This file provides the proof of the Wielandt fixpoint order formula, *) +(* which is a prerequisite for B & G, Section 3 and Peterfalvi, Section 9. *) +(******************************************************************************) + +Set Implicit Arguments. +Unset Strict Implicit. +Unset Printing Implicit Defensive. + +Local Open Scope ring_scope. +Import GroupScope GRing.Theory. +Import FinRing.Theory. + +Implicit Types (gT wT : finGroupType) (m n p q : nat). + +Lemma coprime_act_abelian_pgroup_structure gT p (A X : {group gT}) : + abelian A -> p.-group A -> p^'.-group X -> X \subset 'N(A) -> + exists2 s : {set {group gT}}, + \big[dprod/1]_(B in s) B = A + & {in s, forall B : {group gT}, + [/\ homocyclic B, X \subset 'N(B) + & acts_irreducibly X (B / 'Phi(B)) 'Q]}. +Proof. +move: {2}_.+1 (ltnSn #|A|) => m. +elim: m => // m IHm in gT A X *; rewrite ltnS => leAm cAA pA p'X nAX. +have [n1 eA]: {n | exponent A = p ^ n}%N by apply p_natP; rewrite pnat_exponent. +have [-> | ntA] := eqsVneq A 1. + by exists set0 => [|B]; rewrite ?big_set0 ?inE. +have [p_pr _ _] := pgroup_pdiv pA ntA; have p_gt1 := prime_gt1 p_pr. +case: n1 => [|n] in eA; first by rewrite trivg_exponent eA in ntA. +have nA1X: X \subset 'N('Ohm_1(A)) := char_norm_trans (Ohm_char 1 A) nAX. +have sAnA1: 'Mho^n(A) \subset 'Ohm_1(A). + rewrite (MhoE n pA) (OhmE 1 pA) genS //. + apply/subsetP=> xpn; case/imsetP=> x Ax ->{xpn}; rewrite !inE groupX //. + by rewrite -expgM -expnSr -eA -order_dvdn dvdn_exponent. +have nAnX: X \subset 'N('Mho^n(A)) := char_norm_trans (Mho_char n A) nAX. +have [B minB sBAn]: {B : {group gT} | minnormal B X & B \subset 'Mho^n(A)}. + apply: mingroup_exists; rewrite nAnX andbT; apply/trivgPn. + have [x Ax ox] := exponent_witness (abelian_nil cAA). + exists (x ^+ (p ^ n)); first by rewrite Mho_p_elt ?(mem_p_elt pA). + by rewrite -order_dvdn -ox eA dvdn_Pexp2l ?ltnn. +have abelA1: p.-abelem 'Ohm_1(A) by rewrite Ohm1_abelem. +have sBA1: B \subset 'Ohm_1(A) := subset_trans sBAn sAnA1. +case/mingroupP: minB; case/andP=> ntB nBX minB. +have{nBX sBA1} [U defA1 nUX] := Maschke_abelem abelA1 p'X sBA1 nA1X nBX. +have [_ mulBU _ tiBU] := dprodP defA1; have{mulBU} [_ sUA1] := mulG_sub mulBU. +have sUA: U \subset A := subset_trans sUA1 (Ohm_sub 1 _). +have [U1 | {defA1 minB}ntU] := eqsVneq U 1. + rewrite U1 dprodg1 /= in defA1. + have homoA: homocyclic A. + apply/(Ohm1_homocyclicP pA cAA); rewrite eA pfactorK //=. + by apply/eqP; rewrite eqEsubset sAnA1 -defA1 sBAn. + exists [set A]; rewrite ?big_set1 // => G; move/set1P->; split=> //. + have OhmMho: forall k, 'Ohm_k(A) = 'Mho^(n.+1 - k)(A). + by move=> k; rewrite (homocyclic_Ohm_Mho k pA) // eA pfactorK. + have fM: {in A &, {morph (fun x => x ^+ (p ^ n)) : x y / x * y >-> x * y}}. + by move=> x y Ax Ay /=; rewrite expgMn // /commute -(centsP cAA). + pose f := Morphism fM; have ker_f: 'ker f = 'Phi(A). + apply/setP=> z; rewrite (Phi_Mho pA cAA) -(subSnn n) -OhmMho. + by rewrite (OhmEabelian pA) ?(abelianS (Ohm_sub n A)) ?inE. + have [g injg def_g] := first_isom f; rewrite /= {}ker_f in g injg def_g. + have{f def_g} def_g: forall H, gval H \subset A -> g @* (H / _) = 'Mho^n(H). + move=> H sHA; rewrite def_g morphimEsub //. + by rewrite (MhoEabelian n (pgroupS sHA pA) (abelianS sHA cAA)). + have im_g: g @* (A / 'Phi(A)) = B by rewrite def_g // defA1 OhmMho subn1. + have defAb: A / 'Phi(A) = g @*^-1 B by rewrite -im_g injmK. + have nsPhiA: 'Phi(A) <| A := Phi_normal A. + have nPhiX: X \subset 'N('Phi(A)) := char_norm_trans (Phi_char A) nAX. + rewrite defAb; apply/mingroupP; split=> [|Hb]. + by rewrite -(morphim_injm_eq1 injg) ?morphpreK /= -?defAb ?im_g ?ntB ?actsQ. + case/andP=> ntHb actsXHb /= sgHbB; have [sHbA _] := subsetIP sgHbB. + rewrite -sub_morphim_pre // in sgHbB; rewrite -(minB _ _ sgHbB) ?injmK //. + rewrite morphim_injm_eq1 // {}ntHb {actsXHb}(subset_trans actsXHb) //=. + have{sHbA} [H defHb sPhiH sHA] := inv_quotientS nsPhiA sHbA. + rewrite defHb def_g // (char_norm_trans (Mho_char n H)) //. + by rewrite astabsQ ?subsetIr ?(normalS sPhiH sHA). +have nsUA: U <| A by rewrite -sub_abelian_normal. +have nUA: A \subset 'N(U) by case/andP: nsUA. +have Au_lt_m: #|A / U| < m := leq_trans (ltn_quotient ntU sUA) leAm. +have cAuAu: abelian (A / U) := quotient_abelian _ cAA. +have pAu: p.-group (A / U) := quotient_pgroup _ pA. +have p'Xu: p^'.-group (X / U) := quotient_pgroup _ p'X. +have nXAu: X / U \subset 'N(A / U) := quotient_norms _ nAX. +have{Au_lt_m p'Xu nXAu} [S defAu simS] := IHm _ _ _ Au_lt_m cAuAu pAu p'Xu nXAu. +have sSAu: forall Ku, Ku \in S -> Ku \subset A / U. + by move=> Ku S_Ku; rewrite -(bigdprodWY defAu) sub_gen // (bigcup_max Ku). +have{B ntB sBAn tiBU} [Ku S_Ku eKu]: exists2 Ku, Ku \in S & exponent Ku == (p ^ n.+1)%N. + apply/exists_inP; apply: contraR ntB; rewrite negb_exists_in -subG1 -tiBU. + move/forall_inP=> expSpn; apply/subsetP=> x Ux; rewrite inE Ux coset_idr //. + by rewrite (subsetP nUA) // (subsetP (Mho_sub n A)) // (subsetP sBAn). + have [y Ay ->]: exists2 y, y \in A & x = y ^+ (p ^ n). + by apply/imsetP; rewrite -MhoEabelian ?(subsetP sBAn). + rewrite morphX ?(subsetP nUA) // (exponentP _ _ (mem_quotient _ Ay)) //. + rewrite -sub_Ldiv -OhmEabelian ?(abelianS (Ohm_sub n _)) //=. + rewrite (OhmE n pAu) /= -(bigdprodWY defAu) genS // subsetI sub_gen //=. + apply/bigcupsP=> Ku S_Ku; rewrite sub_LdivT. + have: exponent Ku %| p ^ n.+1. + by rewrite (dvdn_trans (exponentS (sSAu _ S_Ku))) // -eA exponent_quotient. + case/dvdn_pfactor=> // k le_k_n1 expKu; rewrite expKu dvdn_exp2l //. + by rewrite -ltnS ltn_neqAle le_k_n1 -(eqn_exp2l _ _ p_gt1) -expKu expSpn. +have{sSAu} [sKuA [homoKu nKuX minKu]] := (sSAu Ku S_Ku, simS Ku S_Ku). +have [K defKu sUK sKA] := inv_quotientS nsUA sKuA. +have [cKK cKuKu] := (abelianS sKA cAA, abelianS sKuA cAuAu). +have [pK pKu] := (pgroupS sKA pA, pgroupS sKuA pAu). +have nsUK: U <| K := normalS sUK sKA nsUA; have [_ nUK] := andP nsUK. +have nKX: X \subset 'N(K). + by rewrite -(quotientSGK nUX) ?normsG ?quotient_normG // -defKu. +pose K1 := 'Mho^1(K); have nsK1K: K1 <| K := Mho_normal 1 K. +have nXKb: X / K1 \subset 'N(K / K1) by exact: quotient_norms. +pose K'u := \big[dprod/1]_(Bu in S :\ Ku) Bu. +have{S_Ku} defAu_K: K / U \x K'u = A / U by rewrite -defKu -big_setD1. +have [[_ Pu _ defK'u]] := dprodP defAu_K; rewrite defK'u => mulKPu _ tiKPu. +have [_ sPuA] := mulG_sub mulKPu. +have [P defPu sUP sPA] := inv_quotientS nsUA sPuA. +have{simS defK'u} nPX: X \subset 'N(P). + rewrite -(quotientSGK nUX) ?normsG // quotient_normG ?(normalS sUP sPA) //. + rewrite -defPu -(bigdprodWY defK'u) norms_gen ?norms_bigcup //. + by apply/bigcapsP=> Bu; case/setD1P=> _; case/simS. +have abelKb: p.-abelem (K / K1). + by rewrite -[K1](Phi_Mho pK) ?Phi_quotient_abelem. +have p'Xb: p^'.-group (X / K1) := quotient_pgroup _ p'X. +have sUKb: U / K1 \subset K / K1 := quotientS _ sUK. +have nUXb: X / K1 \subset 'N(U / K1) := quotient_norms _ nUX. +have tiUK1: U :&: K1 = 1. + apply/trivgP; apply/subsetP=> xp; case/setIP=> Uxp K1xp. + have{K1xp} [x Kx def_xp]: exists2 x, x \in K & xp = x ^+ p. + by apply/imsetP; rewrite -(MhoEabelian 1). + suffices A1x: x \in 'Ohm_1(A). + by rewrite def_xp inE; case/abelemP: abelA1 => // _ ->. + have nUx: x \in 'N(U) := subsetP nUK x Kx. + rewrite -sub1set -(quotientSGK _ sUA1) ?quotient_set1 ?sub1set //. + apply: (subsetP (quotientS U (subset_trans (MhoS n sKA) sAnA1))). + rewrite quotientE morphim_Mho //= -quotientE -defKu. + have ->: 'Mho^n(Ku) = 'Ohm_1(Ku). + by rewrite (homocyclic_Ohm_Mho 1 pKu) // (eqP eKu) pfactorK ?subn1. + rewrite (OhmE 1 pKu) ?mem_gen // !inE defKu mem_quotient //=. + by rewrite -morphX //= -def_xp coset_id. +have [Db defKb nDXb] := Maschke_abelem abelKb p'Xb sUKb nXKb nUXb. +have [_ mulUDb _ tiUDb] := dprodP defKb; have [_ sDKb] := mulG_sub mulUDb. +have [D defDb sK1D sDK] := inv_quotientS (Mho_normal 1 K) sDKb. +have nK1X: X \subset 'N(K1) := char_norm_trans (Mho_char 1 K) nKX. +have [cDU [sK1K nK1K]] := (centSS sUK sDK cKK, andP nsK1K). +have nDX: X \subset 'N(D). + rewrite -(quotientSGK nK1X) ?normsG // quotient_normG ?(normalS _ sDK) //. + by rewrite -defDb. +have{mulUDb} mulUD: U * D = K. + rewrite (centC cDU) -(mulSGid sK1D) -mulgA -(centC cDU). + rewrite -quotientK ?quotientMr ?(subset_trans _ nK1K) ?mul_subG // -defDb. + by rewrite mulUDb quotientGK. +have cKP: P \subset 'C(K) := centSS sPA sKA cAA. +have mulKP: K * P = A. + rewrite -(mulSGid sUK) -mulgA -(quotientGK nsUA) -mulKPu defPu. + by rewrite -quotientK ?quotientMr ?mul_subG ?(subset_trans _ nUA). +have defKP: K :&: P = U. + apply/eqP; rewrite eqEsubset subsetI sUK sUP !andbT. + by rewrite -quotient_sub1 ?subIset ?nUK // -tiKPu defPu quotientI. +have tiUD: U :&: D = 1. + apply/trivgP; rewrite -tiUK1 subsetI subsetIl. + rewrite -quotient_sub1; last by rewrite subIset ?(subset_trans sUK). + by rewrite -tiUDb defDb quotientI. +have tiDP: D :&: P = 1 by rewrite -(setIidPl sDK) -setIA defKP setIC. +have mulDP: D * P = A by rewrite -(mulSGid sUP) mulgA -(centC cDU) mulUD. +have sDA := subset_trans sDK sKA. +have defA: D \x P = A by rewrite dprodE // (centSS sPA sDA). +have ntD: D :!=: 1. + apply: contraNneq ntA => D1; rewrite trivg_exponent eA -(eqP eKu). + rewrite -trivg_exponent -subG1 -tiKPu defKu subsetIidl defPu quotientS //. + by rewrite -(mul1g P) -D1 mulDP. +have ltPm: #|P| < m. + by rewrite (leq_trans _ leAm) // -(dprod_card defA) ltn_Pmull ?cardG_gt1. +have [cPP pP] := (abelianS sPA cAA, pgroupS sPA pA). +have{S defAu K'u defAu_K} [S defP simS] := IHm _ _ _ ltPm cPP pP p'X nPX. +exists (D |: S) => [ | {defP}B]. + rewrite big_setU1 ?defP //=; apply: contra ntD => S_D. + by rewrite -subG1 -tiDP subsetIidl -(bigdprodWY defP) sub_gen ?(bigcup_max D). +case/setU1P=> [-> {B S simS} | ]; last exact: simS. +have [[pD cDD] nUD] := (pgroupS sDA pA, abelianS sDA cAA, subset_trans sDA nUA). +have isoD: D \isog Ku by rewrite defKu -mulUD quotientMidl quotient_isog. +rewrite {isoD}(isog_homocyclic isoD); split=> //. +have nPhiDX: X \subset 'N('Phi(D)) := char_norm_trans (Phi_char D) nDX. +have [f [injf im_f act_f]]: + exists f : {morphism D / 'Phi(D) >-> coset_of 'Phi(Ku)}, + [/\ 'injm f, f @* (D / 'Phi(D)) = Ku / 'Phi(Ku) + & {in D / 'Phi(D) & X, morph_act 'Q 'Q f (coset U)}]. +- have [/= injf im_f] := isomP (quotient_isom nUD tiUD). + set f := restrm nUD (coset U) in injf im_f. + rewrite -quotientMidl mulUD -defKu in im_f. + have fPhiD: f @* 'Phi(D) = 'Phi(Ku) by rewrite -im_f (morphim_Phi _ pD). + rewrite -['Phi(Ku)]/(gval 'Phi(Ku)%G) -(group_inj fPhiD). + exists (quotm_morphism [morphism of f] (Phi_normal _)). + rewrite (injm_quotm _ injf) morphim_quotm /= -/f im_f. + split=> // yb x; case/morphimP=> y Ny Dy ->{yb} Xx. + have [nPhiDx nUx] := (subsetP nPhiDX x Xx, subsetP nUX x Xx). + have Dyx: y ^ x \in D by rewrite memJ_norm // (subsetP nDX). + rewrite quotmE // !qactE ?qact_domE ?subsetT ?astabsJ ?quotmE //=. + - by congr (coset _ _); rewrite /f /restrm morphJ // (subsetP nUD). + - by rewrite (subsetP (morphim_norm _ _)) ?mem_morphim. + rewrite morphim_restrm (setIidPr (Phi_sub _)). + by rewrite (subsetP (morphim_norm _ _)) ?mem_quotient. +apply/mingroupP; split=> [|Y]. + rewrite -subG1 quotient_sub1 ?(normal_norm (Phi_normal _)) //. + by rewrite proper_subn ?Phi_proper // actsQ. +case/andP=> ntY actsXY sYD; have{minKu} [_ minKu] := mingroupP minKu. +apply: (injm_morphim_inj injf); rewrite // im_f. +apply: minKu; last by rewrite /= -im_f morphimS. +rewrite morphim_injm_eq1 // ntY. +apply/subsetP=> xb; case/morphimP=> x Nx Xx ->{xb}. +rewrite 2!inE /= qact_domE ?subsetT // astabsJ. +rewrite (subsetP (char_norm_trans (Phi_char _) nKuX)) ?mem_quotient //=. +apply/subsetP=> fy; case/morphimP=> y Dy Yy ->{fy}. +by rewrite inE /= -act_f // morphimEsub // mem_imset // (acts_act actsXY). +Qed. + +CoInductive is_iso_quotient_homocyclic_sdprod gT (V G : {group gT}) m : Prop := + IsoQuotientHomocyclicSdprod wT (W D G1 : {group wT}) (f : {morphism D >-> gT}) + of homocyclic W & #|W| = (#|V| ^ m)%N + & 'ker f = 'Mho^1(W) & f @* W = V & f @* G1 = G & W ><| G1 = D. + +Lemma iso_quotient_homocyclic_sdprod gT (V G : {group gT}) p m : + minnormal V G -> coprime p #|G| -> p.-abelem V -> m > 0 -> + is_iso_quotient_homocyclic_sdprod V G m. +Proof. +move=> minV copG abelV m_gt0; pose q := (p ^ m)%N. +have [ntV nVG] := andP (mingroupp minV). +have [p_pr pVdvdn [n Vpexpn]] := pgroup_pdiv (abelem_pgroup abelV) ntV. +move/(abelem_mx_irrP abelV ntV nVG): (minV) => mx_irrV. +have dim_lt0 : 'dim V > 0 by rewrite (dim_abelemE abelV) // Vpexpn pfactorK. +have q_gt1: q > 1 by rewrite (ltn_exp2l 0) // prime_gt1. +have p_q: p.-nat q by rewrite pnat_exp pnat_id. +have p_dv_q: p %| q := dvdn_exp2l p m_gt0. +pose rG := regular_repr [comUnitRingType of 'Z_q] G; pose MR_G := ('MR rG)%gact. +have [wT [fL injL [fX injX fJ]]]: exists wT : finGroupType, + exists2 fL : {morphism setT >-> wT}, 'injm fL & + exists2 fX : {morphism G >-> wT}, 'injm fX & + {in setT & G, morph_act MR_G 'J fL fX}. +- exists (sdprod_groupType MR_G). + exists (sdpair1_morphism MR_G); first exact: injm_sdpair1. + by exists (sdpair2_morphism MR_G); [exact: injm_sdpair2 | exact: sdpair_act]. +move imfL: (fL @* [set: _])%G => L; move imfX: (fX @* G)%G => X. +have cLL: abelian L by rewrite -imfL morphim_abelian // zmod_abelian. +have pL: p.-group L. + by rewrite -imfL morphim_pgroup -?pnat_exponent ?exponent_mx_group. +have tiVG: V :&: G = 1 by rewrite coprime_TIg // Vpexpn coprime_pexpl. +have{copG} p'G: p^'.-group G by rewrite /pgroup p'natE // -prime_coprime. +have p'X: p^'.-group X by rewrite -imfX morphim_pgroup. +have nXL: X \subset 'N(L). + rewrite -imfX -imfL; apply/subsetP=> _ /morphimP[x Gx _ ->]; rewrite inE. + apply/subsetP=> _ /imsetP[_ /morphimP[v rVv _ ->] ->]. + by rewrite -fJ // mem_morphim ?in_setT. +have [/= S defL im_S] := coprime_act_abelian_pgroup_structure cLL pL p'X nXL. +pose gi (z : 'Z_q) := z%:R : 'F_p. +have giM: rmorphism gi. + split=> [z1 z2|]; last split=> // z1 z2. + apply: canRL (addrK _) _; apply: val_inj. + by rewrite -{2}(subrK z2 z1) -natrD /= !val_Fp_nat ?modn_dvdm // Zp_cast. + by apply: val_inj; rewrite -natrM /= !val_Fp_nat ?modn_dvdm // Zp_cast. +have [gL [DgL _ _ _]] := domP (invm_morphism injL) (congr_group imfL). +pose g u := map_mx (RMorphism giM) (gL u). +have gM: {in L &, {morph g : u v / u * v}}. + by move=> u v Lu Lv /=; rewrite {1}/g morphM // map_mxD. +have kerg: 'ker (Morphism gM) = 'Phi(L). + rewrite (Phi_Mho pL cLL) (MhoEabelian 1 pL cLL). + apply/setP=> u; apply/idP/imsetP=> [ | [v Lv ->{u}]]; last first. + rewrite !inE groupX //=; apply/eqP/rowP=> i; apply: val_inj. + rewrite !mxE morphX // mulmxnE Zp_mulrn /= val_Fp_nat //=. + by move: {i}(_ i); rewrite Zp_cast // => vi; rewrite modn_dvdm // modnMl. + case/morphpreP; rewrite -{1}imfL => /morphimP[v rVv _ ->{u}] /set1P /=. + rewrite /g DgL /= invmE // => /rowP vp0. + pose x := fL (map_mx (fun t : 'Z_q => (t %/ p)%:R) v). + exists x; first by rewrite -imfL mem_morphim ?inE. + rewrite -morphX ?in_setT //; congr (fL _); apply/rowP=> i. + rewrite mulmxnE -{1}(natr_Zp (v 0 i)) {1}(divn_eq (v 0 i) p) addnC. + by have:= congr1 val (vp0 i); rewrite !mxE -mulrnA /= val_Fp_nat // => ->. +have [gX [DgX KgX _ imgX]] := domP (invm_morphism injX) (congr_group imfX). +pose aG := regular_repr [fieldType of 'F_p] G. +have GgX: {in X, forall x, gX x \in G}. + by rewrite DgX -imfX => _ /morphimP[x Gx _ ->]; rewrite /= invmE. +have XfX: {in G, forall x, fX x \in X}. + by move=> x Gx; rewrite -imfX mem_morphim. +have gJ: {in L & X, forall u x, g (u ^ x) = g u *m aG (gX x)}. + rewrite -{1}imfL -{1}imfX => _ _ /morphimP[u rVu _ ->] /morphimP[x Gx _ ->]. + rewrite -fJ // /g DgL DgX /= !invmE // mx_repr_actE ?inE //. + by rewrite (map_mxM (RMorphism giM)) map_regular_mx. +pose gMx U := rowg_mx (Morphism gM @* U). +have simS: forall U, U \in S -> mxsimple aG (gMx U). + move=> U S_U; have [_ nUX irrU] := im_S U S_U. + have{irrU} [modU irrU] := mingroupP irrU; have{modU} [ntU _] := andP modU. + have sUL: U \subset L by rewrite -(bigdprodWY defL) sub_gen // (bigcup_max U). + split=> [||U2 modU2]. + - rewrite (eqmx_module _ (genmxE _)); apply/mxmoduleP=> x Gx. + apply/row_subP=> i; rewrite row_mul rowK. + have [u Lu Uu def_u] := morphimP (enum_valP i). + rewrite -(invmE injX Gx) -DgX def_u -gJ ?XfX //. + set ux := u ^ _; apply: eq_row_sub (gring_index _ (g ux)) _. + have Uux: ux \in U by rewrite memJ_norm // (subsetP nUX) ?XfX. + by rewrite rowK gring_indexK //; apply: mem_morphim; rewrite ?(subsetP sUL). + - apply: contra ntU; rewrite rowg_mx_eq0. + rewrite -subG1 sub_morphim_pre // -kerE kerg => sU_Phi. + rewrite /= quotientS1 //=; rewrite (big_setD1 U) //= in defL. + have{defL} [[_ U' _ ->] defUU' cUU' tiUU'] := dprodP defL. + have defL: U \* U' = L by rewrite cprodE. + have:= cprod_modl (Phi_cprod pL defL) (Phi_sub U). + rewrite -(setIidPl (Phi_sub U')) setIAC -setIA tiUU' setIg1 cprodg1 => ->. + by rewrite subsetIidr. + rewrite -!rowgS stable_rowg_mxK /= => [sU2gU nzU2|]; last first. + apply/subsetP=> z _; rewrite !inE /=; apply/subsetP=> u gUu. + by rewrite inE /= /scale_act -[val z]natr_Zp scaler_nat groupX. + rewrite sub_morphim_pre // -subsetIidl. + rewrite -(quotientSGK (normal_norm (Phi_normal U))) //=; last first. + rewrite subsetI Phi_sub (subset_trans (PhiS pL sUL)) //. + by rewrite -kerg ker_sub_pre. + rewrite [(U :&: _) / _]irrU //; last by rewrite quotientS ?subsetIl. + rewrite (contra _ nzU2) /=; last first. + rewrite -subG1 quotient_sub1; last first. + by rewrite subIset // normal_norm // Phi_normal. + rewrite /= -(morphpre_restrm sUL). + move/(morphimS (restrm_morphism sUL (Morphism gM))). + rewrite morphpreK ?im_restrm // morphim_restrm => s_U2_1. + rewrite -trivg_rowg -subG1 (subset_trans s_U2_1) //. + rewrite -(morphim_ker (Morphism gM)) morphimS // kerg. + by rewrite subIset ?(PhiS pL) ?orbT. + rewrite actsQ //; first by rewrite (char_norm_trans (Phi_char U)). + rewrite normsI //; apply/subsetP=> x Xx; rewrite inE. + apply/subsetP=> _ /imsetP[u g'U2u ->]. + have [Lu U2gu] := morphpreP g'U2u; rewrite mem_rowg in U2gu. + rewrite inE memJ_norm ?(subsetP nXL) // Lu /= inE gJ //. + by rewrite mem_rowg (mxmodule_trans modU2) ?GgX. +have im_g: Morphism gM @* L = [set: 'rV_#|G|]. + apply/eqP; rewrite eqEcard subsetT cardsT card_matrix card_Fp //= mul1n. + rewrite card_morphim kerg setIid (Phi_Mho pL cLL) -divgS ?Mho_sub //. + rewrite -(mul_card_Ohm_Mho_abelian 1 cLL) mulnK ?cardG_gt0 //. + rewrite (card_pgroup (pgroupS (Ohm_sub 1 L) pL)) -rank_abelian_pgroup //. + by rewrite -imfL (injm_rank injL) //= rank_mx_group mul1n. +have sumS: (\sum_(U in S) gMx U :=: 1%:M)%MS. + apply/eqmxP; rewrite submx1; apply/rV_subP=> v _. + have: v \in Morphism gM @* L by rewrite im_g inE. + case/morphimP=> u Lu _ ->{v}. + rewrite -mem_rowg -sub1set -morphim_set1 // sub_morphim_pre ?sub1set //. + have [c [Uc -> _]] := mem_bigdprod defL Lu; rewrite group_prod //= => U S_U. + have sUL: U \subset L by rewrite -(bigdprodWY defL) sub_gen // (bigcup_max U). + rewrite inE (subsetP sUL) ?Uc // inE mem_rowg (sumsmx_sup U) // -mem_rowg. + by rewrite (subsetP (sub_rowg_mx _)) // mem_morphim ?(subsetP sUL) ?Uc. +have Fp'G: [char 'F_p]^'.-group G. + by rewrite (eq_p'group _ (charf_eq (char_Fp p_pr))). +have [VK [modVK defVK]] := rsim_regular_submod mx_irrV Fp'G. +have [U S_U isoUV]: {U | U \in S & mx_iso (regular_repr _ G) (gMx U) VK}. + apply: hom_mxsemisimple_iso (scalar_mx_hom _ 1 _) _ => [|U S_U _|]; auto. + by apply/(submod_mx_irr modVK); exact: (mx_rsim_irr defVK). + by rewrite mulmx1 sumS submx1. +have simU := simS U S_U; have [modU _ _] := simU. +pose rV := abelem_repr abelV ntV nVG. +have{VK modVK defVK isoUV} [h dimU h_free hJ]: mx_rsim (submod_repr modU) rV. + by apply: mx_rsim_trans (mx_rsim_sym defVK); exact/mx_rsim_iso. +have sUL : U \subset L. + by move: defL; rewrite (big_setD1 U) //= => /dprodP[[_ U1 _ ->] /mulG_sub[]]. +pose W := [set: 'rV['Z_(p ^ m)](V)]%G. +have [homU nUX _] := im_S U S_U; have [cUU _] := andP homU. +have atypeU: abelian_type U == nseq ('dim V) (p ^ m)%N. + rewrite (big_setD1 U) //= in defL. + have [[_ U' _ defU'] defUU' _ tiUU'] := dprodP defL. + rewrite defU' in defL defUU' tiUU'. + have ->: 'dim V = 'r(U). + apply/eqP; rewrite -dimU -(eqn_exp2l _ _ (prime_gt1 p_pr)). + rewrite (rank_abelian_pgroup (pgroupS sUL pL) cUU). + rewrite -(card_pgroup (pgroupS (Ohm_sub 1 U) (pgroupS sUL pL))). + rewrite -{1}(card_Fp p_pr) -card_rowg stable_rowg_mxK; last first. + apply/subsetP=> z _; rewrite !inE; apply/subsetP=> v gUv. + by rewrite inE /= /scale_act -(natr_Zp (val z)) scaler_nat groupX. + rewrite card_morphim kerg (Phi_Mho pL cLL) (setIidPr sUL) -divgI setIC. + rewrite -(dprod_modl (Mho_dprod 1 defL) (Mho_sub 1 U)). + rewrite [_ :&: _](trivgP _); last by rewrite -tiUU' setIC setSI ?Mho_sub. + by rewrite dprodg1 -(mul_card_Ohm_Mho_abelian 1 cUU) mulnK ?cardG_gt0. + have isoL: isog L [set: 'rV['Z_q]_#|G|] by rewrite -imfL isog_sym sub_isog. + have homL: homocyclic L by rewrite (isog_homocyclic isoL) mx_group_homocyclic. + have [-> _] := abelian_type_dprod_homocyclic defL pL homL. + by rewrite (exponent_isog isoL) // exponent_mx_group. +have pU: p.-group U by rewrite (pgroupS sUL). +have isoWU: isog U W. + by rewrite eq_abelian_type_isog ?zmod_abelian // abelian_type_mx_group ?mul1n. +have {cUU atypeU} cardU : #|U| = (#|V| ^ m)%N. + rewrite card_homocyclic // (exponent_isog isoWU) exponent_mx_group //. + rewrite -size_abelian_type // (eqP atypeU) size_nseq. + by rewrite (dim_abelemE abelV) // Vpexpn pfactorK // expnAC. +pose f3 w := rVabelem abelV ntV (in_submod _ (g w) *m h). +have f3M: {in U &, {morph f3: w1 w2 / w1 * w2}}. + move=> w1 w2 Uw1 Uw2 /=; rewrite {1}/f3. + rewrite gM ?(subsetP sUL) // linearD mulmxDl. + by rewrite morphM ?mem_im_abelem_rV. +have Ugw w : w \in U -> (g w <= gMx U)%MS. + move=> Uw; rewrite -mem_rowg (subsetP (sub_rowg_mx _)) //. + by rewrite (mem_morphim (Morphism gM)) ?(subsetP sUL). +have KgU: 'ker_U (Morphism gM) = 'Mho^1(U). + rewrite kerg (Phi_Mho pL cLL); rewrite (big_setD1 U) //= in defL. + have [[_ U' _ defU'] _ _ tiUU'] := dprodP defL; rewrite defU' in defL tiUU'. + rewrite setIC -(dprod_modl (Mho_dprod 1 defL) (Mho_sub 1 U)). + by rewrite [_ :&: _](trivgP _) ?dprodg1 // -tiUU' setIC setSI ?Mho_sub. +have{KgU} Kf3: 'ker (Morphism f3M) = 'Mho^1(U). + apply/setP=> w; rewrite !inE /=. + rewrite morph_injm_eq1 ?rVabelem_injm ?mem_im_abelem_rV //=. + rewrite -[1](mul0mx _ h) (inj_eq (row_free_inj h_free)) in_submod_eq0. + case Uw: (w \in U) => /=; last first. + by apply/sym_eq; apply: contraFF Uw; apply: (subsetP (Mho_sub _ _)). + rewrite -[(_ <= _)%MS]andTb -(Ugw _ Uw) -sub_capmx capmx_compl submx0. + by rewrite -KgU !inE Uw (subsetP sUL). +have cUU: abelian U := abelianS sUL cLL. +have im_f3: Morphism f3M @* U = V. + apply/eqP; rewrite eqEcard card_morphim setIid Kf3; apply/andP; split. + by apply/subsetP=> _ /morphimP[w _ _ ->]; apply: mem_rVabelem. + rewrite -divgS ?Mho_sub // -(mul_card_Ohm_Mho_abelian 1 cUU). + rewrite mulnK ?cardG_gt0 // (card_pgroup (pgroupS (Ohm_sub 1 U) pU)). + rewrite -rank_abelian_pgroup // (isog_rank isoWU) /W. + by rewrite (dim_abelemE abelV) // rank_mx_group mul1n Vpexpn pfactorK. +have f3J: {in U & X, morph_act 'J 'J (Morphism f3M) gX}. + move=> u x Uu Xx; rewrite /f3 /= gJ ?(subsetP sUL) // in_submodJ ?Ugw //. + by rewrite -mulmxA hJ ?GgX // mulmxA rVabelemJ ?GgX. +have defUX: U ><| X = U <*> X. + rewrite norm_joinEr; last by case: (im_S _ S_U). + by rewrite sdprodE ?coprime_TIg ?(pnat_coprime pU). +pose f := sdprodm defUX f3J. +have{im_f3} fU_V: f @* U = V by rewrite morphim_sdprodml. +have fX_G: f @* X = G by rewrite morphim_sdprodmr // imgX -imfX im_invm. +suffices: 'ker f = 'Mho^1(U) by exists wT U (U <*> X)%G X [morphism of f]. +rewrite -Kf3; apply/setP=> y; apply/idP/idP; last first. + move=> /morphpreP[/= Uy /set1P f3y]. + by rewrite !inE /= sdprodmEl //= f3y (subsetP (joing_subl _ X)) /=. +rewrite ker_sdprodm => /imset2P[u t Uu /setIdP[Xt /eqP/= fu] ->{y}]. +have: f3 u \in V :&: G. + by rewrite inE -fU_V morphim_sdprodml //= mem_imset ?setIid // fu GgX. +rewrite tiVG in_set1 fu morph_injm_eq1 ?KgX ?injm_invm // => /eqP t1. +by rewrite t1 invg1 mulg1 !inE Uu /= fu t1 morph1. +Qed. + +Theorem solvable_Wielandt_fixpoint (I : finType) gT (A : I -> {group gT}) + (n m : I -> nat) (G V : {group gT}) : + (forall i, m i + n i > 0 -> A i \subset G) -> + G \subset 'N(V) -> coprime #|V| #|G| -> solvable V -> + {in G, forall a, \sum_(i | a \in A i) m i = \sum_(i | a \in A i) n i}%N -> + (\prod_i #|'C_V(A i)| ^ (m i * #|A i|) + = \prod_i #|'C_V(A i)| ^ (n i * #|A i|))%N. +Proof. +move: {2}_.+1 (ltnSn #|V|) => c leVc sA_G nVG coVG solV partG; move: leVc. +pose nz_k i := (0 < m i + n i)%N; rewrite !(bigID nz_k xpredT) /= {2 4}/nz_k. +rewrite !(big1 _ (predC _)) /= => [|i|i]; try by case: (m i) (n i) => [[]|]. +pose sum_k A_ a k := (\sum_(i | (a \in (A_ i : {set _})) && nz_k i) k i)%N. +have{partG} partG: {in G, forall a, sum_k _ A a m = sum_k _ A a n}. + move=> a /partG; rewrite !(bigID nz_k (fun i => a \in _)) -!/(sum_k _ A a _). + by rewrite /= !big1 ?addn0 /nz_k // => i /andP[_]; case: (m i) (n i) => [[]|]. +rewrite !muln1; elim: c => // c IHc in gT G A V nVG coVG solV partG sA_G *. +rewrite ltnS => leVc; have [-> | ntV] := eqsVneq V 1. + by rewrite !big1 // => i _; rewrite setI1g cards1 exp1n. +have nsVVG: V <| V <*> G by rewrite normalYl. +without loss{c leVc IHc} minV: / minnormal V (V <*> G). + have [B minB sBV]: {B : {group gT} | minnormal B (V <*> G) & B \subset V}. + by apply: mingroup_exists; rewrite ntV normal_norm. + have [nBVG ntB abB] := minnormal_solvable minB sBV solV. + have [nBV nBG] := joing_subP nBVG; have solB := solvableS sBV solV. + have [{1}<- -> // | ltBV _] := eqVproper sBV. + have ltBc: #|B| < c := leq_trans (proper_card ltBV) leVc. + have coBG: coprime #|B| #|G| := coprimeSg sBV coVG. + have factorCA_B k i: nz_k i -> + (#|'C_B(A i)| ^ (k i * #|A i|) * #|'C_(V / B)(A i / B)| ^ (k i * #|A i / B|) + = #|'C_V(A i)| ^ (k i * #|A i|))%N. + - move/sA_G => sAiG; have nBAi := subset_trans sAiG nBG. + have [coVAi coBAi] := (coprimegS sAiG coVG, coprimegS sAiG coBG). + rewrite -(card_isog (quotient_isog _ _)) ?(coprime_TIg coBAi) // -expnMn. + rewrite -coprime_quotient_cent // -{1}(setIidPr sBV) setIAC. + by rewrite card_quotient ?LagrangeI // subIset ?nBV. + rewrite -!{1}(eq_bigr _ (factorCA_B _)) {factorCA_B} !big_split /=. + pose A_B i := A i / B; congr (_ * _)%N; first exact: (IHc _ G). + have: #|V / B| < c by apply: leq_trans leVc; rewrite ltn_quotient. + have (i): nz_k i -> A i / B \subset G / B by move/sA_G/quotientS->. + apply: IHc; rewrite ?morphim_sol ?coprime_morph ?quotient_norms //. + move=> _ /morphimP[a Na Ga ->]. + suffices eqAB: sum_k _ A_B (coset B a) =1 sum_k _ A a by rewrite !eqAB partG. + move=> k; apply: eq_bigl => i; apply: andb_id2r => /sA_G sAiG. + rewrite -sub1set -quotient_set1 // quotientSK ?sub1set //. + by rewrite -{2}(mul1g (A i)) -(coprime_TIg coBG) setIC group_modr // inE Ga. +have /is_abelemP[p p_pr abelV] := minnormal_solvable_abelem minV solV. +have [p_gt1 [pV cVV _]] := (prime_gt1 p_pr, and3P abelV). +have{minV} minV: minnormal V G. + apply/mingroupP; split=> [|B nBG sBV]; first by rewrite ntV nVG. + by case/mingroupP: minV => _ -> //; rewrite join_subG (sub_abelian_norm cVV). +have co_pG: coprime p #|G|. + by have [_ _ [e oV]] := pgroup_pdiv pV ntV; rewrite oV coprime_pexpl in coVG. +have p'G: p^'.-group G by rewrite pgroupE p'natE -?prime_coprime. +pose rC i := logn p #|'C_V(A i)|. +have ErC k i: (#|'C_V(A i)| ^ (k i * #|A i|) = p ^ (rC i * k i * #|A i|))%N. + suffices /card_pgroup->: p.-group 'C_V(A i) by rewrite -expnM mulnA. + by rewrite (pgroupS (subsetIl _ _)). +rewrite !{1}(eq_bigr _ (fun i _ => ErC _ i)) {ErC} -!expn_sum; congr (_ ^ _)%N. +have eqmodX x y: (forall e, x = y %[mod p ^ e]) -> x = y. + pose e := maxn x y; move/(_ e); have:= ltn_expl e p_gt1. + by rewrite gtn_max /= => /andP[x_ltq y_ltq]; rewrite !modn_small. +apply: eqmodX => e; have [-> | e_gt0] := posnP e; first by rewrite !modn1. +set q := (p ^ e)%N; have q_gt1: q > 1 by rewrite -(exp1n e) ltn_exp2r. +have{e_gt0 co_pG} [wT W D G1 f homoW oW kerf imfW imfG1 defD] := + iso_quotient_homocyclic_sdprod minV co_pG abelV e_gt0. +have [[cWW _] [_ /mulG_sub[sWD sG1D] nWG1 tiWG1]] := (andP homoW, sdprodP defD). +have pW: p.-group W by rewrite /pgroup oW pnat_exp [p.-nat _]pV. +have rW_V: 'r(W) = 'dim V. + rewrite (rank_abelian_pgroup pW cWW) -(mulnK #|_| (cardG_gt0 'Mho^1(W))). + rewrite mul_card_Ohm_Mho_abelian // divg_normal ?Mho_normal //=. + rewrite -(setIidPr (Mho_sub 1 W)) -kerf. + by rewrite (card_isog (first_isog_loc _ _)) //= imfW (dim_abelemE abelV). +have expW: exponent W = q. + apply/eqP; rewrite -(@eqn_exp2r _ _ ('dim V)) // -{1}rW_V -expnM mulnC expnM. + by rewrite (dim_abelemE abelV) -?card_pgroup // -oW eq_sym max_card_abelian. +have{rW_V} /isogP[fW injfW im_fW]: [set: 'rV['Z_q](V)] \isog W. + rewrite eq_abelian_type_isog ?zmod_abelian // abelian_type_mx_group ?mul1n //. + by rewrite abelian_type_homocyclic // rW_V expW. +have WfW u: fW u \in W by rewrite -im_fW mem_morphim ?inE. +have [fW' [DfW' KfW' _ _]] := domP (invm_morphism injfW) im_fW. +have{KfW'} injfW': 'injm fW' by rewrite KfW' injm_invm. +have fW'K: {in W, cancel fW' fW} by move=> w Ww; rewrite DfW' invmK //= im_fW. +have toWlin a1: linear (fun u => fW' (fW u ^ val (subg G1 a1))). + move=> z /= x y; rewrite (morphM fW) /= ?in_setT // conjMg /=. + rewrite morphM ?memJ_norm ?(subsetP nWG1) ?subgP //=; congr (_ * _). + rewrite -(natr_Zp z) !scaler_nat morphX ?in_setT // conjXg morphX //. + by rewrite memJ_norm // (subsetP nWG1) ?subgP. +pose rW a1 := lin1_mx (Linear (toWlin a1)). +pose fG := restrm sG1D f; have im_fG : fG @* G1 = G by rewrite im_restrm. +have injfG: 'injm fG by rewrite -tiWG1 setIC ker_restrm kerf setIS ?Mho_sub. +pose fG' := invm injfG; have im_fG': fG' @* G = G1 by rewrite -im_fG im_invm. +pose gamma i := \sum_(a in A i) rW (fG' a). +suffices{sum_k partG} tr_rW_Ai i: nz_k i -> \tr (gamma i) = (rC i * #|A i|)%:R. + have Dtr k i: nz_k i -> (rC i * k i * #|A i|)%:R = \tr (gamma i *+ k i). + by rewrite mulnAC natrM raddfMn mulr_natr /= => /tr_rW_Ai->. + rewrite -!val_Zp_nat // !natr_sum !{1}(eq_bigr _ (Dtr _)){Dtr}; congr (val _). + rewrite -!raddf_sum -!(eq_bigr _ (fun i _ => sumrMnl _ _ _ _)); congr (\tr _). + have sA_GP i a nz_i := subsetP (sA_G i nz_i) a. + rewrite !(exchange_big_dep (mem G)) {sA_GP}//=; apply: eq_bigr => a Ga. + by rewrite !sumrMnr !(big_andbC _ _ _ nz_k) -!/(sum_k _ A a _) partG. +move/sA_G=> {sA_G} sAiG; pose Ai1 := fG' @* A i; pose rR := 'r([~: W, Ai1]). +have sAiG1: Ai1 \subset G1 by rewrite -im_fG' morphimS. +have AfG' a: a \in A i -> fG' a \in Ai1. + by move=> Aa; rewrite mem_morphim //= im_restrm imfG1 ?(subsetP sAiG). +have coWAi1: coprime #|W| #|Ai1|. + by rewrite coprime_morphr ?(coprimegS sAiG) ?(pnat_coprime pW). +suffices [Pl [Pr [Pu [Pd [PlrudK ErC ErR]]]]]: + exists Pl, exists Pr, exists Pu, exists Pd, + [/\ row_mx Pl Pr *m col_mx Pu Pd = 1%R, + {in A i, forall a, Pd *m (rW (fG' a) *m Pr) = 1%:M :> 'M_(rC i)} + & \sum_(a in A i) Pu *m (rW (fG' a) *m Pl) = 0 :> 'M_rR]. +- rewrite -(mulmx1 (gamma i)) idmxE -PlrudK mulmxA mxtrace_mulC mul_mx_row. + rewrite mul_col_row mxtrace_block !mulmx_suml !mulmx_sumr ErR mxtrace0 add0r. + by rewrite (eq_bigr _ ErC) sumr_const raddfMn /= mxtrace1 natrM mulr_natr. +have defW: [~: W, Ai1] \x 'C_W(Ai1) = W. + by rewrite coprime_abelian_cent_dprod ?(subset_trans sAiG1). +have [_ mulRCW _ tiRCW] := dprodP defW; have [sRW sCW] := mulG_sub mulRCW. +have [homoRW homoCW] := dprod_homocyclic defW pW homoW. +have [] := abelian_type_dprod_homocyclic defW pW homoW. +rewrite expW -/rR => atypeRW atypeCW. +have [[cRR _] [cCC _]] := (andP homoRW, andP homoCW). +have{cRR atypeRW} /isogP[hR injhR im_hR]: [~: W, Ai1] \isog [set: 'rV['Z_q]_rR]. + rewrite eq_abelian_type_isog ?zmod_abelian ?atypeRW //. + by rewrite abelian_type_mx_group // mul1n eqxx. +have{tiRCW} rCW : 'r('C_W(Ai1)) = rC i. + rewrite -['r(_)]rank_Ohm1; have /rank_abelem ->: p.-abelem 'Ohm_1('C_W(Ai1)). + by rewrite Ohm1_abelem ?(pgroupS (subsetIl _ _)). + congr (logn p _); transitivity #|'C_W(Ai1) : 'Mho^1('C_W(Ai1))|. + by rewrite -divgS ?Mho_sub // -(mul_card_Ohm_Mho_abelian 1 cCC) mulnK. + transitivity #|'C_W(Ai1) : 'Mho^1(W)|. + symmetry; have /dprodP[_ /= defW1 _ _] := Mho_dprod 1 defW. + rewrite -indexgI; congr #|_ : _|; rewrite /= -defW1 -group_modr ?Mho_sub //. + by rewrite [_ :&: _](trivgP _) ?mul1g //= setIC -tiRCW setSI ?Mho_sub. + suffices /card_isog ->: 'C_V(A i) \isog 'C_W(Ai1) / 'Mho^1(W). + by rewrite card_quotient // subIset // normal_norm ?Mho_normal. + rewrite coprime_quotient_cent ?Mho_sub ?abelian_sol //= -/Ai1; last first. + by rewrite (subset_trans sAiG1) // (char_norm_trans _ nWG1) ?Mho_char. + have ->: A i :=: fG @* Ai1. + by rewrite /Ai1 morphim_invmE morphpreK // im_restrm imfG1. + rewrite -imfW morphim_restrm (setIidPr sAiG1). + have [f1 injf1 im_f1] := first_isom f. + rewrite -!im_f1 -injm_subcent ?quotientS ?(subset_trans sAiG1) //. + by rewrite -kerf isog_sym sub_isog // subIset ?quotientS. +have{atypeCW} /isogP[hC injhC im_hC]: 'C_W(Ai1) \isog [set: 'rV['Z_q]_(rC i)]. + rewrite eq_abelian_type_isog ?zmod_abelian // atypeCW rCW. + by rewrite abelian_type_mx_group ?mul1n. +have mkMx m1 m2 (U : {group 'rV['Z_q]_m1}) (g : {morphism U >-> 'rV['Z_q]_m2}): + setT \subset 'dom g -> {Mg | mulmx^~ Mg =1 g}. +- move/subsetP=> allU; suffices lin_g: linear g. + by exists (lin1_mx (Linear lin_g)) => u; rewrite mul_rV_lin1. + move=> z u v; rewrite morphM ?allU ?in_setT //. + by rewrite -(natr_Zp z) !scaler_nat -zmodXgE morphX ?allU ?in_setT. +have /mkMx[Pu defPu]: setT \subset 'dom (invm injfW \o invm injhR). + by rewrite -sub_morphim_pre -im_hR // im_invm //= im_fW. +have /mkMx[Pd defPd]: setT \subset 'dom (invm injfW \o invm injhC). + by rewrite -sub_morphim_pre -im_hC //= im_fW im_invm subsetIl. +pose fUl := pairg1 [finGroupType of 'rV['Z_q]_(rC i)] \o hR. +pose fUr := @pair1g [finGroupType of 'rV['Z_q]_rR] _ \o hC. +have cRCW: fUr @* 'C_W(Ai1) \subset 'C(fUl @* [~: W, Ai1]). + rewrite !morphim_comp morphim_pair1g morphim_pairg1. + set UR := hR @* _; set UC := hC @* _. + by have/dprodP[] : _ = setX UR UC := setX_dprod _ _. +have /domP[fUr' [DfUr' _ _ im_fUr']]: 'dom fUr = 'C_W(Ai1). + by rewrite /dom -im_hC injmK. +have /domP[fUl' [DfUl' _ _ im_fUl']]: 'dom fUl = [~: W, Ai1]. + by rewrite /dom -im_hR injmK. +rewrite -{}im_fUr' -{}im_fUl' in cRCW; pose hW := dprodm defW cRCW. +pose fPl := @fst _ _ \o (hW \o fW); pose fPr := @snd _ _ \o (hW \o fW). +have /mkMx[/= Pl defPl]: setT \subset 'dom fPl. + by rewrite -!sub_morphim_pre ?subsetT ?im_fW. +have /mkMx[/= Pr defPr]: setT \subset 'dom fPr. + by rewrite -!sub_morphim_pre ?subsetT ?im_fW. +exists Pl, Pr, Pu, Pd; split. +- apply/row_matrixP=> j; rewrite rowE -row1 mul_row_col mulmxDr !mulmxA. + apply: (injmP injfW); rewrite ?in_setT // morphM ?in_setT //. + rewrite defPl defPr defPu defPd -/hW [hW]lock /= -lock. + have /(mem_dprod defW)[jR [jC [RjR CjC -> _]]]:= WfW (row j 1). + rewrite [hW _]dprodmE // DfUl' DfUr' /= mulg1 mul1g !invmE // -DfW'. + by rewrite !fW'K ?(subsetP sRW jR) ?(subsetP sCW). +- move=> a Aa; apply/row_matrixP=> j; pose jC := invm injhC (row j 1%:M). + rewrite rowE -row1 !mulmxA defPd defPr -/hW [hW]lock /= mul_rV_lin1 /= -lock. + have CjC: jC \in 'C_W(Ai1). + by rewrite -(im_invm injhC) mem_morphim /= ?im_hC ?inE. + have [[/fW'K id_jC /centP cA1jC] A1a] := (setIP CjC, AfG' a Aa). + rewrite -DfW' id_jC subgK ?(subsetP sAiG1) // /conjg cA1jC // mulKg id_jC. + by rewrite [hW _]dprodmEr ?DfUr' //= invmK ?im_hC ?inE. +apply/row_matrixP=> j; pose jR := invm injhR (row j 1%:M). +have RjR: jR \in [~: W, Ai1]. + by rewrite -(im_invm injhR) mem_morphim /= ?im_hR ?inE. +rewrite rowE -row1 mulmx_sumr raddf0 -/jR. +have /subsetP nRA1: Ai1 \subset 'N([~: W, Ai1]) by rewrite commg_normr. +transitivity (\sum_(a1 in Ai1) hR (jR ^ a1)). + rewrite {1}[Ai1 in rhs in _ = rhs]morphimEsub /= ?im_restrm ?imfG1 //. + rewrite big_imset /=; last first. + apply: sub_in2 (injmP (injm_invm injfG)); apply/subsetP. + by rewrite /= im_restrm imfG1. + apply: eq_bigr => a /AfG' A1a. + have RjRa: jR ^ fG' a \in [~: W, Ai1] by rewrite memJ_norm ?nRA1. + rewrite !mulmxA defPu defPl mul_rV_lin1 -/hW [hW]lock /= -lock. + rewrite subgK ?(subsetP sAiG1) // -DfW' !fW'K ?(subsetP sRW) //. + by rewrite [hW _]dprodmEl // DfUl'. +have [nf [fj Rfj ->]] := gen_prodgP RjR. +transitivity (\sum_(a1 in Ai1) (\prod_i1 hR (fj i1 ^ a1))%g). + apply: eq_bigr => a1 Aa1; rewrite conjg_prod morph_prod // => i1 _. + by rewrite memJ_norm ?mem_gen ?nRA1. +rewrite exchange_big big1 //= => i1 _; have /imset2P[w a1 Ww Aa1 ->] := Rfj i1. +apply: (addrI (\sum_(a2 in Ai1) hR [~ w, a2])). +rewrite addr0 {2}(reindex_inj (mulgI a1)) -big_split /=. +apply: eq_big => [a2 | a2 Aa2]; first by rewrite groupMl. +by rewrite commgMJ [rhs in _ = rhs]morphM ?memJ_norm ?nRA1 ?mem_commg ?groupM. +Qed. |
