diff options
| author | Enrico Tassi | 2015-03-09 11:07:53 +0100 |
|---|---|---|
| committer | Enrico Tassi | 2015-03-09 11:24:38 +0100 |
| commit | fc84c27eac260dffd8f2fb1cb56d599f1e3486d9 (patch) | |
| tree | c16205f1637c80833a4c4598993c29fa0fd8c373 /mathcomp/solvable/finmodule.v | |
Initial commit
Diffstat (limited to 'mathcomp/solvable/finmodule.v')
| -rw-r--r-- | mathcomp/solvable/finmodule.v | 596 |
1 files changed, 596 insertions, 0 deletions
diff --git a/mathcomp/solvable/finmodule.v b/mathcomp/solvable/finmodule.v new file mode 100644 index 0000000..e2eae84 --- /dev/null +++ b/mathcomp/solvable/finmodule.v @@ -0,0 +1,596 @@ +(* (c) Copyright Microsoft Corporation and Inria. All rights reserved. *) +Require Import ssreflect ssrbool ssrfun eqtype ssrnat seq path div choice. +Require Import fintype bigop ssralg finset fingroup morphism perm. +Require Import finalg action gproduct commutator cyclic. + +(******************************************************************************) +(* This file regroups constructions and results that are based on the most *) +(* primitive version of representation theory -- viewing an abelian group as *) +(* the additive group of a (finite) Z-module. This includes the Gaschutz *) +(* splitting and transitivity theorem, from which we will later derive the *) +(* Schur-Zassenhaus theorem and the elementary abelian special case of *) +(* Maschke's theorem, the coprime abelian centraliser/commutator trivial *) +(* intersection theorem, from which we will derive that p-groups under coprime*) +(* action factor into special groups, and the construction of the transfer *) +(* homomorphism and its expansion relative to a cycle, from which we derive *) +(* the Higman Focal Subgroup and the Burnside Normal Complement theorems. *) +(* The definitions and lemmas for the finite Z-module induced by an abelian *) +(* are packaged in an auxiliary FiniteModule submodule: they should not be *) +(* needed much outside this file, which contains all the results that exploit *) +(* this construction. *) +(* FiniteModule defines the Z[N(A)]-module associated with a finite abelian *) +(* abelian group A, given a proof abelA : abelian A) : *) +(* fmod_of abelA == the type of elements of the module (similar to but *) +(* distinct from [subg A]). *) +(* fmod abelA x == the injection of x into fmod_of abelA if x \in A, else 0 *) +(* fmval u == the projection of u : fmod_of abelA onto A *) +(* u ^@ x == the action of x \in 'N(A) on u : fmod_of abelA *) +(* The transfer morphism is be constructed from a morphism f : H >-> rT, and *) +(* a group G, along with the two assumptions sHG : H \subset G and *) +(* abfH : abelian (f @* H): *) +(* transfer sGH abfH == the function gT -> FiniteModule.fmod_of abfH that *) +(* implements the transfer morphism induced by f on G. *) +(* The Lemma transfer_indep states that the transfer morphism can be expanded *) +(* using any transversal of the partition HG := rcosets H G of G. *) +(* Further, for any g \in G, HG :* <[g]> is also a partition of G (Lemma *) +(* rcosets_cycle_partition), and for any transversal X of HG :* <[g]> the *) +(* function r mapping x : gT to rcosets (H :* x) <[g]> is (constructively) a *) +(* bijection from X to the <[g]>-orbit partition of HG, and Lemma *) +(* transfer_pcycle_def gives a simplified expansion of the transfer morphism. *) +(******************************************************************************) + +Set Implicit Arguments. +Unset Strict Implicit. +Unset Printing Implicit Defensive. + +Import GroupScope GRing.Theory FinRing.Theory. +Local Open Scope ring_scope. + +Module FiniteModule. + +Reserved Notation "u ^@ x" (at level 31, left associativity). + +Inductive fmod_of (gT : finGroupType) (A : {group gT}) (abelA : abelian A) := + Fmod x & x \in A. + +Bind Scope ring_scope with fmod_of. + +Section OneFinMod. + +Let f2sub (gT : finGroupType) (A : {group gT}) (abA : abelian A) := + fun u : fmod_of abA => let : Fmod x Ax := u in Subg Ax : FinGroup.arg_sort _. +Local Coercion f2sub : fmod_of >-> FinGroup.arg_sort. + +Variables (gT : finGroupType) (A : {group gT}) (abelA : abelian A). +Local Notation fmodA := (fmod_of abelA). +Implicit Types (x y z : gT) (u v w : fmodA). + +Let sub2f (s : [subg A]) := Fmod abelA (valP s). + +Definition fmval u := val (f2sub u). +Canonical fmod_subType := [subType for fmval]. +Local Notation valA := (@val _ _ fmod_subType) (only parsing). +Definition fmod_eqMixin := Eval hnf in [eqMixin of fmodA by <:]. +Canonical fmod_eqType := Eval hnf in EqType fmodA fmod_eqMixin. +Definition fmod_choiceMixin := [choiceMixin of fmodA by <:]. +Canonical fmod_choiceType := Eval hnf in ChoiceType fmodA fmod_choiceMixin. +Definition fmod_countMixin := [countMixin of fmodA by <:]. +Canonical fmod_countType := Eval hnf in CountType fmodA fmod_countMixin. +Canonical fmod_subCountType := Eval hnf in [subCountType of fmodA]. +Definition fmod_finMixin := [finMixin of fmodA by <:]. +Canonical fmod_finType := Eval hnf in FinType fmodA fmod_finMixin. +Canonical fmod_subFinType := Eval hnf in [subFinType of fmodA]. + +Definition fmod x := sub2f (subg A x). +Definition actr u x := if x \in 'N(A) then fmod (fmval u ^ x) else u. + +Definition fmod_opp u := sub2f u^-1. +Definition fmod_add u v := sub2f (u * v). + +Fact fmod_add0r : left_id (sub2f 1) fmod_add. +Proof. move=> u; apply: val_inj; exact: mul1g. Qed. + +Fact fmod_addrA : associative fmod_add. +Proof. move=> u v w; apply: val_inj; exact: mulgA. Qed. + +Fact fmod_addNr : left_inverse (sub2f 1) fmod_opp fmod_add. +Proof. move=> u; apply: val_inj; exact: mulVg. Qed. + +Fact fmod_addrC : commutative fmod_add. +Proof. case=> x Ax [y Ay]; apply: val_inj; exact: (centsP abelA). Qed. + +Definition fmod_zmodMixin := + ZmodMixin fmod_addrA fmod_addrC fmod_add0r fmod_addNr. +Canonical fmod_zmodType := Eval hnf in ZmodType fmodA fmod_zmodMixin. +Canonical fmod_finZmodType := Eval hnf in [finZmodType of fmodA]. +Canonical fmod_baseFinGroupType := + Eval hnf in [baseFinGroupType of fmodA for +%R]. +Canonical fmod_finGroupType := + Eval hnf in [finGroupType of fmodA for +%R]. + +Lemma fmodP u : val u \in A. Proof. exact: valP. Qed. +Lemma fmod_inj : injective fmval. Proof. exact: val_inj. Qed. +Lemma congr_fmod u v : u = v -> fmval u = fmval v. +Proof. exact: congr1. Qed. + +Lemma fmvalA : {morph valA : x y / x + y >-> (x * y)%g}. Proof. by []. Qed. +Lemma fmvalN : {morph valA : x / - x >-> x^-1%g}. Proof. by []. Qed. +Lemma fmval0 : valA 0 = 1%g. Proof. by []. Qed. +Canonical fmval_morphism := @Morphism _ _ setT fmval (in2W fmvalA). + +Definition fmval_sum := big_morph fmval fmvalA fmval0. + +Lemma fmvalZ n : {morph valA : x / x *+ n >-> (x ^+ n)%g}. +Proof. by move=> u; rewrite /= morphX ?inE. Qed. + +Lemma fmodKcond x : val (fmod x) = if x \in A then x else 1%g. +Proof. by rewrite /= /fmval /= val_insubd. Qed. +Lemma fmodK : {in A, cancel fmod val}. Proof. exact: subgK. Qed. +Lemma fmvalK : cancel val fmod. +Proof. by case=> x Ax; apply: val_inj; rewrite /fmod /= sgvalK. Qed. +Lemma fmod1 : fmod 1 = 0. Proof. by rewrite -fmval0 fmvalK. Qed. +Lemma fmodM : {in A &, {morph fmod : x y / (x * y)%g >-> x + y}}. +Proof. by move=> x y Ax Ay /=; apply: val_inj; rewrite /fmod morphM. Qed. +Canonical fmod_morphism := Morphism fmodM. +Lemma fmodX n : {in A, {morph fmod : x / (x ^+ n)%g >-> x *+ n}}. +Proof. exact: morphX. Qed. +Lemma fmodV : {morph fmod : x / x^-1%g >-> - x}. +Proof. +move=> x; apply: val_inj; rewrite fmvalN !fmodKcond groupV. +by case: (x \in A); rewrite ?invg1. +Qed. + +Lemma injm_fmod : 'injm fmod. +Proof. +apply/injmP=> x y Ax Ay []; move/val_inj; exact: (injmP (injm_subg A)). +Qed. + +Notation "u ^@ x" := (actr u x) : ring_scope. + +Lemma fmvalJcond u x : + val (u ^@ x) = if x \in 'N(A) then val u ^ x else val u. +Proof. by case: ifP => Nx; rewrite /actr Nx ?fmodK // memJ_norm ?fmodP. Qed. + +Lemma fmvalJ u x : x \in 'N(A) -> val (u ^@ x) = val u ^ x. +Proof. by move=> Nx; rewrite fmvalJcond Nx. Qed. + +Lemma fmodJ x y : y \in 'N(A) -> fmod (x ^ y) = fmod x ^@ y. +Proof. +move=> Ny; apply: val_inj; rewrite fmvalJ ?fmodKcond ?memJ_norm //. +by case: ifP => // _; rewrite conj1g. +Qed. + +Fact actr_is_action : is_action 'N(A) actr. +Proof. +split=> [a u v eq_uv_a | u a b Na Nb]. + case Na: (a \in 'N(A)); last by rewrite /actr Na in eq_uv_a. + by apply: val_inj; apply: (conjg_inj a); rewrite -!fmvalJ ?eq_uv_a. +by apply: val_inj; rewrite !fmvalJ ?groupM ?conjgM. +Qed. + +Canonical actr_action := Action actr_is_action. +Notation "''M'" := actr_action (at level 8) : action_scope. + +Lemma act0r x : 0 ^@ x = 0. +Proof. by rewrite /actr conj1g morph1 if_same. Qed. + +Lemma actAr x : {morph actr^~ x : u v / u + v}. +Proof. +by move=> u v; apply: val_inj; rewrite !(fmvalA, fmvalJcond) conjMg; case: ifP. +Qed. + +Definition actr_sum x := big_morph _ (actAr x) (act0r x). + +Lemma actNr x : {morph actr^~ x : u / - u}. +Proof. by move=> u; apply: (addrI (u ^@ x)); rewrite -actAr !subrr act0r. Qed. + +Lemma actZr x n : {morph actr^~ x : u / u *+ n}. +Proof. +by move=> u; elim: n => [|n IHn]; rewrite ?act0r // !mulrS actAr IHn. +Qed. + +Fact actr_is_groupAction : is_groupAction setT 'M. +Proof. +move=> a Na /=; rewrite inE; apply/andP; split. + by apply/subsetP=> u _; rewrite inE. +by apply/morphicP=> u v _ _; rewrite !permE /= actAr. +Qed. + +Canonical actr_groupAction := GroupAction actr_is_groupAction. +Notation "''M'" := actr_groupAction (at level 8) : groupAction_scope. + +Lemma actr1 u : u ^@ 1 = u. +Proof. exact: act1. Qed. + +Lemma actrM : {in 'N(A) &, forall x y u, u ^@ (x * y) = u ^@ x ^@ y}. +Proof. +by move=> x y Nx Ny /= u; apply: val_inj; rewrite !fmvalJ ?conjgM ?groupM. +Qed. + +Lemma actrK x : cancel (actr^~ x) (actr^~ x^-1%g). +Proof. +move=> u; apply: val_inj; rewrite !fmvalJcond groupV. +by case: ifP => -> //; rewrite conjgK. +Qed. + +Lemma actrKV x : cancel (actr^~ x^-1%g) (actr^~ x). +Proof. by move=> u; rewrite /= -{2}(invgK x) actrK. Qed. + +End OneFinMod. + +Bind Scope ring_scope with fmod_of. +Prenex Implicits fmval fmod actr. +Notation "u ^@ x" := (actr u x) : ring_scope. +Notation "''M'" := actr_action (at level 8) : action_scope. +Notation "''M'" := actr_groupAction : groupAction_scope. + +End FiniteModule. + +Canonical FiniteModule.fmod_subType. +Canonical FiniteModule.fmod_eqType. +Canonical FiniteModule.fmod_choiceType. +Canonical FiniteModule.fmod_countType. +Canonical FiniteModule.fmod_finType. +Canonical FiniteModule.fmod_subCountType. +Canonical FiniteModule.fmod_subFinType. +Canonical FiniteModule.fmod_zmodType. +Canonical FiniteModule.fmod_finZmodType. +Canonical FiniteModule.fmod_baseFinGroupType. +Canonical FiniteModule.fmod_finGroupType. + +(* Still allow ring notations, but give priority to groups now. *) +Import FiniteModule GroupScope. + +Section Gaschutz. + +Variables (gT : finGroupType) (G H P : {group gT}). +Implicit Types K L : {group gT}. + +Hypotheses (nsHG : H <| G) (sHP : H \subset P) (sPG : P \subset G). +Hypotheses (abelH : abelian H) (coHiPG : coprime #|H| #|G : P|). + +Let sHG := normal_sub nsHG. +Let nHG := subsetP (normal_norm nsHG). + +Let m := (expg_invn H #|G : P|). + +Implicit Types a b : fmod_of abelH. +Local Notation fmod := (fmod abelH). + +Theorem Gaschutz_split : [splits G, over H] = [splits P, over H]. +Proof. +apply/splitsP/splitsP=> [[K /complP[tiHK eqHK]] | [Q /complP[tiHQ eqHQ]]]. + exists (K :&: P)%G; rewrite inE setICA (setIidPl sHP) setIC tiHK eqxx. + by rewrite group_modl // eqHK (sameP eqP setIidPr). +have sQP: Q \subset P by rewrite -eqHQ mulG_subr. +pose rP x := repr (P :* x); pose pP x := x * (rP x)^-1. +have PpP x: pP x \in P by rewrite -mem_rcoset rcoset_repr rcoset_refl. +have rPmul x y: x \in P -> rP (x * y) = rP y. + by move=> Px; rewrite /rP rcosetM rcoset_id. +pose pQ x := remgr H Q x; pose rH x := pQ (pP x) * rP x. +have pQhq: {in H & Q, forall h q, pQ (h * q) = q} by exact: remgrMid. +have pQmul: {in P &, {morph pQ : x y / x * y}}. + apply: remgrM; [exact/complP | exact: normalS (nsHG)]. +have HrH x: rH x \in H :* x. + by rewrite rcoset_sym mem_rcoset invMg mulgA mem_divgr // eqHQ PpP. +have GrH x: x \in G -> rH x \in G. + move=> Gx; case/rcosetP: (HrH x) => y Hy ->. + by rewrite groupM // (subsetP sHG). +have rH_Pmul x y: x \in P -> rH (x * y) = pQ x * rH y. + by move=> Px; rewrite /rH mulgA -pQmul; first by rewrite /pP rPmul ?mulgA. +have rH_Hmul h y: h \in H -> rH (h * y) = rH y. + by move=> Hh; rewrite rH_Pmul ?(subsetP sHP) // -(mulg1 h) pQhq ?mul1g. +pose mu x y := fmod ((rH x * rH y)^-1 * rH (x * y)). +pose nu y := (\sum_(Px in rcosets P G) mu (repr Px) y)%R. +have rHmul: {in G &, forall x y, rH (x * y) = rH x * rH y * val (mu x y)}. + move=> x y Gx Gy; rewrite /= fmodK ?mulKVg // -mem_lcoset lcoset_sym. + rewrite -norm_rlcoset; last by rewrite nHG ?GrH ?groupM. + by rewrite (rcoset_transl (HrH _)) -rcoset_mul ?nHG ?GrH // mem_mulg. +have actrH a x: x \in G -> (a ^@ rH x = a ^@ x)%R. + move=> Gx; apply: val_inj; rewrite /= !fmvalJ ?nHG ?GrH //. + case/rcosetP: (HrH x) => b /(fmodK abelH) <- ->; rewrite conjgM. + by congr (_ ^ _); rewrite conjgE -fmvalN -!fmvalA (addrC a) addKr. +have mu_Pmul x y z: x \in P -> mu (x * y) z = mu y z. + move=> Px; congr fmod; rewrite -mulgA !(rH_Pmul x) ?rPmul //. + by rewrite -mulgA invMg -mulgA mulKg. +have mu_Hmul x y z: x \in G -> y \in H -> mu x (y * z) = mu x z. + move=> Gx Hy; congr fmod; rewrite (mulgA x) (conjgCV x) -mulgA 2?rH_Hmul //. + by rewrite -mem_conjg (normP _) ?nHG. +have{mu_Hmul} nu_Hmul y z: y \in H -> nu (y * z) = nu z. + move=> Hy; apply: eq_bigr => _ /rcosetsP[x Gx ->]; apply: mu_Hmul y z _ Hy. + by rewrite -(groupMl _ (subsetP sPG _ (PpP x))) mulgKV. +have cocycle_mu: {in G & &, forall x y z, + mu (x * y)%g z + mu x y ^@ z = mu y z + mu x (y * z)%g}%R. +- move=> x y z Gx Gy Gz; apply: val_inj. + apply: (mulgI (rH x * rH y * rH z)). + rewrite -(actrH _ _ Gz) addrC fmvalA fmvalJ ?nHG ?GrH //. + rewrite mulgA -(mulgA _ (rH z)) -conjgC mulgA -!rHmul ?groupM //. + by rewrite mulgA -mulgA -2!(mulgA (rH x)) -!rHmul ?groupM. +move: mu => mu in rHmul mu_Pmul cocycle_mu nu nu_Hmul. +have{cocycle_mu} cocycle_nu: {in G &, forall y z, + nu z + nu y ^@ z = mu y z *+ #|G : P| + nu (y * z)%g}%R. +- move=> y z Gy Gz; rewrite /= (actr_sum z) /=. + have ->: (nu z = \sum_(Px in rcosets P G) mu (repr Px * y)%g z)%R. + rewrite /nu (reindex_acts _ (actsRs_rcosets P G) Gy) /=. + apply: eq_bigr => _ /rcosetsP[x Gx /= ->]. + rewrite rcosetE -rcosetM. + case: repr_rcosetP=> p1 Pp1; case: repr_rcosetP=> p2 Pp2. + by rewrite -mulgA [x * y]lock !mu_Pmul. + rewrite -sumr_const -!big_split /=; apply: eq_bigr => _ /rcosetsP[x Gx ->]. + rewrite -cocycle_mu //; case: repr_rcosetP => p1 Pp1. + by rewrite groupMr // (subsetP sPG). +move: nu => nu in nu_Hmul cocycle_nu. +pose f x := rH x * val (nu x *+ m)%R. +have{cocycle_nu} fM: {in G &, {morph f : x y / x * y}}. + move=> x y Gx Gy; rewrite /f ?rHmul // -3!mulgA; congr (_ * _). + rewrite (mulgA _ (rH y)) (conjgC _ (rH y)) -mulgA; congr (_ * _). + rewrite -fmvalJ ?actrH ?nHG ?GrH // -!fmvalA actZr -mulrnDl. + rewrite -(addrC (nu y)) cocycle_nu // mulrnDl !fmvalA; congr (_ * _). + by rewrite !fmvalZ expgK ?fmodP. +exists (Morphism fM @* G)%G; apply/complP; split. + apply/trivgP/subsetP=> x /setIP[Hx /morphimP[y _ Gy eq_x]]. + apply/set1P; move: Hx; rewrite {x}eq_x /= groupMr ?subgP //. + rewrite -{1}(mulgKV y (rH y)) groupMl -?mem_rcoset // => Hy. + by rewrite -(mulg1 y) /f nu_Hmul // rH_Hmul //; exact: (morph1 (Morphism fM)). +apply/setP=> x; apply/mulsgP/idP=> [[h y Hh fy ->{x}] | Gx]. + rewrite groupMl; last exact: (subsetP sHG). + case/morphimP: fy => z _ Gz ->{h Hh y}. + by rewrite /= /f groupMl ?GrH // (subsetP sHG) ?fmodP. +exists (x * (f x)^-1) (f x); last first; first by rewrite mulgKV. + by apply/morphimP; exists x. +rewrite -groupV invMg invgK -mulgA (conjgC (val _)) mulgA. +by rewrite groupMl -(mem_rcoset, mem_conjg) // (normP _) ?nHG ?fmodP. +Qed. + +Theorem Gaschutz_transitive : {in [complements to H in G] &, + forall K L, K :&: P = L :&: P -> exists2 x, x \in H & L :=: K :^ x}. +Proof. +move=> K L /=; set Q := K :&: P => /complP[tiHK eqHK] cpHL QeqLP. +have [trHL eqHL] := complP cpHL. +pose nu x := fmod (divgr H L x^-1). +have sKG: {subset K <= G} by apply/subsetP; rewrite -eqHK mulG_subr. +have sLG: {subset L <= G} by apply/subsetP; rewrite -eqHL mulG_subr. +have val_nu x: x \in G -> val (nu x) = divgr H L x^-1. + by move=> Gx; rewrite fmodK // mem_divgr // eqHL groupV. +have nu_cocycle: {in G &, forall x y, nu (x * y)%g = nu x ^@ y + nu y}%R. + move=> x y Gx Gy; apply: val_inj; rewrite fmvalA fmvalJ ?nHG //. + rewrite !val_nu ?groupM // /divgr conjgE !mulgA mulgK. + by rewrite !(invMg, remgrM cpHL) ?groupV ?mulgA. +have nuL x: x \in L -> nu x = 0%R. + move=> Lx; apply: val_inj; rewrite val_nu ?sLG //. + by rewrite /divgr remgr_id ?groupV ?mulgV. +exists (fmval ((\sum_(X in rcosets Q K) nu (repr X)) *+ m)). + exact: fmodP. +apply/eqP; rewrite eq_sym eqEcard; apply/andP; split; last first. + by rewrite cardJg -(leq_pmul2l (cardG_gt0 H)) -!TI_cardMg // eqHL eqHK. +apply/subsetP=> _ /imsetP[x Kx ->]; rewrite conjgE mulgA (conjgC _ x). +have Gx: x \in G by rewrite sKG. +rewrite conjVg -mulgA -fmvalJ ?nHG // -fmvalN -fmvalA (_ : _ + _ = nu x)%R. + by rewrite val_nu // mulKVg groupV mem_remgr // eqHL groupV. +rewrite actZr -!mulNrn -mulrnDl actr_sum. +rewrite addrC (reindex_acts _ (actsRs_rcosets _ K) Kx) -sumrB /= -/Q. +rewrite (eq_bigr (fun _ => nu x)) => [|_ /imsetP[y Ky ->]]; last first. + rewrite !rcosetE -rcosetM QeqLP. + case: repr_rcosetP => z /setIP[Lz _]; case: repr_rcosetP => t /setIP[Lt _]. + rewrite !nu_cocycle ?groupM ?(sKG y) // ?sLG //. + by rewrite (nuL z) ?(nuL t) // !act0r !add0r addrC addKr. +apply: val_inj; rewrite sumr_const !fmvalZ. +rewrite -{2}(expgK coHiPG (fmodP (nu x))); congr (_ ^+ _ ^+ _). +rewrite -[#|_|]divgS ?subsetIl // -(divnMl (cardG_gt0 H)). +rewrite -!TI_cardMg //; last by rewrite setIA setIAC (setIidPl sHP). +by rewrite group_modl // eqHK (setIidPr sPG) divgS. +Qed. + +End Gaschutz. + +(* This is the TI part of B & G, Proposition 1.6(d). *) +(* We go with B & G rather than Aschbacher and will derive 1.6(e) from (d), *) +(* rather than the converse, because the derivation of 24.6 from 24.3 in *) +(* Aschbacher requires a separate reduction to p-groups to yield 1.6(d), *) +(* making it altogether longer than the direct Gaschutz-style proof. *) +(* This Lemma is used in maximal.v for the proof of Aschbacher 24.7. *) +Lemma coprime_abel_cent_TI (gT : finGroupType) (A G : {group gT}) : + A \subset 'N(G) -> coprime #|G| #|A| -> abelian G -> 'C_[~: G, A](A) = 1. +Proof. +move=> nGA coGA abG; pose f x := val (\sum_(a in A) fmod abG x ^@ a)%R. +have fM: {in G &, {morph f : x y / x * y}}. + move=> x y Gx Gy /=; rewrite -fmvalA -big_split /=; congr (fmval _). + by apply: eq_bigr => a Aa; rewrite fmodM // actAr. +have nfA x a: a \in A -> f (x ^ a) = f x. + move=> Aa; rewrite {2}/f (reindex_inj (mulgI a)) /=; congr (fmval _). + apply: eq_big => [b | b Ab]; first by rewrite groupMl. + by rewrite -!fmodJ ?groupM ?(subsetP nGA) // conjgM. +have kerR: [~: G, A] \subset 'ker (Morphism fM). + rewrite gen_subG; apply/subsetP=> xa; case/imset2P=> x a Gx Aa -> {xa}. + have Gxa: x ^ a \in G by rewrite memJ_norm ?(subsetP nGA). + rewrite commgEl; apply/kerP; rewrite (groupM, morphM) ?(groupV, morphV) //=. + by rewrite nfA ?mulVg. +apply/trivgP; apply/subsetP=> x /setIP[Rx cAx]; apply/set1P. +have Gx: x \in G by apply: subsetP Rx; rewrite commg_subl. +rewrite -(expgK coGA Gx) (_ : x ^+ _ = 1) ?expg1n //. +rewrite -(fmodK abG Gx) -fmvalZ -(mker (subsetP kerR x Rx)); congr fmval. +rewrite -GRing.sumr_const; apply: eq_bigr => a Aa. +by rewrite -fmodJ ?(subsetP nGA) // /conjg (centP cAx) // mulKg. +Qed. + +Section Transfer. + +Variables (gT aT : finGroupType) (G H : {group gT}). +Variable alpha : {morphism H >-> aT}. + +Hypotheses (sHG : H \subset G) (abelA : abelian (alpha @* H)). + +Local Notation HG := (rcosets (gval H) (gval G)). + +Fact transfer_morph_subproof : H \subset alpha @*^-1 (alpha @* H). +Proof. by rewrite -sub_morphim_pre. Qed. + +Let fmalpha := restrm transfer_morph_subproof (fmod abelA \o alpha). + +Let V (rX : {set gT} -> gT) g := + \sum_(Hx in rcosets H G) fmalpha (rX Hx * g * (rX (Hx :* g))^-1). + +Definition transfer g := V repr g. + +(* This is Aschbacher (37.2). *) +Lemma transferM : {in G &, {morph transfer : x y / (x * y)%g >-> x + y}}. +Proof. +move=> s t Gs Gt /=. +rewrite [transfer t](reindex_acts 'Rs _ Gs) ?actsRs_rcosets //= -big_split /=. +apply: eq_bigr => _ /rcosetsP[x Gx ->]; rewrite !rcosetE -!rcosetM. +rewrite -zmodMgE -morphM -?mem_rcoset; first by rewrite !mulgA mulgKV rcosetM. + by rewrite rcoset_repr rcosetM mem_rcoset mulgK mem_repr_rcoset. +by rewrite rcoset_repr (rcosetM _ _ t) mem_rcoset mulgK mem_repr_rcoset. +Qed. + +Canonical transfer_morphism := Morphism transferM. + +(* This is Aschbacher (37.1). *) +Lemma transfer_indep X (rX := transversal_repr 1 X) : + is_transversal X HG G -> {in G, transfer =1 V rX}. +Proof. +move=> trX g Gg; have mem_rX := repr_mem_pblock trX 1; rewrite -/rX in mem_rX. +apply: (addrI (\sum_(Hx in HG) fmalpha (repr Hx * (rX Hx)^-1))). +rewrite {1}(reindex_acts 'Rs _ Gg) ?actsRs_rcosets // -!big_split /=. +apply: eq_bigr => _ /rcosetsP[x Gx ->]; rewrite !rcosetE -!rcosetM. +case: repr_rcosetP => h1 Hh1; case: repr_rcosetP => h2 Hh2. +have: H :* (x * g) \in rcosets H G by rewrite -rcosetE mem_imset ?groupM. +have: H :* x \in rcosets H G by rewrite -rcosetE mem_imset. +case/mem_rX/rcosetP=> h3 Hh3 -> /mem_rX/rcosetP[h4 Hh4 ->]. +rewrite -!(mulgA h1) -!(mulgA h2) -!(mulgA h3) !(mulKVg, invMg). +by rewrite addrC -!zmodMgE -!morphM ?groupM ?groupV // -!mulgA !mulKg. +Qed. + +Section FactorTransfer. + +Variable g : gT. +Hypothesis Gg : g \in G. + +Let sgG : <[g]> \subset G. Proof. by rewrite cycle_subG. Qed. +Let H_g_rcosets x : {set {set gT}} := rcosets (H :* x) <[g]>. +Let n_ x := #|<[g]> : H :* x|. + +Lemma mulg_exp_card_rcosets x : x * (g ^+ n_ x) \in H :* x. +Proof. +rewrite /n_ /indexg -orbitRs -pcycle_actperm ?inE //. +rewrite -{2}(iter_pcycle (actperm 'Rs g) (H :* x)) -permX -morphX ?inE //. +by rewrite actpermE //= rcosetE -rcosetM rcoset_refl. +Qed. + +Let HGg : {set {set {set gT}}} := orbit 'Rs <[g]> @: HG. + +Let partHG : partition HG G := rcosets_partition sHG. +Let actsgHG : [acts <[g]>, on HG | 'Rs]. +Proof. exact: subset_trans sgG (actsRs_rcosets H G). Qed. +Let partHGg : partition HGg HG := orbit_partition actsgHG. + +Let injHGg : {in HGg &, injective cover}. +Proof. by have [] := partition_partition partHG partHGg. Qed. + +Let defHGg : HG :* <[g]> = cover @: HGg. +Proof. +rewrite -imset_comp [_ :* _]imset2_set1r; apply: eq_imset => Hx /=. +by rewrite cover_imset -curry_imset2r. +Qed. + +Lemma rcosets_cycle_partition : partition (HG :* <[g]>) G. +Proof. by rewrite defHGg; have [] := partition_partition partHG partHGg. Qed. + +Variable X : {set gT}. +Hypothesis trX : is_transversal X (HG :* <[g]>) G. + +Let sXG : {subset X <= G}. Proof. exact/subsetP/(transversal_sub trX). Qed. + +Lemma rcosets_cycle_transversal : H_g_rcosets @: X = HGg. +Proof. +have sHXgHGg x: x \in X -> H_g_rcosets x \in HGg. + by move/sXG=> Gx; apply: mem_imset; rewrite -rcosetE mem_imset. +apply/setP=> Hxg; apply/imsetP/idP=> [[x /sHXgHGg HGgHxg -> //] | HGgHxg]. +have [_ /rcosetsP[z Gz ->] ->] := imsetP HGgHxg. +pose Hzg := H :* z * <[g]>; pose x := transversal_repr 1 X Hzg. +have HGgHzg: Hzg \in HG :* <[g]>. + by rewrite mem_mulg ?set11 // -rcosetE mem_imset. +have Hzg_x: x \in Hzg by rewrite (repr_mem_pblock trX). +exists x; first by rewrite (repr_mem_transversal trX). +case/mulsgP: Hzg_x => y u /rcoset_transl <- /(orbit_act 'Rs) <- -> /=. +by rewrite rcosetE -rcosetM. +Qed. + +Local Notation defHgX := rcosets_cycle_transversal. + +Let injHg: {in X &, injective H_g_rcosets}. +Proof. +apply/imset_injP; rewrite defHgX (card_transversal trX) defHGg. +by rewrite (card_in_imset injHGg). +Qed. + +Lemma sum_index_rcosets_cycle : (\sum_(x in X) n_ x)%N = #|G : H|. +Proof. by rewrite [#|G : H|](card_partition partHGg) -defHgX big_imset. Qed. + +Lemma transfer_cycle_expansion : + transfer g = \sum_(x in X) fmalpha ((g ^+ n_ x) ^ x^-1). +Proof. +pose Y := \bigcup_(x in X) [set x * g ^+ i | i : 'I_(n_ x)]. +pose rY := transversal_repr 1 Y. +pose pcyc x := pcycle (actperm 'Rs g) (H :* x). +pose traj x := traject (actperm 'Rs g) (H :* x) #|pcyc x|. +have Hgr_eq x: H_g_rcosets x = pcyc x. + by rewrite /H_g_rcosets -orbitRs -pcycle_actperm ?inE. +have pcyc_eq x: pcyc x =i traj x by exact: pcycle_traject. +have uniq_traj x: uniq (traj x) by apply: uniq_traject_pcycle. +have n_eq x: n_ x = #|pcyc x| by rewrite -Hgr_eq. +have size_traj x: size (traj x) = n_ x by rewrite n_eq size_traject. +have nth_traj x j: j < n_ x -> nth (H :* x) (traj x) j = H :* (x * g ^+ j). + move=> lt_j_x; rewrite nth_traject -?n_eq //. + by rewrite -permX -morphX ?inE // actpermE //= rcosetE rcosetM. +have sYG: Y \subset G. + apply/bigcupsP=> x Xx; apply/subsetP=> _ /imsetP[i _ ->]. + by rewrite groupM ?groupX // sXG. +have trY: is_transversal Y HG G. + apply/and3P; split=> //; apply/forall_inP=> Hy. + have /and3P[/eqP <- _ _] := partHGg; rewrite -defHgX cover_imset. + case/bigcupP=> x Xx; rewrite Hgr_eq pcyc_eq => /trajectP[i]. + rewrite -n_eq -permX -morphX ?in_setT // actpermE /= rcosetE -rcosetM => lti. + set y := x * _ => ->{Hy}; pose oi := Ordinal lti. + have Yy: y \in Y by apply/bigcupP; exists x => //; apply/imsetP; exists oi. + apply/cards1P; exists y; apply/esym/eqP. + rewrite eqEsubset sub1set inE Yy rcoset_refl. + apply/subsetP=> _ /setIP[/bigcupP[x' Xx' /imsetP[j _ ->]] Hy_x'gj]. + have eq_xx': x = x'. + apply: (pblock_inj trX) => //; have /andP[/and3P[_ tiX _] _] := trX. + have HGgHyg: H :* y * <[g]> \in HG :* <[g]>. + by rewrite mem_mulg ?set11 // -rcosetE mem_imset ?(subsetP sYG). + rewrite !(def_pblock tiX HGgHyg) //. + by rewrite -[x'](mulgK (g ^+ j)) mem_mulg // groupV mem_cycle. + by rewrite -[x](mulgK (g ^+ i)) mem_mulg ?rcoset_refl // groupV mem_cycle. + apply/set1P; rewrite /y eq_xx'; congr (_ * _ ^+ _) => //; apply/eqP. + rewrite -(@nth_uniq _ (H :* x) (traj x)) ?size_traj // ?eq_xx' //. + by rewrite !nth_traj ?(rcoset_transl Hy_x'gj) // -eq_xx'. +have rYE x i : x \in X -> i < n_ x -> rY (H :* x :* g ^+ i) = x * g ^+ i. + move=> Xx lt_i_x; rewrite -rcosetM; apply: (canLR_in (pblockK trY 1)). + by apply/bigcupP; exists x => //; apply/imsetP; exists (Ordinal lt_i_x). + apply/esym/def_pblock; last exact: rcoset_refl; first by case/and3P: partHG. + by rewrite -rcosetE mem_imset ?groupM ?groupX // sXG. +rewrite (transfer_indep trY Gg) /V -/rY (set_partition_big _ partHGg) /=. +rewrite -defHgX big_imset /=; last first. + apply/imset_injP; rewrite defHgX (card_transversal trX) defHGg. + by rewrite (card_in_imset injHGg). +apply eq_bigr=> x Xx; rewrite Hgr_eq (eq_bigl _ _ (pcyc_eq x)) -big_uniq //=. +have n_gt0: 0 < n_ x by rewrite indexg_gt0. +rewrite /traj -n_eq; case def_n: (n_ x) (n_gt0) => // [n] _. +rewrite conjgE invgK -{1}[H :* x]rcoset1 -{1}(expg0 g). +elim: {1 3}n 0%N (addn0 n) => [|m IHm] i def_i /=. + rewrite big_seq1 {i}[i]def_i rYE // ?def_n //. + rewrite -(mulgA _ _ g) -rcosetM -expgSr -[(H :* x) :* _]rcosetE. + rewrite -actpermE morphX ?inE // permX // -{2}def_n n_eq iter_pcycle mulgA. + by rewrite -[H :* x]rcoset1 (rYE _ 0%N) ?mulg1. +rewrite big_cons rYE //; last by rewrite def_n -def_i ltnS leq_addl. +rewrite permE /= rcosetE -rcosetM -(mulgA _ _ g) -expgSr. +rewrite addSnnS in def_i; rewrite IHm //. +rewrite rYE //; last by rewrite def_n -def_i ltnS leq_addl. +by rewrite mulgV [fmalpha 1]morph1 add0r. +Qed. + +End FactorTransfer. + +End Transfer. |
