From c7ddacdfc43ba25c9fbd9505b3960047c13596d0 Mon Sep 17 00:00:00 2001 From: Cyril Cohen Date: Tue, 24 Mar 2015 12:23:33 +0100 Subject: metadata for solvable and field --- mathcomp/field/AUTHORS | 1 + mathcomp/field/CeCILL-B | 1 + mathcomp/field/INSTALL | 1 + mathcomp/field/Make | 14 + mathcomp/field/Makefile | 23 ++ mathcomp/field/README | 1 + mathcomp/field/opam | 12 + mathcomp/odd_order/wielandt_fixpoint.v | 651 +++++++++++++++++++++++++++++++++ mathcomp/solvable/AUTHORS | 1 + mathcomp/solvable/CeCILL-B | 1 + mathcomp/solvable/INSTALL | 1 + mathcomp/solvable/Make | 21 ++ mathcomp/solvable/Makefile | 23 ++ mathcomp/solvable/README | 1 + mathcomp/solvable/opam | 12 + mathcomp/solvable/wielandt_fixpoint.v | 651 --------------------------------- 16 files changed, 764 insertions(+), 651 deletions(-) create mode 120000 mathcomp/field/AUTHORS create mode 120000 mathcomp/field/CeCILL-B create mode 120000 mathcomp/field/INSTALL create mode 100644 mathcomp/field/Make create mode 100644 mathcomp/field/Makefile create mode 120000 mathcomp/field/README create mode 100644 mathcomp/field/opam create mode 100644 mathcomp/odd_order/wielandt_fixpoint.v create mode 120000 mathcomp/solvable/AUTHORS create mode 120000 mathcomp/solvable/CeCILL-B create mode 120000 mathcomp/solvable/INSTALL create mode 100644 mathcomp/solvable/Make create mode 100644 mathcomp/solvable/Makefile create mode 120000 mathcomp/solvable/README create mode 100644 mathcomp/solvable/opam delete mode 100644 mathcomp/solvable/wielandt_fixpoint.v (limited to 'mathcomp') diff --git a/mathcomp/field/AUTHORS b/mathcomp/field/AUTHORS new file mode 120000 index 0000000..b55a98d --- /dev/null +++ b/mathcomp/field/AUTHORS @@ -0,0 +1 @@ +../../etc/AUTHORS \ No newline at end of file diff --git a/mathcomp/field/CeCILL-B b/mathcomp/field/CeCILL-B new file mode 120000 index 0000000..83e22fd --- /dev/null +++ b/mathcomp/field/CeCILL-B @@ -0,0 +1 @@ +../../etc/CeCILL-B \ No newline at end of file diff --git a/mathcomp/field/INSTALL b/mathcomp/field/INSTALL new file mode 120000 index 0000000..6aa7ec5 --- /dev/null +++ b/mathcomp/field/INSTALL @@ -0,0 +1 @@ +../../etc/INSTALL \ No newline at end of file diff --git a/mathcomp/field/Make b/mathcomp/field/Make new file mode 100644 index 0000000..93ff57c --- /dev/null +++ b/mathcomp/field/Make @@ -0,0 +1,14 @@ +all.v +algC.v +algebraics_fundamentals.v +algnum.v +closed_field.v +countalg.v +cyclotomic.v +falgebra.v +fieldext.v +finfield.v +galois.v +separable.v + +-R . mathcomp.field diff --git a/mathcomp/field/Makefile b/mathcomp/field/Makefile new file mode 100644 index 0000000..d693257 --- /dev/null +++ b/mathcomp/field/Makefile @@ -0,0 +1,23 @@ +H=@ + +ifeq "$(COQBIN)" "" +COQBIN=$(dir $(shell which coqtop))/ +endif + + +OLD_MAKEFLAGS:=$(MAKEFLAGS) +MAKEFLAGS+=-B + +.DEFAULT_GOAL := all + +%: + $(H)[ -e Makefile.coq ] || $(COQBIN)/coq_makefile -f Make -o Makefile.coq + $(H)MAKEFLAGS=$(OLD_MAKEFLAGS) $(MAKE) --no-print-directory \ + -f Makefile.coq $* + +.PHONY: clean +clean: + $(H)MAKEFLAGS=$(OLD_MAKEFLAGS) $(MAKE) --no-print-directory \ + -f Makefile.coq clean + $(H)rm -f Makefile.coq + diff --git a/mathcomp/field/README b/mathcomp/field/README new file mode 120000 index 0000000..e4e30e8 --- /dev/null +++ b/mathcomp/field/README @@ -0,0 +1 @@ +../../etc/README \ No newline at end of file diff --git a/mathcomp/field/opam b/mathcomp/field/opam new file mode 100644 index 0000000..659ad66 --- /dev/null +++ b/mathcomp/field/opam @@ -0,0 +1,12 @@ +opam-version: "1.2" +name: "coq:mathcomp:field" +version: "1.5" +maintainer: "Ssreflect " +authors: "Ssreflect " +homepage: "http://ssr.msr-inria.inria.fr/" +bug-reports: "ssreflect@msr-inria.inria.fr" +license: "CeCILL-B" +build: [ make "-j" "%{jobs}%" ] +install: [ make "install" ] +remove: [ "sh" "-c" "rm -rf '%{lib}%/coq/user-contrib/mathcomp/field'" ] +depends: [ "coq:mathcomp:solvable" { = "1.5" } ] 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. diff --git a/mathcomp/solvable/AUTHORS b/mathcomp/solvable/AUTHORS new file mode 120000 index 0000000..b55a98d --- /dev/null +++ b/mathcomp/solvable/AUTHORS @@ -0,0 +1 @@ +../../etc/AUTHORS \ No newline at end of file diff --git a/mathcomp/solvable/CeCILL-B b/mathcomp/solvable/CeCILL-B new file mode 120000 index 0000000..83e22fd --- /dev/null +++ b/mathcomp/solvable/CeCILL-B @@ -0,0 +1 @@ +../../etc/CeCILL-B \ No newline at end of file diff --git a/mathcomp/solvable/INSTALL b/mathcomp/solvable/INSTALL new file mode 120000 index 0000000..6aa7ec5 --- /dev/null +++ b/mathcomp/solvable/INSTALL @@ -0,0 +1 @@ +../../etc/INSTALL \ No newline at end of file diff --git a/mathcomp/solvable/Make b/mathcomp/solvable/Make new file mode 100644 index 0000000..41bd3e0 --- /dev/null +++ b/mathcomp/solvable/Make @@ -0,0 +1,21 @@ +abelian.v +all.v +alt.v +burnside_app.v +center.v +commutator.v +extraspecial.v +extremal.v +finmodule.v +frobenius.v +gfunctor.v +gseries.v +hall.v +jordanholder.v +maximal.v +nilpotent.v +pgroup.v +primitive_action.v +sylow.v + +-R . mathcomp.solvable diff --git a/mathcomp/solvable/Makefile b/mathcomp/solvable/Makefile new file mode 100644 index 0000000..d693257 --- /dev/null +++ b/mathcomp/solvable/Makefile @@ -0,0 +1,23 @@ +H=@ + +ifeq "$(COQBIN)" "" +COQBIN=$(dir $(shell which coqtop))/ +endif + + +OLD_MAKEFLAGS:=$(MAKEFLAGS) +MAKEFLAGS+=-B + +.DEFAULT_GOAL := all + +%: + $(H)[ -e Makefile.coq ] || $(COQBIN)/coq_makefile -f Make -o Makefile.coq + $(H)MAKEFLAGS=$(OLD_MAKEFLAGS) $(MAKE) --no-print-directory \ + -f Makefile.coq $* + +.PHONY: clean +clean: + $(H)MAKEFLAGS=$(OLD_MAKEFLAGS) $(MAKE) --no-print-directory \ + -f Makefile.coq clean + $(H)rm -f Makefile.coq + diff --git a/mathcomp/solvable/README b/mathcomp/solvable/README new file mode 120000 index 0000000..e4e30e8 --- /dev/null +++ b/mathcomp/solvable/README @@ -0,0 +1 @@ +../../etc/README \ No newline at end of file diff --git a/mathcomp/solvable/opam b/mathcomp/solvable/opam new file mode 100644 index 0000000..e950335 --- /dev/null +++ b/mathcomp/solvable/opam @@ -0,0 +1,12 @@ +opam-version: "1.2" +name: "coq:mathcomp:solvable" +version: "1.5" +maintainer: "Ssreflect " +authors: "Ssreflect " +homepage: "http://ssr.msr-inria.inria.fr/" +bug-reports: "ssreflect@msr-inria.inria.fr" +license: "CeCILL-B" +build: [ make "-j" "%{jobs}%" ] +install: [ make "install" ] +remove: [ "sh" "-c" "rm -rf '%{lib}%/coq/user-contrib/mathcomp/solvable'" ] +depends: [ "coq:mathcomp:algebra" { = "1.5" } ] diff --git a/mathcomp/solvable/wielandt_fixpoint.v b/mathcomp/solvable/wielandt_fixpoint.v deleted file mode 100644 index beebc3d..0000000 --- a/mathcomp/solvable/wielandt_fixpoint.v +++ /dev/null @@ -1,651 +0,0 @@ -(* (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. -- cgit v1.2.3