aboutsummaryrefslogtreecommitdiff
path: root/mathcomp/odd_order/PFsection9.v
diff options
context:
space:
mode:
Diffstat (limited to 'mathcomp/odd_order/PFsection9.v')
-rw-r--r--mathcomp/odd_order/PFsection9.v2205
1 files changed, 2205 insertions, 0 deletions
diff --git a/mathcomp/odd_order/PFsection9.v b/mathcomp/odd_order/PFsection9.v
new file mode 100644
index 0000000..361d5fe
--- /dev/null
+++ b/mathcomp/odd_order/PFsection9.v
@@ -0,0 +1,2205 @@
+(* (c) Copyright Microsoft Corporation and Inria. All rights reserved. *)
+Require Import ssreflect ssrbool ssrfun eqtype ssrnat seq path div choice.
+Require Import fintype tuple finfun bigop prime binomial ssralg poly finset.
+Require Import fingroup morphism perm automorphism quotient action finalg zmodp.
+Require Import gfunctor gproduct cyclic commutator center gseries nilpotent.
+Require Import pgroup sylow hall abelian maximal frobenius.
+Require Import matrix mxalgebra mxrepresentation mxabelem vector.
+Require Import BGsection1 BGsection3 BGsection7 BGsection15 BGsection16.
+Require Import algC classfun character inertia vcharacter.
+Require Import PFsection1 PFsection2 PFsection3 PFsection4.
+Require Import PFsection5 PFsection6 PFsection8.
+
+(******************************************************************************)
+(* This file covers Peterfalvi, Section 9: On the maximal subgroups of Types *)
+(* II, III and IV. For defW : W1 \x W2 = W, MtypeP : of_typeP M U defW, and *)
+(* H := M`_\F we define : *)
+(* Ptype_Fcore_kernel MtypeP == a maximal normal subgroup of M contained *)
+(* (locally) H0 in H and containing 'C_H(U), provided M is *)
+(* not a maximal subgroup of type V. *)
+(* Ptype_Fcore_kernel MtypeP == the stabiliser of Hbar := H / H0 in U; this *)
+(* (locally to this file) C is locked for performance reasons. *)
+(* typeP_Galois MtypeP <=> U acts irreducibly on Hbar; this implies *)
+(* that M / H0C is isomorphic to a Galois group *)
+(* acting on the semidirect product of the *)
+(* additive group of a finite field with a *)
+(* a subgroup of its multiplicative group. *)
+(* --> This predicate reflects alternative (b) in Peterfalvi (9.7). *)
+(******************************************************************************)
+
+Set Implicit Arguments.
+Unset Strict Implicit.
+Unset Printing Implicit Defensive.
+
+Import GroupScope GRing.Theory FinRing.Theory.
+
+Section Nine.
+
+Variable gT : minSimpleOddGroupType.
+Local Notation G := (TheMinSimpleOddGroup gT).
+Implicit Types (p q : nat) (x y z : gT).
+Implicit Types H K L N P Q R S T U V W : {group gT}.
+
+(* Peterfalvi (9.1) is covered by BGsection3.Frobenius_Wielandt_fixpoint. *)
+
+(* These assumptions correspond to Peterfalvi, Hypothesis (9.2). *)
+
+Variables M U W W1 W2 : {group gT}.
+Hypotheses (maxM : M \in 'M) (defW : W1 \x W2 = W) (MtypeP: of_typeP M U defW).
+Hypothesis notMtype5 : FTtype M != 5.
+
+Local Notation "` 'M'" := (gval M) (at level 0, only parsing) : group_scope.
+Local Notation "` 'U'" := (gval U) (at level 0, only parsing) : group_scope.
+Local Notation "` 'W1'" := (gval W1) (at level 0, only parsing) : group_scope.
+Local Notation H := `M`_\F%G.
+Local Notation "` 'H'" := `M`_\F (at level 0) : group_scope.
+Local Notation "` 'W2'" := (gval W2) (at level 0, only parsing) : group_scope.
+Local Notation HU := M^`(1)%G.
+Local Notation "` 'HU'" := `M^`(1) (at level 0) : group_scope.
+Local Notation U' := U^`(1)%G.
+Local Notation "` 'U''" := `U^`(1) (at level 0) : group_scope.
+
+Let q := #|W1|.
+
+Let defM : HU ><| W1 = M. Proof. by have [[]] := MtypeP. Qed.
+Let defHU : H ><| U = HU. Proof. by have [_ []] := MtypeP. Qed.
+Let nUW1 : W1 \subset 'N(U). Proof. by have [_ []] := MtypeP. Qed.
+Let cHU' : U' \subset 'C(H). Proof. by have [_ []] := typeP_context MtypeP. Qed.
+
+Let notMtype1 : FTtype M != 1%N. Proof. exact: FTtypeP_neq1 MtypeP. Qed.
+
+Local Notation Mtype24 := (compl_of_typeII_IV maxM MtypeP notMtype5).
+Let ntU : U :!=: 1. Proof. by have [] := Mtype24. Qed.
+Let pr_q : prime q. Proof. by have [] := Mtype24. Qed.
+Let ntW2 : W2 :!=: 1. Proof. by have [_ _ _ []] := MtypeP. Qed.
+Let sW2H : W2 \subset H. Proof. by have [_ _ _ []] := MtypeP. Qed.
+Let defW2 : 'C_H(W1) = W2. Proof. exact: typeP_cent_core_compl MtypeP. Qed.
+
+Lemma Ptype_Fcore_sdprod : H ><| (U <*> W1) = M.
+Proof.
+have [_ /= sW1M mulHUW1 _ tiHUW1] := sdprod_context defM.
+have [/= /andP[sHHU _] sUHU mulHU nHU tiHU] := sdprod_context defHU.
+rewrite sdprodE /= norm_joinEr // ?mulgA ?mulHU //.
+ by rewrite mulG_subG nHU (subset_trans sW1M) ?gFnorm.
+rewrite setIC -(setIidPr sHHU) setIA -group_modl //.
+by rewrite (setIC W1) tiHUW1 mulg1 setIC tiHU.
+Qed.
+Local Notation defHUW1 := Ptype_Fcore_sdprod.
+
+Lemma Ptype_Fcore_coprime : coprime #|H| #|U <*> W1|.
+Proof.
+by rewrite (coprime_sdprod_Hall_l defHUW1) ?(pHall_Hall (Fcore_Hall M)).
+Qed.
+Let coH_UW1 := Ptype_Fcore_coprime.
+Let coHU : coprime #|H| #|U|.
+Proof. exact: coprimegS (joing_subl U W1) coH_UW1. Qed.
+
+Let not_cHU : ~~ (U \subset 'C(H)).
+Proof. by have [_ [_ ->]] := typeP_context MtypeP. Qed.
+
+Lemma Ptype_compl_Frobenius : [Frobenius U <*> W1 = U ><| W1].
+Proof.
+have [[_ _ ntW1 _] _ _ [_ _ _ _ prHU_W1] _] := MtypeP.
+have [[_ _ _ tiHUW1] [_ sUHU _ _ tiHU]] := (sdprodP defM, sdprod_context defHU).
+apply/Frobenius_semiregularP=> // [|x /prHU_W1 defCx].
+ by rewrite sdprodEY //; apply/trivgP; rewrite -tiHUW1 setSI.
+by apply/trivgP; rewrite -tiHU /= -{1}(setIidPr sUHU) setIAC defCx setSI.
+Qed.
+Local Notation frobUW1 := Ptype_compl_Frobenius.
+
+Let nilH : nilpotent H. Proof. exact: Fcore_nil. Qed.
+Let solH : solvable H. Proof. exact: nilpotent_sol. Qed.
+
+(* This is Peterfalvi (9.3). *)
+Lemma typeII_IV_core (p := #|W2|) :
+ if FTtype M == 2 then 'C_H(U) = 1 /\ #|H| = (#|W2| ^ q)%N
+ else [/\ prime p, 'C_H(U <*> W1) = 1 & #|H| = (p ^ q * #|'C_H(U)|)%N].
+Proof.
+have [_ _ nHUW1 _] := sdprodP defHUW1.
+have /= [oH _ oH1] := Frobenius_Wielandt_fixpoint frobUW1 nHUW1 coH_UW1 solH.
+have [Mtype2 {oH}| notMtype2 {oH1}] := boolP (FTtype M == 2).
+ suffices regHU: 'C_H(U) = 1 by rewrite -defW2 oH1.
+ have [_ _ _ HUtypeF defHUF] := compl_of_typeII maxM MtypeP Mtype2.
+ have [_ _ [U0 [sU0U _]]] := HUtypeF; rewrite {}defHUF => frobHU0.
+ have /set0Pn[x U0x]: U0^# != set0.
+ by rewrite setD_eq0 subG1; case/Frobenius_context: frobHU0.
+ apply/trivgP; rewrite -(Frobenius_reg_ker frobHU0 U0x) setIS // -cent_cycle.
+ by rewrite centS // cycle_subG (subsetP sU0U) //; case/setD1P: U0x.
+have p_pr: prime p.
+ have [S pairMS [xdefW [U_S StypeP]]] := FTtypeP_pair_witness maxM MtypeP.
+ have [[_ _ maxS] _] := pairMS; rewrite {1}(negPf notMtype2) /= => Stype2 _ _.
+ by have [[]] := compl_of_typeII maxS StypeP Stype2.
+rewrite -/q -/p centY setICA defW2 setIC in oH *.
+suffices regW2U: 'C_W2(U) = 1 by rewrite -oH regW2U cards1 exp1n mul1n.
+apply: prime_TIg => //=; apply: contra not_cHU => /setIidPl cUW2.
+rewrite centsC (sameP setIidPl eqP) eqEcard subsetIl.
+by rewrite -(@leq_pmul2l (p ^ q)) -?oH ?cUW2 //= expn_gt0 cardG_gt0.
+Qed.
+
+(* Existential witnesses for Peterfalvi (9.4). *)
+Definition Ptype_Fcore_kernel of of_typeP M U defW :=
+ odflt 1%G [pick H0 : {group gT} | chief_factor M H0 H & 'C_H(U) \subset H0].
+Let H0 := (Ptype_Fcore_kernel MtypeP).
+Local Notation "` 'H0'" := (gval H0) (at level 0, only parsing) : group_scope.
+Local Notation Hbar := (H / `H0)%G.
+Local Notation "` 'Hbar'" := (`H / `H0)%g (at level 0) : group_scope.
+Let p := pdiv #|Hbar|.
+
+(* This corresponds to Peterfalvi (9.4). *)
+Lemma Ptype_Fcore_kernel_exists : chief_factor M H0 H /\ 'C_H(U) \subset H0.
+Proof.
+pose S := <<class_support 'C_H(U) H>> .
+suffices [H1 maxH sCH1]: {H1 : {group gT} | maxnormal H1 H M & S \subset H1}.
+ apply/andP; rewrite /H0 /Ptype_Fcore_kernel; case: pickP => // /(_ H1)/idP[].
+ rewrite /chief_factor maxH Fcore_normal (subset_trans _ sCH1) ?sub_gen //.
+ exact: sub_class_support.
+apply/maxgroup_exists/andP; split.
+ have snCH: 'C_H(U) <|<| H by rewrite nilpotent_subnormal ?subsetIl.
+ by have [/setIidPl/idPn[] | // ] := subnormalEsupport snCH; rewrite centsC.
+have [_ {3}<- nHUW1 _] := (sdprodP defHUW1).
+rewrite norms_gen // mulG_subG class_support_norm norms_class_support //.
+by rewrite normsI ?norms_cent // join_subG normG.
+Qed.
+
+Let chiefH0 : chief_factor M H0 H.
+Proof. by have [] := Ptype_Fcore_kernel_exists. Qed.
+Let ltH0H : H0 \proper H.
+Proof. by case/andP: chiefH0 => /maxgroupp/andP[]. Qed.
+Let nH0M : M \subset 'N(H0).
+Proof. by case/andP: chiefH0 => /maxgroupp/andP[]. Qed.
+Let sH0H : H0 \subset H. Proof. exact: proper_sub ltH0H. Qed.
+Let nsH0M : H0 <| M. Proof. by rewrite /normal (subset_trans sH0H) ?gFsub. Qed.
+Let nsH0H : H0 <| H. Proof. by rewrite (normalS _ (Fcore_sub _)). Qed.
+Let minHbar : minnormal Hbar (M / H0).
+Proof. exact: chief_factor_minnormal. Qed.
+Let ntHbar : Hbar :!=: 1. Proof. by case/mingroupp/andP: minHbar. Qed.
+Let solHbar: solvable Hbar. Proof. by rewrite quotient_sol. Qed.
+Let abelHbar : p.-abelem Hbar.
+Proof. by have [] := minnormal_solvable minHbar _ solHbar. Qed.
+Let p_pr : prime p. Proof. by have [/pgroup_pdiv[]] := and3P abelHbar. Qed.
+Let abHbar : abelian Hbar. Proof. exact: abelem_abelian abelHbar. Qed.
+
+(* This is Peterfalvi, Hypothesis (9.5). *)
+Fact Ptype_Fcompl_kernel_key : unit. Proof. by []. Qed.
+Definition Ptype_Fcompl_kernel :=
+ locked_with Ptype_Fcompl_kernel_key 'C_U(Hbar | 'Q)%G.
+Local Notation C := Ptype_Fcompl_kernel.
+Local Notation "` 'C'" := (gval C) (at level 0, only parsing) : group_scope.
+Local Notation Ubar := (U / `C)%G.
+Local Notation "` 'Ubar'" := (`U / `C)%g (at level 0) : group_scope.
+Local Notation W1bar := (W1 / `H0)%G.
+Local Notation "` 'W1bar'" := (`W1 / `H0)%g (at level 0) : group_scope.
+Local Notation W2bar := 'C_Hbar(`W1bar)%G.
+Local Notation "` 'W2bar'" := 'C_`Hbar(`W1bar) (at level 0) : group_scope.
+Let c := #|C|.
+Let u := #|Ubar|.
+Local Notation tau := (FT_Dade0 maxM).
+Local Notation "chi ^\tau" := (tau chi).
+Let calX := Iirr_kerD M^`(1) H 1.
+Let calS := seqIndD M^`(1) M M`_\F 1.
+Let X_ Y := Iirr_kerD M^`(1) H Y.
+Let S_ Y := seqIndD M^`(1) M M`_\F Y.
+
+Local Notation inMb := (coset (gval H0)).
+
+Local Notation H0C := (`H0 <*> `C)%G.
+Local Notation "` 'H0C'" := (`H0 <*> `C) (at level 0) : group_scope.
+Local Notation HC := (`H <*> `C)%G.
+Local Notation "` 'HC'" := (`H <*> `C) (at level 0) : group_scope.
+Local Notation H0U' := (`H0 <*> `U')%G.
+Local Notation "` 'H0U''" := (gval H0 <*> `U')%G (at level 0) : group_scope.
+Local Notation H0C' := (`H0 <*> `C^`(1)%g)%G.
+Local Notation "` 'H0C''" := (`H0 <*> `C^`(1)) (at level 0) : group_scope.
+
+Let defW2bar : W2bar :=: W2 / H0.
+Proof.
+rewrite -defW2 coprime_quotient_cent ?(subset_trans _ nH0M) //.
+ by have [_ /mulG_sub[]] := sdprodP defM.
+exact: coprimegS (joing_subr _ _) coH_UW1.
+Qed.
+
+Let sCU : C \subset U. Proof. by rewrite [C]unlock subsetIl. Qed.
+
+Let nsCUW1 : C <| U <*> W1.
+Proof.
+have [_ sUW1M _ nHUW1 _] := sdprod_context defHUW1.
+rewrite /normal [C]unlock subIset ?joing_subl // normsI //.
+ by rewrite join_subG normG.
+rewrite /= astabQ norm_quotient_pre ?norms_cent ?quotient_norms //.
+exact: subset_trans sUW1M nH0M.
+Qed.
+
+Lemma Ptype_Fcore_extensions_normal :
+ [/\ H0C <| M, HC <| M, H0U' <| M & H0C' <| M].
+Proof.
+have [nsHUM sW1M /mulG_sub[sHUM _] nHUW1 tiHUW1] := sdprod_context defM.
+have [nsHHU sUHU /mulG_sub[sHHU _] nHU tiHU] := sdprod_context defHU.
+have [sHM sUM] := (subset_trans sHHU sHUM, subset_trans sUHU sHUM).
+have sCM: C \subset M := subset_trans sCU sUM.
+have sH0C_M: H0C \subset M by rewrite /normal join_subG (subset_trans sH0H).
+have [nH0C nH0_H0C] := (subset_trans sCM nH0M, subset_trans sH0C_M nH0M).
+have nsH0C: H0C <| M.
+ rewrite /normal sH0C_M -{1}defM sdprodEY //= -defHU sdprodEY //= -joingA.
+ rewrite join_subG andbC normsY ?(normal_norm nsCUW1) //=; last first.
+ by rewrite (subset_trans _ nH0M) // join_subG sUM.
+ rewrite -quotientYK // -{1}(quotientGK nsH0H) morphpre_norms //= [C]unlock.
+ by rewrite cents_norm // centsC -quotient_astabQ quotientS ?subsetIr.
+split=> //; first by rewrite /= -{1}(joing_idPl sH0H) -joingA normalY ?gFnormal.
+ rewrite normalY // /normal (subset_trans (der_sub 1 U)) //=.
+ rewrite -{1}defM sdprodEY //= -defHU sdprodEY //=.
+ rewrite !join_subG gFnorm cents_norm 1?centsC //=.
+ by rewrite (char_norm_trans (der_char _ _)).
+suffices ->: H0C' :=: H0 <*> H0C^`(1).
+ by rewrite normalY ?(char_normal_trans (der_char _ _)).
+rewrite /= -?quotientYK ?(subset_trans (der_sub _ _)) ?subsetIl //=.
+by rewrite !quotient_der ?cosetpreK ?subsetIl.
+Qed.
+Local Notation nsH0xx_M := Ptype_Fcore_extensions_normal.
+
+Let Du : u = #|HU : HC|.
+Proof.
+have nCU := subset_trans (joing_subl U W1) (normal_norm nsCUW1).
+by rewrite -(index_sdprodr defHU) -?card_quotient.
+Qed.
+
+(* This is Peterfalvi (9.6). *)
+Lemma Ptype_Fcore_factor_facts :
+ [/\ C :!=: U, #|W2bar| = p & #|Hbar| = p ^ q]%N.
+Proof.
+have [defUW1 _ ntW1 _ _] := Frobenius_context Ptype_compl_Frobenius.
+have coHW1: coprime #|H| #|W1| := coprimegS (joing_subr U W1) coH_UW1.
+have [_ sUW1M _ nHUW1 _] := sdprod_context defHUW1.
+have nH0UW1 := subset_trans sUW1M nH0M; have [nH0U nH0W1] := joing_subP nH0UW1.
+have regUHb: 'C_Hbar(U / H0) = 1.
+ have [_ sCH0] := Ptype_Fcore_kernel_exists.
+ by rewrite -coprime_quotient_cent ?(nilpotent_sol nilH) ?quotientS1.
+have ->: C != U.
+ apply: contraNneq ntHbar => defU; rewrite -subG1 -regUHb subsetIidl centsC.
+ by rewrite -defU [C]unlock -quotient_astabQ quotientS ?subsetIr.
+have frobUW1b: [Frobenius U <*> W1 / H0 = (U / H0) ><| W1bar].
+ have tiH0UW1 := coprime_TIg (coprimeSg sH0H coH_UW1).
+ have /isomP[inj_f im_f] := quotient_isom nH0UW1 tiH0UW1.
+ have:= injm_Frobenius (subxx _) inj_f frobUW1.
+ by rewrite im_f !morphim_restrm !(setIidPr _) ?joing_subl ?joing_subr.
+have{frobUW1b} oHbar: #|Hbar| = (#|W2bar| ^ q)%N.
+ have nHbUW1 : U <*> W1 / H0 \subset 'N(Hbar) := quotient_norms H0 nHUW1.
+ have coHbUW1 : coprime #|Hbar| #|U <*> W1 / H0| by apply: coprime_morph.
+ have [//|_ _ -> //] := Frobenius_Wielandt_fixpoint frobUW1b nHbUW1 coHbUW1 _.
+ by rewrite -(card_isog (quotient_isog _ _)) // coprime_TIg ?(coprimeSg sH0H).
+have abelW2bar: p.-abelem W2bar := abelemS (subsetIl _ _) abelHbar.
+rewrite -(part_pnat_id (abelem_pgroup abelW2bar)) p_part in oHbar *.
+suffices /eqP cycW2bar: logn p #|W2bar| == 1%N by rewrite oHbar cycW2bar.
+have cycW2: cyclic W2 by have [_ _ _ []] := MtypeP.
+rewrite eqn_leq -abelem_cyclic //= -/W2bar {1}defW2bar quotient_cyclic //=.
+rewrite lt0n; apply: contraNneq ntHbar => W2bar1.
+by rewrite trivg_card1 oHbar W2bar1 exp1n.
+Qed.
+
+Lemma def_Ptype_factor_prime : prime #|W2| -> p = #|W2|.
+Proof.
+move=> prW2; suffices: p \in \pi(W2) by rewrite !(primes_prime, inE) // => /eqP.
+rewrite mem_primes p_pr cardG_gt0; have [_ <- _] := Ptype_Fcore_factor_facts.
+by rewrite defW2bar dvdn_quotient.
+Qed.
+
+(* The first assertion of (9.4)(b) (the rest is subsumed by (9.6)). *)
+Lemma typeIII_IV_core_prime : FTtype M != 2 -> p = #|W2|.
+Proof.
+by have:= typeII_IV_core => /=; case: ifP => // _ [/def_Ptype_factor_prime].
+Qed.
+
+Let frobUW1c : [Frobenius U <*> W1 / C = Ubar ><| W1 / C].
+Proof.
+apply: Frobenius_quotient frobUW1 _ nsCUW1 _.
+ by apply: nilpotent_sol; have [_ []] := MtypeP.
+by have [] := Ptype_Fcore_factor_facts; rewrite eqEsubset sCU.
+Qed.
+
+Definition typeP_Galois := acts_irreducibly U Hbar 'Q.
+
+(* This is Peterfalvi (9.7)(a). *)
+Lemma typeP_Galois_Pn :
+ ~~ typeP_Galois ->
+ {H1 : {group coset_of H0} |
+ [/\ #|H1| = p, U / H0 \subset 'N(H1), [acts U, on H1 | 'Q],
+ \big[dprod/1]_(w in W1bar) H1 :^ w = Hbar
+ & let a := #|U : 'C_U(H1 | 'Q)| in
+ [/\ a > 1, a %| p.-1, cyclic (U / 'C_U(H1 | 'Q))
+ & exists V : {group 'rV['Z_a]_q.-1}, Ubar \isog V]]}.
+Proof.
+have [_ sUW1M defHUW1 nHUW1 _] := sdprod_context defHUW1.
+have [nHU nHW1] := joing_subP nHUW1.
+have nH0UW1 := subset_trans sUW1M nH0M; have [nH0U nH0W1] := joing_subP nH0UW1.
+rewrite /typeP_Galois acts_irrQ //= => not_minHbarU.
+have [H1 minH1 sH1Hb]: {H1 | minnormal (gval H1) (U / H0) & H1 \subset Hbar}.
+ by apply: mingroup_exists; rewrite ntHbar quotient_norms.
+exists H1; have [defH1 | ltH1H] := eqVproper sH1Hb.
+ by rewrite -defH1 minH1 in not_minHbarU.
+have [/andP[ntH1 nH1U] _] := mingroupP minH1.
+have actsUH1: [acts U, on H1 | 'Q].
+ by rewrite -(cosetpreK H1) actsQ ?norm_quotient_pre.
+have [nH0H [neqCU _ oHbar]] := (normal_norm nsH0H, Ptype_Fcore_factor_facts).
+have nUW1b: W1bar \subset 'N(U / H0) by apply: quotient_norms.
+have oW1b: #|W1bar| = q.
+ rewrite -(card_isog (quotient_isog _ _)) // coprime_TIg //.
+ by rewrite (coprimeSg sH0H) // (coprimegS (joing_subr U W1)).
+have [oH1 defHbar]: #|H1| = p /\ \big[dprod/1]_(w in W1bar) H1 :^ w = Hbar.
+ have nHbUW1: U <*> W1 / H0 \subset 'N(Hbar) by apply: quotient_norms.
+ pose rUW1 := abelem_repr abelHbar ntHbar nHbUW1.
+ have irrUW1: mx_irreducible rUW1.
+ apply/abelem_mx_irrP/mingroupP; split=> [|H2]; first by rewrite ntHbar.
+ case/andP=> ntH2 nH2UW1 sH2H; case/mingroupP: minHbar => _; apply=> //.
+ by rewrite ntH2 -defHUW1 quotientMl // mulG_subG sub_abelian_norm.
+ have nsUUW1: U / H0 <| U <*> W1 / H0 by rewrite quotient_normal // normalYl.
+ pose rU := subg_repr rUW1 (normal_sub nsUUW1).
+ pose V1 := rowg_mx (abelem_rV abelHbar ntHbar @* H1).
+ have simV1: mxsimple rU V1 by apply/mxsimple_abelem_subg/mxsimple_abelemGP.
+ have [W0 /subsetP sW01 [sumW0 dxW0]] := Clifford_basis irrUW1 simV1.
+ have def_q: q = (#|W0| * \rank V1)%N.
+ transitivity (\rank (\sum_(w in W0) V1 *m rUW1 w))%R.
+ by rewrite sumW0 mxrank1 /= (dim_abelemE abelHbar) // oHbar pfactorK.
+ rewrite (mxdirectP dxW0) -sum_nat_const; apply: eq_bigr => x /sW01/= Wx.
+ by rewrite mxrankMfree ?row_free_unit ?repr_mx_unit.
+ have oH1: #|H1| = (p ^ \rank V1)%N.
+ by rewrite -{1}(card_Fp p_pr) -card_rowg rowg_mxK card_injm ?abelem_rV_injm.
+ have oW0: #|W0| = q.
+ apply/prime_nt_dvdP=> //; last by rewrite def_q dvdn_mulr.
+ apply: contraTneq (proper_card ltH1H) => trivW0.
+ by rewrite oHbar def_q trivW0 mul1n -oH1 ltnn.
+ have q_gt0 := prime_gt0 pr_q.
+ rewrite oH1 -(mulKn (\rank V1) q_gt0) -{1}oW0 -def_q divnn q_gt0.
+ have defHbar: \big[dprod/1]_(w in W0) H1 :^ w = Hbar.
+ have inj_rV_Hbar := rVabelem_injm abelHbar ntHbar.
+ have/(injm_bigdprod _ inj_rV_Hbar)/= := bigdprod_rowg sumW0 dxW0.
+ rewrite sub_im_abelem_rV rowg1 im_rVabelem => <- //=; apply: eq_bigr => w.
+ by move/sW01=> Ww; rewrite abelem_rowgJ ?rowg_mxK ?abelem_rV_mK.
+ have injW0: {in W0 &, injective (fun w => H1 :^ w)}.
+ move=> x y Wx Wy /= eq_Hxy; apply: contraNeq ntH1 => neq_xy.
+ rewrite -(conjsg_eq1 _ x) -[H1 :^ x]setIid {1}eq_Hxy; apply/eqP.
+ rewrite (bigD1 y) // (bigD1 x) /= ?Wx // dprodA in defHbar.
+ by case/dprodP: defHbar => [[_ _ /dprodP[_ _ _ ->] _]].
+ have defH1W0: [set H1 :^ w | w in W0] = [set H1 :^ w | w in W1 / H0].
+ apply/eqP; rewrite eqEcard (card_in_imset injW0) oW0 -oW1b leq_imset_card.
+ rewrite andbT; apply/subsetP=> _ /imsetP[w /sW01/= Ww ->].
+ move: Ww; rewrite norm_joinEr ?quotientMl // => /mulsgP[x w1 Ux Ww1 ->].
+ by rewrite conjsgM (normsP nH1U) // mem_imset.
+ have injW1: {in W1 / H0 &, injective (fun w => H1 :^ w)}.
+ by apply/imset_injP; rewrite -defH1W0 (card_in_imset injW0) oW0 oW1b.
+ by rewrite -(big_imset id injW1) -defH1W0 big_imset.
+split=> //; set a := #|_ : _|; pose q1 := #|(W1 / H0)^#|.
+have a_gt1: a > 1.
+ rewrite indexg_gt1 subsetIidl /= astabQ -sub_quotient_pre //.
+ apply: contra neqCU => cH1U; rewrite [C]unlock (sameP eqP setIidPl) /= astabQ.
+ rewrite -sub_quotient_pre // -(bigdprodWY defHbar) cent_gen centsC.
+ by apply/bigcupsP=> w Ww; rewrite centsC centJ -(normsP nUW1b w) ?conjSg.
+have Wb1: 1 \in W1bar := group1 _.
+have ->: q.-1 = q1 by rewrite -oW1b (cardsD1 1) Wb1.
+have /cyclicP[h defH1]: cyclic H1 by rewrite prime_cyclic ?oH1.
+have o_h: #[h] = p by rewrite defH1 in oH1.
+have inj_Zp_h w := injm_Zp_unitm (h ^ w).
+pose phi w := invm (inj_Zp_h w) \o restr_perm <[h ^ w]> \o actperm 'Q.
+have dU w: w \in W1bar -> {subset U <= 'dom (phi w)}.
+ move=> Ww x Ux; have Qx := subsetP (acts_dom actsUH1) x Ux.
+ rewrite inE Qx /= im_Zp_unitm inE mem_morphpre //=; last first.
+ by apply: Aut_restr_perm (actperm_Aut 'Q _); rewrite //= quotientT.
+ rewrite cycleJ -defH1 !inE /=; apply/subsetP=> z H1w_z; rewrite inE actpermK.
+ rewrite qactJ (subsetP nH0U) ?memJ_norm // normJ mem_conjg.
+ by rewrite (subsetP nH1U) // -mem_conjg (normsP nUW1b) ?mem_quotient.
+have sUD := introT subsetP (dU _ _).
+have Kphi w: 'ker (phi w) = 'C(H1 :^ w | 'Q).
+ rewrite !ker_comp ker_invm -kerE ker_restr_perm defH1 -cycleJ.
+ apply/setP=> x; rewrite !inE; congr (_ && _) => /=.
+ by apply: eq_subset_r => h1; rewrite !inE actpermK.
+have o_phiU w: w \in W1bar -> #|phi w @* U| = a.
+ move=> Ww; have [w1 Nw1 Ww1 def_w] := morphimP Ww.
+ rewrite card_morphim Kphi (setIidPr _) ?sUD // /a indexgI /= !astabQ.
+ by rewrite centJ def_w morphpreJ // -{1}(normsP nUW1 w1 Ww1) indexJg.
+have a_dv_p1: a %| p.-1.
+ rewrite -(o_phiU 1) // (dvdn_trans (cardSg (subsetT _))) // card_units_Zp //.
+ by rewrite conjg1 o_h (@totient_pfactor p 1) ?muln1.
+have cycZhw w: cyclic (units_Zp #[h ^ w]).
+ rewrite -(injm_cyclic (inj_Zp_h w)) // im_Zp_unitm Aut_prime_cyclic //=.
+ by rewrite -orderE orderJ o_h.
+have cyc_phi1U: cyclic (phi 1 @* U) := cyclicS (subsetT _) (cycZhw 1).
+split=> //; last have{cyc_phi1U a_dv_p1} [z def_z] := cyclicP cyc_phi1U.
+ by rewrite -(conjsg1 H1) -Kphi (isog_cyclic (first_isog_loc _ _)) ?sUD.
+have o_hw w: #[h ^ w] = #[h ^ 1] by rewrite !orderJ.
+pose phi1 w x := eq_rect _ (fun m => {unit 'Z_m}) (phi w x) _ (o_hw w).
+have val_phi1 w x: val (phi1 w x) = val (phi w x) :> nat.
+ by rewrite /phi1; case: _ / (o_hw _).
+have mem_phi1 w x: w \in W1bar -> x \in U -> phi1 w x \in <[z]>%G.
+ move=> Ww Ux; have: #|<[z]>%G| = a by rewrite /= -def_z o_phiU.
+ rewrite /phi1; case: _ / (o_hw w) <[z]>%G => A oA /=.
+ suffices <-: phi w @* U = A by rewrite mem_morphim // dU.
+ by apply/eqP; rewrite (eq_subG_cyclic (cycZhw w)) ?subsetT // oA o_phiU.
+have o_z: #[z] = a by rewrite orderE -def_z o_phiU.
+pose phi0 w x := ecast m 'Z_m o_z (invm (injm_Zpm z) (phi1 w x)).
+pose psi x := (\row_(i < q1) (phi0 (enum_val i) x * (phi0 1 x)^-1)%g)%R.
+have psiM: {in U &, {morph psi: x y / x * y}}.
+ have phi0M w: w \in W1bar -> {in U &, {morph phi0 w: x y / x * y}}.
+ move=> Ww x y Ux Uy; rewrite /phi0; case: (a) / (o_z) => /=.
+ rewrite -morphM; first 1 [congr (invm _ _)] || by rewrite im_Zpm mem_phi1.
+ by rewrite /phi1; case: _ / (o_hw w); rewrite /= -morphM ?dU.
+ move=> x y Ux Uy; apply/rowP=> i; have /setD1P[_ Ww] := enum_valP i.
+ by rewrite !{1}mxE !{1}phi0M // addrCA -addrA -opprD addrCA addrA.
+suffices Kpsi: 'ker (Morphism psiM) = C.
+ by exists [group of Morphism psiM @* U]; rewrite /Ubar -Kpsi first_isog.
+apply/esym/eqP; rewrite eqEsubset; apply/andP; split.
+ rewrite [C]unlock -(bigdprodWY defHbar); apply/subsetP=> x /setIP[Ux cHx].
+ suffices phi0x1 w: w \in W1bar -> phi0 w x = 1.
+ rewrite !inE Ux; apply/eqP/rowP=> i; have /setD1P[_ Ww] := enum_valP i.
+ by rewrite !mxE !phi0x1 ?mulgV.
+ move=> Ww; apply: val_inj; rewrite /phi0; case: (a) / (o_z); congr (val _).
+ suffices /eqP->: phi1 w x == 1 by rewrite morph1.
+ rewrite -2!val_eqE [val _]val_phi1 -(o_hw w) [phi _ _]mker // Kphi.
+ by apply: subsetP (astabS _ _) _ cHx; rewrite sub_gen // (bigcup_sup w).
+have sKU: 'ker (Morphism psiM) \subset U by apply: subsetIl.
+rewrite -quotient_sub1 -?(Frobenius_trivg_cent frobUW1c); last first.
+ by apply: subset_trans (normal_norm nsCUW1); rewrite subIset ?joing_subl.
+rewrite subsetI quotientS //= quotient_cents2r // [C]unlock subsetI.
+rewrite (subset_trans (commSg W1 sKU)) ?commg_subl //= astabQ gen_subG /=.
+apply/subsetP=> _ /imset2P[x w1 Kx Ww1 ->].
+have:= Kx; rewrite -groupV 2!inE groupV => /andP[Ux /set1P/rowP psi_x'0].
+have [nH0x Ux'] := (subsetP nH0U x Ux, groupVr Ux); pose x'b := (inMb x)^-1.
+rewrite mem_morphpre ?groupR ?morphR //= ?(subsetP nH0W1) //.
+have conj_x'b w: w \in W1bar -> (h ^ w) ^ x'b = (h ^ w) ^+ val (phi 1 x^-1).
+ move=> Ww; transitivity (Zp_unitm (phi w x^-1) (h ^ w)).
+ have /morphpreP[_ /morphpreP[Px' Rx']] := dU w Ww x^-1 Ux'.
+ rewrite invmK ?restr_permE ?cycle_id //.
+ by rewrite actpermE qactJ groupV nH0x morphV.
+ have:= Ww; rewrite -(setD1K Wb1) autE ?cycle_id // => /setU1P[-> // | W'w].
+ have /eqP := psi_x'0 (enum_rank_in W'w w); rewrite 2!mxE enum_rankK_in //.
+ rewrite -eq_mulgV1 -val_eqE /phi0; case: (a) / (o_z); rewrite /= val_eqE.
+ rewrite (inj_in_eq (injmP (injm_invm _))) /= ?im_Zpm ?mem_phi1 //.
+ by rewrite -2!val_eqE /= !val_phi1 // => /eqP->.
+rewrite -sub_cent1 -(bigdprodWY defHbar) gen_subG; apply/bigcupsP=> w2 Ww2.
+rewrite defH1 -cycleJ cycle_subG cent1C inE conjg_set1 !conjgM // conj_x'b //.
+rewrite conjXg -!conjgM -conj_x'b ?groupM ?groupV ?mem_quotient //.
+by rewrite !conjgM !conjgKV.
+Qed.
+
+(* This is Peterfalvi (9.7)(b). *)
+(* Note that part of this statement feeds directly into the final chapter of *)
+(* the proof (PFsection14 and BGappendixC) and is not used before; we have *)
+(* thus chosen to formulate the statement of (9.7)(b) accordingly. *)
+(* For example, we supply separately the three component of the semi-direct *)
+(* product isomorphism, because no use is made of the global isomorphism. We *)
+(* also state explicitly that the image of W2bar is Fp because this is the *)
+(* fact used in B & G, Appendix C, it is readily available during the proof, *)
+(* whereas it can only be derived from the original statement of (9.7)(b) by *)
+(* using Galois theory. Indeed the Galois part of the isomorphism is only *)
+(* needed for this -- so with the formulation below it will not be used. *)
+(* In order to avoid the use of the Wedderburn theorem on finite division *)
+(* rings we build the field F from the enveloping algebra of the *)
+(* representation of U rather than its endomorphism ring: then the fact that *)
+(* Ubar is abelian yields commutativity directly. *)
+Lemma typeP_Galois_P :
+ typeP_Galois ->
+ {F : finFieldType & {phi : {morphism Hbar >-> F}
+ & {psi : {morphism U >-> {unit F}} & {eta : {morphism W1 >-> {perm F}}
+ & forall alpha : {perm F}, reflect (rmorphism alpha) (alpha \in eta @* W1)
+ & [/\ 'injm eta, {in Hbar & W1, morph_act 'Q 'P phi eta}
+ & {in U & W1, forall x w, val (psi (x ^ w)) = eta w (val (psi x))}]}
+ & 'ker psi = C /\ {in Hbar & U, morph_act 'Q 'U phi psi}}
+ & [/\ #|F| = (p ^ q)%N, isom Hbar [set: F] phi & phi @* W2bar = <[1%R : F]>]}
+ & [/\ cyclic Ubar, coprime u p.-1 & u %| (p ^ q).-1 %/ p.-1]}.
+Proof.
+move=> irrU; have [_ sUW1M _ /joing_subP[nHU nHW1] _] := sdprod_context defHUW1.
+have [nHbU nHbW1] := (quotient_norms H0 nHU, quotient_norms H0 nHW1).
+have{sUW1M} /joing_subP[nH0U nH0W1] := subset_trans sUW1M nH0M.
+have [ltCU oW2b oHb] := Ptype_Fcore_factor_facts.
+pose rU := abelem_repr abelHbar ntHbar nHbU.
+pose inHb := rVabelem abelHbar ntHbar; pose outHb := abelem_rV abelHbar ntHbar.
+have{irrU} irrU: mx_irreducible rU by apply/abelem_mx_irrP; rewrite -acts_irrQ.
+pose E_U := [pred A | (A \in enveloping_algebra_mx rU)%MS].
+have cEE A: A \in E_U -> centgmx rU A.
+ case/envelop_mxP=> z_ ->{A}; rewrite -memmx_cent_envelop linear_sum.
+ rewrite summx_sub // => x Ux; rewrite linearZ scalemx_sub {z_}//=.
+ rewrite memmx_cent_envelop; apply/centgmxP=> y Uy.
+ rewrite -repr_mxM // commgC 2?repr_mxM ?(groupR, groupM) // -/rU.
+ apply/row_matrixP=> i; rewrite row_mul; move: (row i _) => h.
+ have cHbH': (U / H0)^`(1) \subset 'C(Hbar).
+ by rewrite -quotient_der ?quotient_cents.
+ apply: rVabelem_inj; rewrite rVabelemJ ?groupR //.
+ by apply: (canLR (mulKg _)); rewrite -(centsP cHbH') ?mem_commg ?mem_rVabelem.
+have{cEE} [F [outF [inF outFK inFK] E_F]]:
+ {F : finFieldType & {outF : {rmorphism F -> 'M(Hbar)%Mg}
+ & {inF : {additive _} | cancel outF inF & {in E_U, cancel inF outF}}
+ & forall a, outF a \in E_U}}%R.
+- pose B := row_base (enveloping_algebra_mx rU).
+ have freeB: row_free B by apply: row_base_free.
+ pose outF := [additive of vec_mx \o mulmxr B].
+ pose inF := [additive of mulmxr (pinvmx B) \o mxvec].
+ have E_F a: outF a \in E_U by rewrite !inE vec_mxK mulmx_sub ?eq_row_base.
+ have inK: {in E_U, cancel inF outF}.
+ by move=> A E_A; rewrite /= mulmxKpV ?mxvecK ?eq_row_base.
+ have outI: injective outF := inj_comp (can_inj vec_mxK) (row_free_inj freeB).
+ have outK: cancel outF inF by move=> a; apply: outI; rewrite inK ?E_F.
+ pose one := inF 1%R; pose mul a b := inF (outF a * outF b)%R.
+ have outM: {morph outF: a b / mul a b >-> a * b}%R.
+ by move=> a b; rewrite inK //; apply: envelop_mxM; exact: E_F.
+ have out0: outF 0%R = 0%R by apply: raddf0.
+ have out1: outF one = 1%R by rewrite inK //; exact: envelop_mx1.
+ have nzFone: one != 0%R by rewrite -(inj_eq outI) out1 out0 oner_eq0.
+ have mulA: associative mul by move=> *; apply: outI; rewrite !{1}outM mulrA.
+ have mulC: commutative mul.
+ move=> a b; apply: outI; rewrite !{1}outM.
+ by apply: cent_mxP (E_F a); rewrite memmx_cent_envelop cEE ?E_F.
+ have mul1F: left_id one mul by move=> a; apply: outI; rewrite outM out1 mul1r.
+ have mulD: left_distributive mul +%R%R.
+ by move=> a1 a2 b; apply: canLR outK _; rewrite !raddfD mulrDl -!{1}outM.
+ pose Fring_NC := RingType 'rV__ (ComRingMixin mulA mulC mul1F mulD nzFone).
+ pose Fring := ComRingType Fring_NC mulC.
+ have outRM: multiplicative (outF : Fring -> _) by [].
+ have mulI (nza : {a | a != 0%R :> Fring}): GRing.rreg (val nza).
+ case: nza => a /=; rewrite -(inj_eq outI) out0 => nzA b1 b2 /(congr1 outF).
+ rewrite !{1}outM => /row_free_inj eqB12; apply/outI/eqB12.
+ by rewrite row_free_unit (mx_Schur irrU) ?cEE ?E_F.
+ pose inv (a : Fring) := oapp (fun nza => invF (mulI nza) one) a (insub a).
+ have inv0: (inv 0 = 0)%R by rewrite /inv insubF ?eqxx.
+ have mulV: GRing.Field.axiom inv.
+ by move=> a nz_a; rewrite /inv insubT /= (f_invF (mulI (exist _ _ _))).
+ pose Funit := FieldUnitMixin mulV inv0.
+ pose FringUcl := @GRing.ComUnitRing.Class _ (GRing.ComRing.class Fring) Funit.
+ have Ffield := @FieldMixin (GRing.ComUnitRing.Pack FringUcl nat) _ mulV inv0.
+ pose F := FieldType (IdomainType _ (FieldIdomainMixin Ffield)) Ffield.
+ by exists [finFieldType of F], (AddRMorphism outRM); first exists inF.
+pose in_uF (a : F) : {unit F} := insubd (1 : {unit F}) a.
+have in_uF_E a: a != 1 -> val (in_uF a) = a.
+ by move=> nt_a; rewrite insubdK /= ?unitfE.
+have [psi psiK]: {psi : {morphism U >-> {unit F}}
+ | {in U, forall x, outF (val (psi x)) = rU (inMb x)}}.
+- pose psi x := in_uF (inF (rU (inMb x))).
+ have psiK x: x \in U -> outF (val (psi x)) = rU (inMb x).
+ move/(mem_quotient H0)=> Ux; have EUx := envelop_mx_id rU Ux.
+ rewrite in_uF_E ?inFK //; apply: contraTneq (repr_mx_unitr rU Ux).
+ by move/(canRL_in inFK EUx)->; rewrite rmorph0 unitr0.
+ suffices psiM: {in U &, {morph psi: x y / x * y}} by exists (Morphism psiM).
+ move=> x y Ux Uy /=; apply/val_inj/(can_inj outFK); rewrite rmorphM //.
+ by rewrite !{1}psiK ?groupM // morphM ?(subsetP nH0U) ?repr_mxM ?mem_quotient.
+have /trivgPn/sig2W[s W2s nts]: W2bar != 1%G.
+ by rewrite -cardG_gt1 oW2b prime_gt1.
+pose sb := outHb s; have [Hs cW1s] := setIP W2s.
+have nz_sb: sb != 0%R by rewrite morph_injm_eq1 ?abelem_rV_injm.
+pose phi' a : coset_of H0 := inHb (sb *m outF a)%R.
+have Hphi' a: phi' a \in Hbar by apply: mem_rVabelem.
+have phi'D: {in setT &, {morph phi' : a b / a * b}}.
+ by move=> a b _ _; rewrite /phi' !raddfD [inHb _]morphM ?mem_im_abelem_rV.
+have inj_phi': injective phi'.
+ move=> a b /rVabelem_inj eq_sab; apply: contraNeq nz_sb.
+ rewrite -[sb]mulmx1 idmxE -(rmorph1 outF) -subr_eq0 => /divff <-.
+ by rewrite rmorphM mulmxA !raddfB /= eq_sab subrr mul0mx.
+have injm_phi': 'injm (Morphism phi'D) by apply/injmP; exact: in2W.
+have Dphi: 'dom (invm injm_phi') = Hbar.
+ apply/setP=> h; apply/morphimP/idP=> [[a _ _ ->] // | Hh].
+ have /cyclic_mxP[A E_A def_h]: (outHb h <= cyclic_mx rU sb)%MS.
+ by rewrite -(mxsimple_cyclic irrU) ?submx1.
+ by exists (inF A); rewrite ?inE //= /phi' inFK // -def_h [inHb _]abelem_rV_K.
+have [phi [def_phi Kphi _ im_phi]] := domP _ Dphi.
+have{Kphi} inj_phi: 'injm phi by rewrite Kphi injm_invm.
+have{im_phi} im_phi: phi @* Hbar = setT by rewrite im_phi -Dphi im_invm.
+have phiK: {in Hbar, cancel phi phi'} by rewrite def_phi -Dphi; exact: invmK.
+have{def_phi Dphi injm_phi'} phi'K: cancel phi' phi.
+ by move=> a; rewrite def_phi /= invmE ?inE.
+have phi'1: phi' 1%R = s by rewrite /phi' rmorph1 mulmx1 [inHb _]abelem_rV_K.
+have phi_s: phi s = 1%R by rewrite -phi'1 phi'K.
+have phiJ: {in Hbar & U, forall h x, phi (h ^ inMb x) = phi h * val (psi x)}%R.
+ move=> h x Hh Ux; have Uxb := mem_quotient H0 Ux.
+ apply: inj_phi'; rewrite phiK ?memJ_norm ?(subsetP nHbU) // /phi' rmorphM.
+ by rewrite psiK // mulmxA [inHb _]rVabelemJ // -/inHb [inHb _]phiK.
+have Kpsi: 'ker psi = C.
+ apply/setP=> x; rewrite [C]unlock 2!in_setI /= astabQ; apply: andb_id2l => Ux.
+ have Ubx := mem_quotient H0 Ux; rewrite 3!inE (subsetP nH0U) //= inE.
+ apply/eqP/centP=> [psi_x1 h Hh | cHx]; last first.
+ by apply/val_inj; rewrite -[val _]mul1r -phi_s -phiJ // conjgE -cHx ?mulKg.
+ red; rewrite (conjgC h) -[h ^ _]phiK ?memJ_norm ?(subsetP nHbU) ?phiJ //.
+ by rewrite psi_x1 mulr1 phiK.
+have etaP (w : subg_of W1): injective (fun a => phi (phi' a ^ inMb (val w))).
+ case: w => w /=/(mem_quotient H0)/(subsetP nHbW1) => nHw a b eq_ab.
+ apply/inj_phi'/(conjg_inj (inMb w)).
+ by apply: (injmP inj_phi) eq_ab; rewrite memJ_norm ?mem_rVabelem.
+pose eta w : {perm F} := perm (etaP (subg W1 w)).
+have etaK: {in Hbar & W1, forall h w, eta w (phi h) = phi (h ^ inMb w)}.
+ by move=> h w Hh Ww; rewrite /= permE subgK ?phiK.
+have eta1 w: w \in W1 -> eta w 1%R = 1%R.
+ move=> Ww; rewrite -phi_s etaK //.
+ by rewrite conjgE (centP cW1s) ?mulKg ?mem_quotient.
+have etaM: {in W1 &, {morph eta: w1 w2 / w1 * w2}}.
+ move=> w1 w2 Ww1 Ww2; apply/permP=> a; rewrite -[a]phi'K permM.
+ rewrite !etaK ?memJ_norm ?groupM ?(subsetP nHbW1) ?mem_quotient //.
+ by rewrite -conjgM -morphM ?(subsetP nH0W1).
+have etaMpsi a: {in U & W1, forall x w,
+ eta w (a * val (psi x)) = eta w a * val (psi (x ^ w)%g)}%R.
+- move=> x w Ux Ww; rewrite -[a]phi'K (etaK _ w (Hphi' a) Ww).
+ rewrite -!phiJ // ?memJ_norm ?(subsetP nHbW1, subsetP nUW1) ?mem_quotient //.
+ rewrite etaK ?memJ_norm ?(subsetP nHbU) ?mem_quotient // -!conjgM.
+ by rewrite conjgC -morphJ ?(subsetP nH0U x Ux, subsetP nH0W1 w Ww).
+have psiJ: {in U & W1, forall x w, val (psi (x ^ w)) = eta w (val (psi x))}.
+ by move=> x w Ux Ww /=; rewrite -[val _]mul1r -(eta1 w Ww) -etaMpsi ?mul1r.
+have etaRM w: w \in W1 -> rmorphism (eta w).
+ move=> Ww; have nUw := subsetP nHbW1 _ (mem_quotient _ Ww).
+ have etaD: additive (eta w).
+ move=> a b; rewrite -[a]phi'K -[b]phi'K -!zmodMgE -!zmodVgE.
+ rewrite -morphV // -morphM ?{1}etaK ?groupM ?groupV // conjMg conjVg.
+ by rewrite morphM 1?morphV ?groupV // memJ_norm.
+ do 2![split=> //] => [a b|]; last exact: eta1.
+ rewrite -[a]outFK; have /envelop_mxP[d ->] := E_F a.
+ rewrite raddf_sum mulr_suml ![eta w _](raddf_sum (Additive etaD)) mulr_suml.
+ apply: eq_bigr => _ /morphimP[x Nx Ux ->]; move: {d}(d _) => dx.
+ rewrite -[dx]natr_Zp scaler_nat !(mulrnAl, raddfMn); congr (_ *+ dx)%R.
+ by rewrite -psiK //= outFK mulrC etaMpsi // mulrC psiJ.
+have oF: #|F| = (p ^ q)%N by rewrite -cardsT -im_phi card_injm.
+pose nF := <[1%R : F]>; have o_nF: #|nF| = p.
+ by rewrite -orderE -phi_s (order_injm inj_phi) // (abelem_order_p abelHbar).
+have cyc_uF := @field_unit_group_cyclic F.
+exists F.
+ exists phi; last first.
+ split=> //; first exact/isomP; apply/esym/eqP; rewrite eqEcard o_nF -phi_s.
+ by rewrite (@cycle_subG F) mem_morphim //= card_injm ?subsetIl ?oW2b.
+ exists psi => //; last first.
+ by split=> // h x Hh Ux; rewrite qactJ (subsetP nH0U) ?phiJ.
+ have inj_eta: 'injm (Morphism etaM).
+ have /properP[_ [h Hh notW2h]]: W2bar \proper Hbar.
+ by rewrite properEcard subsetIl oW2b oHb (ltn_exp2l 1) prime_gt1.
+ apply/subsetP=> w /morphpreP[Ww /set1P/permP/(_ (phi h))].
+ rewrite etaK // permE => /(injmP inj_phi) => chw.
+ rewrite -(@prime_TIg _ W1 <[w]>) //; first by rewrite inE Ww cycle_id.
+ rewrite proper_subn // properEneq cycle_subG Ww andbT.
+ apply: contraNneq notW2h => defW1; rewrite inE Hh /= -defW1.
+ rewrite quotient_cycle ?(subsetP nH0W1) // cent_cycle cent1C inE.
+ by rewrite conjg_set1 chw ?memJ_norm // (subsetP nHbW1) ?mem_quotient.
+ exists (Morphism etaM) => [alpha |]; last first.
+ by split=> // h w Hh Ww /=; rewrite qactJ (subsetP nH0W1) -?etaK.
+ pose autF (f : {perm F}) := rmorphism f. (* Bits of Galois theory... *)
+ have [r prim_r]: {r : F | forall f g, autF f -> autF g -> f r = g r -> f = g}.
+ have /cyclicP/sig_eqW[r def_uF] := cyc_uF [set: {unit F}]%G.
+ exists (val r) => f g fRM gRM eq_fgr; apply/permP=> a.
+ rewrite (_ : f =1 RMorphism fRM) // (_ : g =1 RMorphism gRM) //.
+ have [-> | /in_uF_E <-] := eqVneq a 0%R; first by rewrite !rmorph0.
+ have /cycleP[m ->]: in_uF a \in <[r]> by rewrite -def_uF inE.
+ by rewrite val_unitX !rmorphX /= eq_fgr.
+ have /sigW[P /and3P[Pr0 nP lePq]]:
+ exists P: {poly F}, [&& root P r, all (mem nF) P & #|root P| <= q].
+ - pose Mr := (\matrix_(i < q.+1) (sb *m outF (r ^+ i)))%R.
+ have /rowV0Pn[v /sub_kermxP vMr0 nz_v]: kermx Mr != 0%R.
+ rewrite kermx_eq0 neq_ltn ltnS (leq_trans (rank_leq_col Mr)) //.
+ by rewrite (dim_abelemE abelHbar) // oHb pfactorK.
+ pose P : {poly F} := (\poly_(i < q.+1) (v 0 (inord i))%:R)%R.
+ have szP: size P <= q.+1 by apply: size_poly.
+ exists P; apply/and3P; split.
+ + apply/eqP/inj_phi'; congr (inHb _); rewrite rmorph0 mulmx0 -vMr0.
+ rewrite horner_poly !raddf_sum mulmx_sum_row; apply: eq_bigr => i _.
+ rewrite rowK inord_val //= mulr_natl rmorphMn -scaler_nat scalemxAr.
+ by rewrite natr_Zp.
+ + apply/(all_nthP 0%R)=> i /leq_trans/(_ szP) le_i_q.
+ by rewrite coef_poly /= le_i_q mem_cycle.
+ rewrite cardE -ltnS (leq_trans _ szP) //.
+ rewrite max_poly_roots ?enum_uniq //; last first.
+ by apply/allP=> r'; rewrite mem_enum.
+ apply: contraNneq nz_v => /polyP P0; apply/eqP/rowP=> i; apply/eqP.
+ have /eqP := P0 i; rewrite mxE coef0 coef_poly ltn_ord inord_val.
+ have charF: p \in [char F]%R by rewrite !inE p_pr -order_dvdn -o_nF /=.
+ by rewrite -(dvdn_charf charF) (dvdn_charf (char_Fp p_pr)) natr_Zp.
+ have{Pr0 nP} fPr0 f: autF f -> root P (f r).
+ move=> fRM; suff <-: map_poly (RMorphism fRM) P = P by apply: rmorph_root.
+ apply/polyP=> i; rewrite coef_map.
+ have [/(nth_default _)-> | lt_i_P] := leqP (size P) i; first exact: rmorph0.
+ by have /cycleP[n ->] := all_nthP 0%R nP i lt_i_P; exact: rmorph_nat.
+ apply: (iffP morphimP) => [[w _ Ww ->] | alphaRM]; first exact: etaRM.
+ suffices /setP/(_ (alpha r)): [set (eta w) r | w in W1] = [set t | root P t].
+ rewrite inE fPr0 // => /imsetP[w Ww def_wr]; exists w => //.
+ by apply: prim_r => //; exact: etaRM.
+ apply/eqP; rewrite eqEcard; apply/andP; split.
+ by apply/subsetP=> _ /imsetP[w Ww ->]; rewrite inE fPr0 //; exact: etaRM.
+ rewrite (@cardsE F) card_in_imset // => w1 w2 Ww1 Ww2 /= /prim_r eq_w12.
+ by apply: (injmP inj_eta) => //; apply: eq_w12; exact: etaRM.
+have isoUb: isog Ubar (psi @* U) by rewrite /Ubar -Kpsi first_isog.
+pose unF := [set in_uF a | a in nF^#].
+have unF_E: {in nF^#, cancel in_uF val} by move=> a /setD1P[/in_uF_E].
+have unFg: group_set unF.
+ apply/group_setP; split=> [|_ _ /imsetP[a nFa ->] /imsetP[b nFb ->]].
+ have nF1: 1%R \in nF^# by rewrite !inE cycle_id oner_eq0.
+ by apply/imsetP; exists 1%R => //; apply: val_inj; rewrite unF_E.
+ have nFab: (a * b)%R \in nF^#.
+ rewrite !inE mulf_eq0 negb_or.
+ have [[-> /cycleP[m ->]] [-> /cycleP[n ->]]] := (setD1P nFa, setD1P nFb).
+ by rewrite -natrM mem_cycle.
+ by apply/imsetP; exists (a * b)%R => //; apply: val_inj; rewrite /= !unF_E.
+have <-: #|Group unFg| = p.-1.
+ by rewrite -o_nF (cardsD1 1 nF) group1 (card_in_imset (can_in_inj unF_E)).
+have <-: #|[set: {unit F}]| = (p ^ q).-1.
+ rewrite -oF -(cardC1 1) cardsT card_sub; apply: eq_card => a /=.
+ by rewrite !inE unitfE.
+rewrite /u (isog_cyclic isoUb) (card_isog isoUb) cyc_uF.
+suffices co_u_p1: coprime #|psi @* U| #|Group unFg|.
+ by rewrite -(Gauss_dvdr _ co_u_p1) mulnC divnK ?cardSg ?subsetT.
+rewrite -(cyclic_dprod (dprodEY _ _)) ?cyc_uF //.
+ by rewrite (sub_abelian_cent2 (cyclic_abelian (cyc_uF [set:_]%G))) ?subsetT.
+apply/trivgP/subsetP=> _ /setIP[/morphimP[x Nx Ux ->] /imsetP[a nFa /eqP]].
+have nCx: x \in 'N(C) by rewrite -Kpsi (subsetP (ker_norm _)).
+rewrite -val_eqE (unF_E a) //; case/setD1P: nFa => _ /cycleP[n {a}->].
+rewrite zmodXgE => /eqP def_psi_x; rewrite mker ?set11 // Kpsi coset_idr //.
+apply/set1P; rewrite -set1gE -(Frobenius_trivg_cent frobUW1c) /= -/C.
+rewrite inE mem_quotient //= -sub1set -quotient_set1 ?quotient_cents2r //.
+rewrite gen_subG /= -/C -Kpsi; apply/subsetP=> _ /imset2P[_ w /set1P-> Ww ->].
+have Uxw: x ^ w \in U by rewrite memJ_norm ?(subsetP nUW1).
+apply/kerP; rewrite (morphM, groupM) ?morphV ?groupV //.
+apply/(canLR (mulKg _))/val_inj; rewrite psiJ // mulg1 def_psi_x.
+exact: (rmorph_nat (RMorphism (etaRM w Ww))).
+Qed.
+
+Local Open Scope ring_scope.
+
+Let redM := [predC irr M].
+Let mu_ := filter redM (S_ H0).
+
+(* This subproof is shared between (9.8)(b) and (9.9)(b). *)
+Let nb_redM_H0 : size mu_ = p.-1 /\ {subset mu_ <= S_ H0C}.
+Proof.
+have pddM := FT_prDade_hypF maxM MtypeP; pose ptiWM := prDade_prTI pddM.
+have [nsHUM sW1M /mulG_sub[sHUM _] nHUW1 tiHUW1] := sdprod_context defM.
+have [nsHHU sUHU /mulG_sub[sHHU _] nHU tiHU] := sdprod_context defHU.
+have nb_redM K:
+ K <| M -> K \subset HU -> K :&: H = H0 -> count redM (S_ K) = p.-1.
+- move=> nsKM sKHU tiKHbar; have [sKM nKM] := andP nsKM; pose b L := (L / K)%G.
+ have [nsKHU [_ [_ sW2HU cycW2 _] _]] := (normalS sKHU sHUM nsKM, ptiWM).
+ have nKW2 := subset_trans sW2HU (normal_norm nsKHU).
+ have oW2b: #|b W2| = p.
+ have [_ <- _] := Ptype_Fcore_factor_facts; rewrite defW2bar.
+ rewrite !card_quotient ?(subset_trans (subset_trans sW2HU sHUM)) //.
+ by rewrite -indexgI -{2}(setIidPl sW2H) setIAC -setIA tiKHbar indexgI.
+ have{cycW2} cycW2b: cyclic (b W2) by apply: quotient_cyclic.
+ have ntW2b: (W2 / K != 1)%g by rewrite -cardG_gt1 oW2b prime_gt1.
+ have{ntW2b} [defWb ptiWMb]:= primeTIhyp_quotient ptiWM ntW2b sKHU nsKM.
+ pose muK j := (primeTIred ptiWMb j %% K)%CF.
+ apply/eqP; have <-: size (image muK (predC1 0)) = p.-1.
+ by rewrite size_map -cardE cardC1 card_Iirr_cyclic ?oW2b.
+ rewrite -size_filter -uniq_size_uniq ?filter_uniq ?seqInd_uniq // => [|phi].
+ by apply/dinjectiveP=> j1 j2 _ _ /(can_inj (cfModK nsKM))/prTIred_inj.
+ rewrite mem_filter; apply/imageP/andP=> [[j nz_j ->] | [red_phi]]; last first.
+ case/seqIndP=> s /setDP[kerK ker'H] Dphi; rewrite !inE in kerK ker'H.
+ pose s1 := quo_Iirr K s; have Ds: s = mod_Iirr s1 by rewrite quo_IirrK.
+ rewrite {phi}Dphi Ds mod_IirrE ?cfIndMod // in kerK ker'H red_phi *.
+ have [[j Ds1] | [/idPn[]]] := prTIres_irr_cases ptiWMb s1.
+ rewrite Ds1 cfInd_prTIres -/(muK j) in ker'H *; exists j => //.
+ by apply: contraNneq ker'H => ->; rewrite prTIres0 rmorph1 cfker_cfun1.
+ by apply: contra red_phi => /cfMod_irr/= ->.
+ have red_j: redM (muK j).
+ apply: contra (prTIred_not_irr ptiWMb j) => /(cfQuo_irr nsKM).
+ by rewrite cfker_mod ?cfModK // => ->.
+ have [s DmuKj]: exists s, muK j = 'Ind[M, HU] 'chi_s.
+ exists (mod_Iirr (primeTI_Ires ptiWMb j)).
+ by rewrite mod_IirrE // cfIndMod // cfInd_prTIres.
+ split=> //; apply/seqIndP; exists s; rewrite // !inE andbC.
+ rewrite -(@sub_cfker_Ind_irr _ M) ?gFnorm // -DmuKj cfker_mod //=.
+ have [[j1 Ds] | [/idPn]] := prTIres_irr_cases ptiWM s; last by rewrite -DmuKj.
+ rewrite Ds cfker_prTIres //; apply: contraNneq nz_j => j1_0.
+ apply/eqP/(prTIred_inj ptiWMb)/(can_inj (cfModK nsKM)); rewrite -{1}/(muK j).
+ by rewrite DmuKj Ds j1_0 -cfInd_prTIres !prTIres0 -cfIndMod ?rmorph1.
+have [sH0HU sH0M] := (subset_trans sH0H sHHU, subset_trans sH0H (gFsub _ _)).
+have sz_mu: size mu_ = p.-1.
+ by rewrite size_filter nb_redM ?(setIidPl sH0H) // /normal sH0M.
+have s_muC_mu: {subset filter redM (S_ H0C) <= mu_}.
+ move=> phi; rewrite /= !mem_filter => /andP[->]; apply: seqIndS.
+ by rewrite setSD // Iirr_kerS ?joing_subl.
+have UmuC: uniq (filter redM (S_ H0C)) by rewrite filter_uniq ?seqInd_uniq.
+have [|Dmu _] := leq_size_perm UmuC s_muC_mu; last first.
+ by split=> // phi; rewrite -Dmu mem_filter => /andP[].
+have [nsH0C_M _ _ _] := nsH0xx_M.
+have sCHU := subset_trans sCU sUHU; have sCM := subset_trans sCHU sHUM.
+have sHOC_HU: H0C \subset HU by apply/joing_subP.
+rewrite sz_mu size_filter nb_redM //= norm_joinEr ?(subset_trans sCM) //.
+by rewrite -group_modl //= setIC [C]unlock setIA tiHU setI1g mulg1.
+Qed.
+
+Let isIndHC (zeta : 'CF(M)) :=
+ [/\ zeta 1%g = (q * u)%:R, zeta \in S_ H0C
+ & exists2 xi : 'CF(HC), xi \is a linear_char & zeta = 'Ind xi].
+
+(* This is Peterfalvi (9.8). *)
+Lemma typeP_nonGalois_characters (not_Galois : ~~ typeP_Galois) :
+ let a := #|U : 'C_U(sval (typeP_Galois_Pn not_Galois) | 'Q)| in
+ [/\ (*a*) {in X_ H0, forall s, (a %| 'chi_s 1%g)%C},
+ (*b*) size mu_ = p.-1 /\ {in mu_, forall mu_j, isIndHC mu_j},
+ (*c*) exists t, isIndHC 'chi_t
+ & (*d*) let irr_qa := [pred zeta in irr M | zeta 1%g == (q * a)%:R] in
+ let lb_n := (p.-1 * #|U|)%N in let lb_d := (a ^ 2 * #|U'|)%N in
+ (lb_d %| lb_n /\ lb_n %/ lb_d <= count irr_qa (S_ H0U'))%N].
+Proof.
+case: (typeP_Galois_Pn _) => H1 [oH1 nH1U nH1Uq defHbar aP]; rewrite [sval _]/=.
+move => a; case: aP; rewrite -/a => a_gt1 a_dv_p1 cycUb1 isoUb.
+set part_a := ({in _, _}); pose HCbar := (HC / H0)%G.
+have [_ /mulG_sub[sHUM sW1M] nHUW1 tiHUW1] := sdprodP defM.
+have [nsHHU _ /mulG_sub[sHHU sUHU] nHU tiHU] := sdprod_context defHU.
+have [nH0H nHHU] := (normal_norm nsH0H, normal_norm nsHHU).
+have sHHC: H \subset HC by rewrite joing_subl.
+have [nH0HU sCHU] := (subset_trans sHUM nH0M, subset_trans sCU sUHU).
+have nsH0_HU: H0 <| HU by rewrite /normal (subset_trans sH0H).
+have nH0C := subset_trans sCHU nH0HU.
+have [nsH0C_M nsHC_M nsH0U'_M _] := nsH0xx_M; have [sHC_M _] := andP nsHC_M.
+have nsH0HC: H0 <| HC := normalS (subset_trans sH0H sHHC) sHC_M nsH0M.
+have defHCbar: Hbar \x (C / H0) = HCbar.
+ rewrite /= quotientY // [C]unlock /= astabQ quotient_setIpre.
+ by rewrite dprodEY ?subsetIr // setIA -quotientGI // tiHU quotient1 setI1g.
+have sHC_HU: HC \subset HU by rewrite join_subG sHHU.
+have nsHC_HU: HC <| HU := normalS sHC_HU sHUM nsHC_M.
+have defHb1 := defHbar; rewrite (big_setD1 1%g) ?group1 ?conjsg1 //= in defHb1.
+have [[_ H1c _ defH1c] _ _ _] := dprodP defHb1; rewrite defH1c in defHb1.
+have [nsH1H _] := dprod_normal2 defHb1; have [sH1H nH1H] := andP nsH1H.
+have nHW1: W1 \subset 'N(H) := subset_trans sW1M (gFnorm _ _).
+have nHbW1: W1bar \subset 'N(Hbar) by rewrite quotient_norms.
+have sH1wH w: w \in W1bar -> H1 :^ w \subset Hbar.
+ by move/(normsP nHbW1) <-; rewrite conjSg.
+have nsH1wHUb w: w \in W1bar -> H1 :^ w <| HU / H0.
+ move=> W1w; rewrite -(normsP (quotient_norms _ nHUW1) w W1w) normalJ.
+ rewrite /normal (subset_trans sH1H) ?quotientS //.
+ by rewrite -defHU sdprodE // quotientMl // mulG_subG nH1H.
+have nH1wHUb := normal_norm (nsH1wHUb _ _).
+have Part_a: part_a.
+ move=> s; rewrite !inE => /andP[kers'H kersH0].
+ have [t sHt] := constt_cfRes_irr H s; pose theta := ('chi_t / H0)%CF.
+ have{kers'H} t_neq0: t != 0.
+ by rewrite -subGcfker (sub_cfker_constt_Res_irr sHt).
+ have{kersH0} kertH0: H0 \subset cfker 'chi_t.
+ by rewrite (sub_cfker_constt_Res_irr sHt).
+ have Ltheta: theta \is a linear_char.
+ by rewrite /theta -quo_IirrE // (char_abelianP _ _).
+ have Dtheta : _ = theta := cfBigdprod_Res_lin defHbar Ltheta.
+ set T := 'I_HU['chi_t]; have sHT: H \subset T by rewrite sub_Inertia.
+ have sTHU: T \subset HU by rewrite Inertia_sub.
+ suffices{s sHt} a_dv_iTHU: a %| #|HU : T|.
+ have [_ defInd_t _ imInd_t _] := cfInd_sum_Inertia t nsHHU.
+ have /imsetP[r tTr ->]: s \in Ind_Iirr HU @: irr_constt ('Ind[T] 'chi_t).
+ by rewrite imInd_t constt_Ind_Res.
+ by rewrite defInd_t ?cfInd1 // dvdC_mulr ?dvdC_nat // Cint_Cnat ?Cnat_irr1.
+ have /exists_inP[w W1w nt_t_w]: [exists w in W1bar, 'Res[H1 :^ w] theta != 1].
+ rewrite -negb_forall_in; apply: contra t_neq0 => /forall_inP=> tH1w1.
+ rewrite -irr_eq1 -(cfQuoK nsH0H kertH0) -/theta -Dtheta.
+ rewrite [cfBigdprod _ _]big1 ?rmorph1 // => w /tH1w1/eqP->.
+ by rewrite /cfBigdprodi rmorph1.
+ have defT: H ><| (U :&: T) = T.
+ by rewrite (sdprod_modl defHU) // (setIidPr sTHU).
+ have /irrP[k Dk]: 'Res theta \in irr (H1 :^ w).
+ by rewrite lin_char_irr ?cfRes_lin_char.
+ rewrite -divgS // -(sdprod_card defHU) -(sdprod_card defT) divnMl // divgI.
+ rewrite -indexgI; have ->: a = #|U : 'C_U(H1 :^ w | 'Q)|.
+ have [w1 nH0w1 W1w1 ->] := morphimP W1w; rewrite astabQ centJ morphpreJ //.
+ by rewrite -astabQ indexgI -(normsP nUW1 _ W1w1) indexJg -indexgI.
+ rewrite indexgS ?setIS // sub_astabQ ?(subset_trans sTHU) //= -inertia_quo //.
+ apply: subset_trans (sub_inertia_Res _ (nH1wHUb w W1w)) _.
+ by rewrite Dk (inertia_irr_prime _ p_pr) ?subsetIr ?cardJg // -irr_eq1 -Dk.
+pose isoJ := conj_isom H1; pose cfJ w i := 'chi_(isom_Iirr (isoJ w) i).
+pose thetaH (f : {ffun _}) := cfBigdprod defHbar (fun w => cfJ w (f w)).
+pose theta f := cfDprodl defHCbar (thetaH f).
+have abH1: abelian H1 by rewrite cyclic_abelian ?prime_cyclic ?oH1.
+have linH1 i: 'chi[H1]_i \is a linear_char by apply/char_abelianP.
+have lin_thetaH f: thetaH f \is a linear_char.
+ by apply: cfBigdprod_lin_char => w _; rewrite /cfJ isom_IirrE cfIsom_lin_char.
+have nz_thetaH f: thetaH f 1%g != 0 by rewrite lin_char_neq0.
+have Dtheta f: {in W1bar & H1, forall w xb, theta f (xb ^ w) = 'chi_(f w) xb}.
+ move=> w xb W1w H1xb /=; have sHHCb := quotientS H0 sHHC.
+ transitivity ('Res[H1 :^ w] ('Res[Hbar] (theta f)) (xb ^ w)); last first.
+ by rewrite cfDprodlK cfBigdprodKabelian // isom_IirrE cfIsomE.
+ by rewrite cfResRes ?sH1wH // cfResE ?memJ_conjg ?(subset_trans (sH1wH w _)).
+have lin_theta f: theta f \is a linear_char by apply: cfDprodl_lin_char.
+pose Ftheta := pffun_on (0 : Iirr H1) W1bar (predC1 0).
+have inj_theta: {in Ftheta &, injective theta}.
+ move=> f1 f2 /pffun_onP[/supportP W1f1 _] /pffun_onP[/supportP W1f2 _] eq_f12.
+ apply/ffunP=> w.
+ have [W1w | W1'w] := boolP (w \in W1bar); last by rewrite W1f1 ?W1f2.
+ by apply/irr_inj/cfun_inP=> x H1x; rewrite -!Dtheta ?eq_f12.
+have irr_thetaH0 f: (theta f %% H0)%CF \in irr HC.
+ by rewrite cfMod_irr ?lin_char_irr.
+have def_Itheta f: f \in Ftheta -> 'I_HU[theta f %% H0]%CF = HC.
+ case/pffun_onP=> _ nz_fW1; apply/eqP; rewrite eqEsubset sub_Inertia //.
+ rewrite inertia_mod_pre //= -{1}(sdprodW defHU) -group_modl; last first.
+ rewrite (subset_trans sHHC) // -sub_quotient_pre ?normal_norm //.
+ by rewrite sub_Inertia ?quotientS.
+ rewrite -gen_subG genM_join genS ?setUS //= {2}[C]unlock setIS //= astabQ.
+ rewrite morphpreS // centsC -{1}(bigdprodWY defHbar) gen_subG.
+ apply/bigcupsP=> w W1w; rewrite centsC.
+ apply: subset_trans (sub_inertia_Res _ (quotient_norms _ nHHU)) _.
+ rewrite cfDprodlK inertia_bigdprod_irr // subIset // orbC (bigcap_min w) //.
+ rewrite (inertia_irr_prime _ p_pr) ?cardJg ?subsetIr // isom_Iirr_eq0.
+ by apply: nz_fW1; apply: image_f.
+have irrXtheta f: f \in Ftheta -> 'Ind (theta f %% H0)%CF \in irr HU.
+ move/def_Itheta; rewrite -(cfIirrE (irr_thetaH0 f)) => I_f_HC.
+ by rewrite inertia_Ind_irr ?I_f_HC //.
+pose Mtheta := [set cfIirr (theta f %% H0)%CF | f in Ftheta].
+pose Xtheta := [set cfIirr ('Ind[HU] 'chi_t) | t in Mtheta].
+have oXtheta: (u * #|Xtheta| = p.-1 ^ q)%N.
+ transitivity #|Ftheta|; last first.
+ rewrite card_pffun_on cardC1 card_Iirr_abelian // oH1.
+ rewrite -(card_isog (quotient_isog _ _)) ?oW1 ?(subset_trans sW1M) //.
+ by apply/trivgP; rewrite -tiHUW1 setSI ?(subset_trans sH0H).
+ rewrite Du -card_imset_Ind_irr ?card_in_imset //.
+ - move=> f1 f2 Df1 Df2 /(congr1 (tnth (irr HC))); rewrite !{1}cfIirrE //.
+ by move/(can_inj (cfModK nsH0HC)); apply: inj_theta.
+ - by move=> _ /imsetP[f Df ->]; rewrite cfIirrE ?irrXtheta.
+ move=> _ y /imsetP[f /familyP Ff ->] HUy; apply/imsetP.
+ pose yb := inMb y; have HUyb: yb \in (HU / H0)%g by apply: mem_quotient.
+ have nHb_y: inMb y \in 'N(Hbar) by rewrite (subsetP (quotient_norms _ nHHU)).
+ have nH1b_y := subsetP (nH1wHUb _ _) yb HUyb.
+ exists [ffun w => conjg_Iirr (f w) (inMb y ^ w^-1)].
+ apply/familyP=> w; rewrite ffunE.
+ by case: ifP (Ff w) => _; rewrite !inE conjg_Iirr_eq0.
+ apply: irr_inj; rewrite !(cfIirrE, conjg_IirrE) // (cfConjgMod _ nsHC_HU) //.
+ rewrite cfConjgDprodl //; first congr (cfDprodl _ _ %% H0)%CF; last first.
+ rewrite /= -quotientYidl // (subsetP _ _ HUyb) ?quotient_norms //.
+ by rewrite (subset_trans sHUM) ?normal_norm.
+ rewrite cfConjgBigdprod //; apply: eq_bigr => w W1w; congr (cfBigdprodi _ _).
+ rewrite ffunE /cfJ !isom_IirrE conjg_IirrE.
+ apply/cfun_inP=> _ /imsetP[x Hx ->]; rewrite cfIsomE // cfConjgE ?nH1b_y //.
+ rewrite -conjgM conjgCV conjVg conjgM cfIsomE //; last first.
+ by rewrite -mem_conjg (normP _) // -mem_conjg -normJ ?nH1b_y.
+ by rewrite cfConjgE // -mem_conjg -normJ ?nH1b_y.
+have sXthXH0C: Xtheta \subset X_ H0C.
+ apply/subsetP=> _ /imsetP[t Mt ->]; have{Mt} [f Ff Dt] := imsetP Mt.
+ rewrite !inE cfIirrE; last by rewrite Dt cfIirrE ?irrXtheta.
+ rewrite !sub_cfker_Ind_irr ?(subset_trans sHUM) ?normal_norm ?gFnormal //.
+ rewrite {t}Dt cfIirrE // join_subG andbCA {1}cfker_mod //.
+ rewrite !{1}sub_cfker_mod //= andbC {1}cfker_sdprod /=.
+ apply: contraL (familyP Ff 1%g) => kerHb; rewrite group1 negbK.
+ have:= sub_cfker_Res (subxx _) kerHb; rewrite cfDprodlK.
+ move/(subset_trans (sH1wH _ (group1 _)))/(sub_cfker_Res (subxx _)).
+ rewrite cfBigdprodKabelian // isom_IirrE cfker_isom morphim_conj /=.
+ by rewrite !conjsg1 subsetIidl subGcfker.
+pose mu_f (i : Iirr H1) := [ffun w => if w \in W1bar then i else 0].
+have Fmu_f (i : Iirr H1): i != 0 -> mu_f i \in Ftheta.
+ by move=> nz_i; apply/familyP=> w; rewrite ffunE; case: ifP; rewrite !inE.
+pose mk_mu i := 'Ind[HU] (theta (mu_f i) %% H0)%CF.
+have sW1_Imu i: W1 \subset 'I[theta (mu_f i) %% H0]%CF.
+ apply/subsetP=> w W1w; have Mw := subsetP sW1M w W1w.
+ have nHC_W1 := subset_trans sW1M (normal_norm nsHC_M).
+ rewrite inE (subsetP nHC_W1) ?(cfConjgMod _ nsHC_M) //; apply/eqP.
+ have W1wb: inMb w \in W1bar by rewrite mem_quotient.
+ rewrite cfConjgDprodl ?(subsetP _ _ W1wb) ?quotient_norms //; last first.
+ by rewrite (subset_trans (joing_subr U W1)) ?normal_norm.
+ congr (cfDprodl _ _ %% H0)%CF.
+ apply/cfun_inP=> _ /(mem_bigdprod defHbar)[x [H1x -> _]].
+ have Hx w1: w1 \in W1bar -> x w1 \in Hbar.
+ by move=> W1w1; rewrite (subsetP (sH1wH w1 _)) ?H1x.
+ rewrite !lin_char_prod ?cfConjg_lin_char //; apply/eq_bigr=> w1 W1w1.
+ rewrite cfConjgE ?(subsetP nHbW1) //.
+ have W1w1w: (w1 * (inMb w)^-1)%g \in W1bar by rewrite !in_group.
+ rewrite -(cfResE _ (sH1wH _ W1w1w)) -?mem_conjg -?conjsgM ?mulgKV ?H1x //.
+ rewrite -(cfResE _ (sH1wH _ W1w1)) ?H1x ?cfBigdprodKabelian //.
+ rewrite !ffunE W1w1 W1w1w -[x w1](conjgKV w1) -conjgM !isom_IirrE.
+ by rewrite !cfIsomE -?mem_conjg ?H1x.
+have inj_mu: {in predC1 0 &, injective (fun i => cfIirr (mk_mu i))}.
+ move=> i1 i2 nz_i1 nz_i2 /(congr1 (tnth (irr HU))).
+ rewrite !{1}cfIirrE ?irrXtheta ?Fmu_f // /mk_mu.
+ do 2![move/esym; rewrite -{1}(cfIirrE (irr_thetaH0 _))].
+ move/(cfclass_Ind_irrP _ _ nsHC_HU); rewrite !{1}cfIirrE //.
+ case/cfclassP=> _ /(mem_sdprod defHU)[x [y [Hx Uy -> _]]].
+ rewrite (cfConjgM _ nsHC_HU) ?(subsetP sHHU x) ?(subsetP sUHU) //.
+ rewrite {x Hx}(cfConjg_id _ (subsetP sHHC x Hx)) => Dth1.
+ suffices /setIP[_ /inertiaJ]: y \in 'I_HU[theta (mu_f i2) %% H0]%CF.
+ rewrite -Dth1 => /(can_inj (cfModK nsH0HC))/inj_theta/ffunP/(_ 1%g).
+ by rewrite !ffunE group1 => -> //; apply: Fmu_f.
+ rewrite def_Itheta ?Fmu_f //= (subsetP (joing_subr _ _)) //.
+ have nCy: y \in 'N(C).
+ by rewrite (subsetP (normal_norm nsCUW1)) ?mem_gen ?inE ?Uy.
+ have [_ _ /trivgPn[wb W1wb ntwb] _ _] := Frobenius_context frobUW1c.
+ have /morphimP[w nCw W1w Dw] := W1wb; have Mw := subsetP sW1M w W1w.
+ rewrite coset_idr //; apply/set1P; rewrite -set1gE; apply: wlog_neg => nty.
+ rewrite -((Frobenius_reg_ker frobUW1c) wb); last by rewrite !inE ntwb.
+ rewrite inE mem_quotient //=; apply/cent1P/commgP.
+ rewrite Dw -morphR //= coset_id //.
+ suffices: [~ y, w] \in U :&: HC.
+ rewrite /= norm_joinEr ?(subset_trans sCU) // -group_modr ?subsetIl //=.
+ by rewrite setIC tiHU mul1g.
+ have Uyw: [~ y, w] \in U; last rewrite inE Uyw.
+ by rewrite {1}commgEl groupMl ?groupV // memJ_norm ?(subsetP nUW1) // Uy.
+ rewrite -(def_Itheta _ (Fmu_f _ nz_i1)) 2!inE /= andbA -in_setI.
+ rewrite (setIidPl (normal_norm nsHC_HU)) (subsetP sUHU) //=.
+ rewrite Dth1 -(cfConjgM _ nsHC_HU) ?(subsetP sUHU) //.
+ have My: y \in M := subsetP (subset_trans sUHU sHUM) y Uy.
+ rewrite mulKVg (cfConjgM _ nsHC_M) ?in_group //.
+ have /inertiaJ-> := subsetP (sW1_Imu i2) _ (groupVr W1w).
+ rewrite (cfConjgM _ nsHC_M) // -Dth1.
+ by have /inertiaJ-> := subsetP (sW1_Imu i1) w W1w.
+pose Xmu := [set cfIirr (mk_mu i) | i in predC1 0].
+have def_IXmu: {in Xmu, forall s, 'I_M['chi_s] = M}.
+ move=> _ /imsetP[i nz_i ->]; apply/setIidPl.
+ rewrite -subsetIidl -{1}(sdprodW defM) mulG_subG sub_Inertia //.
+ rewrite !cfIirrE ?irrXtheta ?Fmu_f //=.
+ apply: subset_trans (sub_inertia_Ind _ (der_norm 1 M)).
+ by rewrite subsetI sW1M /=.
+pose Smu := [seq 'Ind[M] 'chi_s | s in Xmu].
+have sSmu_mu: {subset Smu <= mu_}.
+ move=> _ /imageP[s Xmu_s ->]; rewrite mem_filter /=.
+ rewrite irrEchar cfnorm_Ind_irr ?gFnormal // def_IXmu //.
+ rewrite -(index_sdprod defM) (eqC_nat _ 1) gtn_eqF ?prime_gt1 // andbF.
+ rewrite mem_seqInd ?gFnormal /normal ?(subset_trans sH0H) ?gFsub //=.
+ suffices /(subsetP sXthXH0C): s \in Xtheta.
+ by apply: subsetP; rewrite setSD // Iirr_kerS ?joing_subl.
+ have /imsetP[i nz_i ->] := Xmu_s; rewrite /Xtheta -imset_comp.
+ by apply/imsetP; exists (mu_f i); rewrite /= ?cfIirrE ?Fmu_f.
+have ResIndXmu: {in Xmu, forall s, 'Res ('Ind[M] 'chi_s) = q%:R *: 'chi_s}.
+ move=> s /def_IXmu Imu_s; rewrite cfResInd_sum_cfclass ?gFnormal ?Imu_s //.
+ by rewrite -(index_sdprod defM) -Imu_s cfclass_inertia big_seq1.
+have uSmu: uniq Smu.
+ apply/dinjectiveP=> s1 s2 Xs1 Xs2 /(congr1 'Res[HU]); rewrite !ResIndXmu //.
+ by move/(can_inj (scalerK (neq0CG W1)))/irr_inj.
+have sz_Smu: size Smu = p.-1.
+ by rewrite size_map -cardE card_in_imset // cardC1 card_Iirr_abelian ?oH1.
+have [sz_mu s_mu_H0C] := nb_redM_H0.
+have Dmu: Smu =i mu_.
+ by have [|//] := leq_size_perm uSmu sSmu_mu; rewrite sz_mu sz_Smu.
+split=> {Part_a part_a}//.
+- split=> // phi mu_phi; have S_HOC_phi := s_mu_H0C _ mu_phi.
+ move: mu_phi; rewrite -Dmu => /imageP[_ /imsetP[i nz_i ->]].
+ rewrite cfIirrE ?irrXtheta ?Fmu_f // => Dphi.
+ split=> //; rewrite Dphi ?cfInd1 ?cfIndInd //.
+ rewrite -(index_sdprod defM) -/q -Du mulrA -natrM.
+ by rewrite lin_char1 1?cfMod_lin_char ?mulr1.
+ by exists (theta (mu_f i) %% H0)%CF; rewrite 1?cfMod_lin_char.
+- have /eqVproper: Xmu \subset Xtheta.
+ apply/subsetP=> _ /imsetP[i nz_i ->]; rewrite -[Xtheta]imset_comp /=.
+ by apply/imsetP; exists (mu_f i); rewrite /= ?cfIirrE ?Fmu_f.
+ case=> [defXmu | /andP[_ /subsetPn[s theta_s Xmu'_s]]]; last first.
+ have [_ /imsetP[f Dth_f ->] Ds] := imsetP theta_s; rewrite cfIirrE // in Ds.
+ have /irrP[t Dt]: 'Ind 'chi_s \in irr M; last 1 [exists t; rewrite -{t}Dt].
+ apply: contraR Xmu'_s => red_Ind_s.
+ have: 'Ind 'chi_s \in mu_.
+ rewrite mem_filter /= red_Ind_s mem_seqInd ?gFnormal //=.
+ apply: subsetP theta_s; rewrite (subset_trans sXthXH0C) ?setSD //.
+ by rewrite Iirr_kerS ?joing_subl.
+ rewrite -Dmu => /imageP[s1 Xmu_s1] /(congr1 (cfdot ('Ind 'chi_s1)))/eqP.
+ rewrite cfnorm_Ind_irr ?gFnormal // eq_sym -cfdot_Res_l.
+ rewrite ResIndXmu // cfdotZl cfdot_irr -natrM mulnC.
+ by case: (s1 =P s) => [<- // | _] /idPn[]; apply: neq0CiG.
+ split; first 2 [by rewrite mem_seqInd ?gFnormal ?(subsetP sXthXH0C)].
+ rewrite Ds cfIirrE ?irrXtheta ?cfInd1 // -Du -(index_sdprod defM) -/q.
+ by rewrite mulrA -natrM lin_char1 ?cfMod_lin_char ?mulr1.
+ exists (theta f %% H0)%CF; first by rewrite cfMod_lin_char.
+ by rewrite Ds cfIirrE ?irrXtheta //= cfIndInd.
+ suffices /(congr1 odd): u = (p.-1 ^ q.-1)%N.
+ rewrite odd_exp -(subnKC (prime_gt1 pr_q)) /= -subn1 odd_sub ?prime_gt0 //.
+ by rewrite -oH1 (oddSg sH1H) ?quotient_odd // mFT_odd.
+ have p1_gt0: (0 < p.-1)%N by rewrite -(subnKC (prime_gt1 p_pr)).
+ apply/eqP; rewrite -(eqn_pmul2r p1_gt0) -expnSr prednK ?prime_gt0 //.
+ by rewrite -oXtheta -defXmu card_in_imset // cardC1 card_Iirr_abelian ?oH1.
+clear Xmu def_IXmu Smu sSmu_mu ResIndXmu uSmu sz_Smu sz_mu s_mu_H0C Dmu.
+clear Mtheta Xtheta irrXtheta oXtheta sXthXH0C mu_f Fmu_f mk_mu sW1_Imu inj_mu.
+clear nz_thetaH lin_thetaH lin_theta Ftheta inj_theta irr_thetaH0 def_Itheta.
+clear theta Dtheta => irr_qa lb_n lb_d.
+have sU'U: U' \subset U := der_sub 1 U.
+have nH0U := subset_trans sUHU nH0HU; have nH0U' := subset_trans sU'U nH0U.
+have sU'CH1: U' \subset 'C_U(H1 | 'Q).
+ by rewrite subsetI sU'U sub_astabQ nH0U' (centsS sH1H) ?quotient_cents.
+have sCH1_U: 'C_U(H1 | 'Q) \subset U := subsetIl U _.
+have dvd_lb: lb_d %| lb_n.
+ rewrite -[lb_d]mulnA dvdn_mul // -(Lagrange sCH1_U).
+ by rewrite mulnC dvdn_pmul2r ?cardSg ?indexg_gt0.
+split; rewrite ?leq_divLR // /lb_n -(Lagrange sCH1_U) -/a -(Lagrange sU'CH1).
+rewrite mulnCA -mulnA mulnC !mulnA !leq_pmul2r ?cardG_gt0 ?indexg_gt0 // mulnC.
+pose H1CH1 := (H1 <*> 'C_(U / H0)(H1))%G; pose HCH1 := (H <*> 'C_U(H1 | 'Q))%G.
+have defH1CH1: H1 \x 'C_(U / H0)(H1) = H1CH1.
+ rewrite dprodEY ?subsetIr ?coprime_TIg ?(coprimeSg sH1H) //.
+ by rewrite (coprimegS (subsetIl _ _)) ?coprime_morph.
+have sHCH1_HU: HCH1 \subset HU by rewrite join_subG sHHU (subset_trans sCH1_U).
+have nsHCH1_HU: HCH1 <| HU.
+ rewrite /normal sHCH1_HU -(sdprodW defHU) mulG_subG normsG ?joing_subl //=.
+ by rewrite normsY // sub_der1_norm.
+have nsH0_HCH1: H0 <| HCH1.
+ by rewrite (normalS _ sHCH1_HU) // (subset_trans sH0H) ?joing_subl.
+have nsH1cHU: H1c <| HU / H0.
+ rewrite -(bigdprodWY defH1c) /normal gen_subG norms_gen ?andbT //.
+ by apply/bigcupsP=> w /setD1P[_ /nsH1wHUb/andP[]].
+ by apply/norms_bigcup/bigcapsP=> w /setD1P[_ /nH1wHUb].
+have defHCH1: H1c ><| H1CH1 = (HCH1 / H0)%G.
+ have /sdprodP[_ /mulG_sub[sH1cH _] nH1cH1 tiH1cH1] := dprodWsdC defHb1.
+ rewrite sdprodE /= -(dprodW defH1CH1).
+ - rewrite mulgA (dprodWC defHb1) -morphim_setIpre -astabQ -quotientMl //.
+ by rewrite norm_joinEr // (subset_trans sCH1_U).
+ - rewrite mul_subG ?subIset // (subset_trans (quotientS _ sUHU)) //.
+ exact: normal_norm nsH1cHU.
+ rewrite -(setIidPl sH1cH) setIAC -setIA -group_modl // coprime_TIg ?mulg1 //.
+ by rewrite coprime_sym (coprimegS (subsetIl _ _)) ?coprime_morph.
+have [nsH1cHCH1 sH1CH1_HCH1 _ nH1cH1C _] := sdprod_context defHCH1.
+pose Clam := ('C_(U / H0)(H1) / (U' / H0))%G.
+pose lam (j : Iirr Clam) := 'chi_(mod_Iirr j).
+pose theta i j := cfSdprod defHCH1 (cfDprod defH1CH1 'chi_i (lam j)).
+have nsU'CH1: U' <| 'C_U(H1 | 'Q) by rewrite (normalS _ sCH1_U) ?gFnormal.
+have nsU'CH1b: U' / H0 <| 'C_(U / H0)(H1).
+ by rewrite -morphim_setIpre -astabQ quotient_normal.
+have abClam: abelian Clam.
+ by rewrite sub_der1_abelian //= quotient_der ?dergS ?subsetIl.
+have lam_lin j: lam j \is a linear_char.
+ by rewrite /lam mod_IirrE ?cfMod_lin_char //; apply/char_abelianP.
+have theta_lin i j: theta i j \is a linear_char.
+ by rewrite cfSdprod_lin_char ?cfDprod_lin_char.
+have <-: #|Clam| = #|'C_U(H1 | 'Q) : U'|.
+ rewrite -card_quotient ?normal_norm //= /= -morphim_setIpre -astabQ.
+ have nsU'U : U' <| U by apply: der_normal.
+ rewrite -(restrmEsub _ _ sCH1_U) -(restrm_quotientE _ sU'U) -morphim_quotm.
+ rewrite card_injm ?quotientS ?injm_quotm ?(isom_inj (quotient_isom _ _)) //.
+ by rewrite coprime_TIg ?(coprimeSg sH0H).
+pose Mtheta := [set mod_Iirr (cfIirr (theta i j)) | i in [set~ 0], j in setT].
+have ->: (p.-1 * #|Clam|)%N = #|Mtheta|.
+ rewrite [Mtheta]curry_imset2X card_imset ?cardsX => [|[i1 j1] [i2 j2] /=/eqP].
+ by rewrite cardsC1 cardsT !card_Iirr_abelian ?(abelianS sH1H) ?oH1.
+ rewrite (can_eq (mod_IirrK _)) // -(inj_eq irr_inj) !cfIirrE ?lin_char_irr //.
+ rewrite (can_eq (cfSdprodK _)) -!dprod_IirrE (inj_eq irr_inj).
+ by rewrite (can_eq (dprod_IirrK _)) => /eqP[->] /(can_inj (mod_IirrK _))->.
+have{lam_lin} thetaH1 i j: 'Res[H1] (theta i j) = 'chi_i.
+ rewrite -(cfResRes _ _ sH1CH1_HCH1) ?joing_subl // cfSdprodK cfDprodKl //.
+ exact: lin_char1.
+have Itheta r: r \in Mtheta -> 'I_HU['chi_r]%CF = HCH1.
+ case/imset2P=> i j; rewrite /= in_setC1 => nz_i _ Dr; apply/eqP.
+ rewrite eqEsubset sub_Inertia //= Dr mod_IirrE // cfIirrE ?lin_char_irr //.
+ rewrite andbT -(quotientSGK _ (normal_sub nsH0_HCH1)) ?subIset ?nH0HU //.
+ rewrite inertia_mod_quo //.
+ apply: subset_trans (sub_inertia_Res _ (nH1wHUb _ (group1 _))) _.
+ rewrite /= conjsg1 thetaH1 (inertia_irr_prime _ p_pr) //.
+ rewrite -quotient_setIpre -astabQ quotientS // -{1}(sdprodW defHU).
+ by rewrite -genM_join sub_gen // group_modl // sub_astabQ nH0H (centsS sH1H).
+have irr_Xtheta: {in Mtheta, forall r, 'Ind[HU] 'chi_r \in irr HU}.
+ by move=> r Mr; rewrite /= inertia_Ind_irr ?Itheta.
+pose Xtheta := [set cfIirr ('Ind[HU] 'chi_r) | r in Mtheta].
+have Da: a = #|HU : HCH1| by rewrite -(index_sdprodr defHU).
+have Xtheta_1: {in Xtheta, forall s, 'chi_s 1%g = a%:R}.
+ move=> _ /imsetP[r Mr ->]; have /imset2P[i j _ _ Dr] := Mr.
+ rewrite cfIirrE ?irr_Xtheta ?cfInd1 //= -Da lin_char1 ?mulr1 //.
+ by rewrite Dr mod_IirrE ?cfMod_lin_char // cfIirrE ?lin_char_irr.
+have nsH0U'HU: H0U' <| HU.
+ by apply: normalS nsH0U'_M; rewrite // -(sdprodWY defHU) genS ?setUSS.
+have sXthetaXH0U': Xtheta \subset X_ H0U'.
+ apply/subsetP=> _ /imsetP[r Mr ->]; have [i j nz_i _ Dr] := imset2P Mr.
+ rewrite !inE cfIirrE ?irr_Xtheta ?sub_cfker_Ind_irr //= ?normal_norm //.
+ rewrite Dr mod_IirrE // cfIirrE ?lin_char_irr // join_subG andbCA.
+ rewrite {1}cfker_mod //= !{1}sub_cfker_mod //; apply/andP; split; last first.
+ rewrite -(sdprodWY (sdprod_cfker _ _)) sub_gen ?subsetU // orbC.
+ rewrite (subset_trans _ (cfker_dprod _ _ _)) // sub_gen ?subsetU // orbC.
+ by rewrite /lam mod_IirrE ?cfker_mod.
+ apply: contraL nz_i => /(subset_trans sH1H); rewrite !inE negbK.
+ by move/(sub_cfker_Res (subxx _)); rewrite thetaH1 subGcfker.
+have nsCH1_U: 'C_U(H1 | 'Q) <| U by rewrite sub_der1_normal.
+have nH1cU: (U / H0)%g \subset 'N(H1c).
+ rewrite -(bigdprodWY defH1c) norms_gen ?norms_bigcup //.
+ apply/bigcapsP=> w /setD1P[_ W1w].
+ by rewrite normJ -sub_conjgV (normsP (quotient_norms H0 nUW1)) ?groupV.
+have ->: #|Mtheta| = (#|Xtheta| * a)%N.
+ rewrite Da mulnC -card_imset_Ind_irr // => _ xy /imset2P[i j nz_i _ ->].
+ case/(mem_sdprod defHU)=> x [y [Hx Uy -> _]]; have HUy := subsetP sUHU y Uy.
+ pose yb := inMb y; have Uyb: yb \in (U / H0)%g by rewrite mem_quotient.
+ pose iy := conjg_Iirr i yb; pose jy := conjg_Iirr j (coset (U' / H0)%g yb).
+ apply/imset2P; exists iy jy; rewrite !inE ?conjg_Iirr_eq0 // in nz_i *.
+ apply: irr_inj; have HCH1x: x \in HCH1 by rewrite mem_gen ?inE ?Hx.
+ rewrite conjg_IirrE (cfConjgM _ nsHCH1_HU) ?(subsetP sHHU x) {Hx}//.
+ rewrite {x HCH1x}(cfConjg_id _ HCH1x) !{1}mod_IirrE //.
+ rewrite !{1}cfIirrE ?lin_char_irr //.
+ rewrite cfConjgMod_norm ?(subsetP nH0U) ?(subsetP (normal_norm nsHCH1_HU)) //.
+ have nCH1_Ub: (U / H0)%g \subset 'N('C_(U / H0)(H1)).
+ by rewrite normsI ?normG ?norms_cent.
+ rewrite cfConjgSdprod ?cfConjgDprod ?(subsetP _ _ Uyb) ?normsY //.
+ rewrite /theta /lam !{1}mod_IirrE // !{1}conjg_IirrE.
+ by rewrite cfConjgMod_norm ?(subsetP _ _ Uyb) // quotient_norms ?gFnorm.
+rewrite leq_pmul2r ?indexg_gt0 // cardE -(size_map (fun s => 'Ind[M] 'chi_s)).
+have kerH1c s: s \in Xtheta -> H1c \subset (cfker 'chi_s / H0)%g.
+ case/imsetP=> r Mr ->; have [i j _ _ Dr] := imset2P Mr.
+ rewrite -(setIidPr (normal_sub nsH1cHCH1)) -morphim_setIpre quotientS //.
+ rewrite cfIirrE ?irr_Xtheta ?sub_cfker_Ind_irr //; last first.
+ by rewrite normsI ?normal_norm // -(quotientGK nsH0_HU) cosetpre_normal.
+ rewrite Dr mod_IirrE // cfker_morph ?normal_norm // cfIirrE ?lin_char_irr //.
+ by rewrite setIS ?joing_subl ?morphpreS // cfker_sdprod.
+have injXtheta:
+ {in M & Xtheta &, forall w s1 s2, 'chi_s1 = 'chi_s2 ^ w -> w \in HU}%CF.
+- move=> _ s1 s2 /(mem_sdprod defM)[y [w [HUy W1w -> _]]] Xs1 Xs2.
+ rewrite groupMl // cfConjgMnorm ?(subsetP (normG _) y) ?(subsetP nHUW1) //.
+ rewrite {y HUy}(cfConjg_id _ HUy) => Ds1.
+ have nH0w: w \in 'N(H0) by rewrite ?(subsetP nH0M) ?(subsetP sW1M).
+ rewrite (subsetP (normal_sub nsH0_HU)) // coset_idr //.
+ have /setDP[]:= subsetP sXthetaXH0U' s1 Xs1; rewrite !inE join_subG /=.
+ case/andP=> kerH0s1 _; apply: contraNeq; rewrite -eq_invg1 => ntw.
+ rewrite -(quotientSGK nH0H) // -(dprodW defHb1) mul_subG ?kerH1c //=.
+ rewrite Ds1 cfker_conjg ?(subsetP nHUW1) // quotientJ // -sub_conjgV.
+ rewrite (subset_trans _ (kerH1c s2 Xs2)) // -(bigdprodWY defH1c) sub_gen //.
+ by rewrite (bigcup_max (inMb w)^-1%g) // !inE ntw groupV mem_quotient.
+rewrite -size_filter uniq_leq_size //.
+ apply/dinjectiveP=> s1 s2 Xs1 Xs2.
+ case/(cfclass_Ind_irrP _ _ (der_normal 1 M))/cfclassP=> y My Ds2.
+ by apply: irr_inj; rewrite Ds2 cfConjg_id ?(injXtheta y s1 s2).
+move=> _ /imageP[s Xs ->]; rewrite mem_filter /= cfInd1 // -(index_sdprod defM).
+rewrite Xtheta_1 // -natrM eqxx mem_seqInd ?gFnormal //.
+rewrite (subsetP sXthetaXH0U') // !andbT inertia_Ind_irr ?gFnormal //.
+by apply/subsetP=> y /setIP[My /inertiaJ/esym/injXtheta->].
+Qed.
+
+Import ssrnum Num.Theory.
+
+(* This is Peterfalvi (9.9); we have exported the fact that HU / H0 is a *)
+(* Frobenius group in case (c), as this is directly used in (9.10). *)
+Lemma typeP_Galois_characters (is_Galois : typeP_Galois) :
+ [/\ (*a*) {in X_ H0, forall s, (u %| 'chi_s 1%g)%Cx},
+ {in X_ H0C', forall s, 'chi_s 1%g = u%:R /\
+ (exists2 xi : 'CF(HC), xi \is a linear_char & 'chi_s = 'Ind xi)},
+ (*b*) size mu_ = p.-1 /\ {in mu_, forall mu_j, isIndHC mu_j}
+ & (*c*) all redM (S_ H0C') ->
+ [/\ C :=: 1%g, u = (p ^ q).-1 %/ p.-1
+ & [Frobenius HU / H0 = Hbar ><| (U / H0)]]].
+Proof.
+have [F [phi [psi _ [Kpsi phiJ]]]] := typeP_Galois_P is_Galois.
+case=> [oF /isomP[inj_phi im_phi] phiW2] [cycUbar co_u_p1 u_dv_pq1].
+have [nsHUM sW1M /mulG_sub[sHUM _] nHUW1 tiHUW1] := sdprod_context defM.
+have [nsHHU sUHU /mulG_sub[sHHU _] nHU tiHU] := sdprod_context defHU.
+have [nsH0C_M nsHC_M _ nsH0C'_M] := nsH0xx_M; have nH0H := normal_norm nsH0H.
+have nsH0HU: H0 <| HU := normalS (subset_trans sH0H sHHU) sHUM nsH0M.
+have nH0U: U \subset 'N(H0) := subset_trans sUHU (normal_norm nsH0HU).
+have nH0C := subset_trans sCU nH0U.
+have sH0C_HU: H0C \subset HU by rewrite -(sdprodWY defHU) genS ?setUSS.
+have nsH0C_HU: H0C <| HU := normalS sH0C_HU sHUM nsH0C_M.
+have nH0C_HU := normal_norm nsH0C_HU.
+have [coH0U coHC] := (coprimeSg sH0H coHU, coprimegS sCU coHU).
+have [nH0C_H nH0C_U] := (subset_trans sHHU nH0C_HU, subset_trans sUHU nH0C_HU).
+have tiHOC_H: H0C :&: H = H0.
+ by rewrite /= norm_joinEr // -group_modl // setIC coprime_TIg ?mulg1.
+have{coH0U} tiHOC_U: H0C :&: U = C.
+ by rewrite /= norm_joinEr // setIC -group_modr // setIC coprime_TIg ?mul1g.
+have isoHbar: Hbar \isog H / H0C.
+ by have:= second_isog nH0C_H; rewrite tiHOC_H.
+have isoUbar: Ubar \isog U / H0C.
+ by have:= second_isog nH0C_U; rewrite tiHOC_U.
+have frobHU: [Frobenius HU / H0C = (H / H0C) ><| (U / H0C)].
+ have defHUbar: (H / H0C) ><| (U / H0C) = (HU / H0C)%g.
+ exact: quotient_coprime_sdprod.
+ apply/Frobenius_semiregularP=> //; first by rewrite -(isog_eq1 isoHbar).
+ by rewrite -(isog_eq1 isoUbar); have [] := Frobenius_context frobUW1c.
+ move=> yb /setD1P[ntyb /morphimP[y nH0Cy Uy] Dyb] /=; rewrite Dyb.
+ apply/trivgP/subsetP=> _ /setIP[/morphimP[/= x nHOCx Hx ->] /cent1P/commgP].
+ rewrite -morphR //; set xy := [~ x, y] => /eqP/coset_idr/=H0Cxy.
+ have [nH0x nH0y] := (subsetP nH0H x Hx, subsetP nH0U y Uy).
+ rewrite inE coset_id ?mem_gen // inE coset_idr //; apply: contraNeq ntyb.
+ rewrite -(morph_injm_eq1 inj_phi) ?mem_quotient // => nz_x.
+ rewrite {yb}Dyb /= coset_id ?mem_gen // -Kpsi !inE Uy orbC /= -val_eqE.
+ rewrite -(inj_eq (mulfI nz_x)) mulr1 -[_ * _]phiJ ?mem_quotient // qactJ nH0y.
+ rewrite -morphJ // conjg_mulR -/xy mkerr ?eqxx // ker_coset -tiHOC_H inE.
+ by rewrite andbC groupM ?groupV ?memJ_norm ?(subsetP nHU) //= H0Cxy ?groupR.
+have{coHC} tiHbC: (Hbar :&: C / H0 = 1)%g by rewrite coprime_TIg ?coprime_morph.
+have{tiHbC} defHCbar: Hbar \x (C / H0) = (HC / H0)%g.
+ by rewrite dprodEY ?quotientY // [C]unlock/= astabQ quotient_setIpre subsetIr.
+have sHCHU: HC \subset HU by rewrite -(sdprodWY defHU) genS ?setUS.
+have nsHCHU: HC <| HU := normalS sHCHU sHUM nsHC_M.
+have sH0HC: H0 \subset HC := subset_trans sH0H (joing_subl H C).
+have nsH0HC: H0 <| HC := normalS sH0HC sHCHU nsH0HU.
+have nsHHUb: Hbar <| HU / H0 by rewrite quotient_normal.
+have I_XH0_C i: i != 0 -> 'I_HU['chi[Hbar]_i %% H0]%CF = HC.
+ move=> /= nz_i; apply/esym/eqP.
+ have nsCHUb: C / H0 <| HU / H0 by rewrite -quotientYidl ?quotient_normal.
+ have sH0C_HC: H0C \subset HC by rewrite genS ?setSU.
+ have nsH0C_HC: H0C <| HC := normalS sH0C_HC sHCHU nsH0C_HU.
+ have [j Dj]: exists j, 'chi_j = (cfDprodl defHCbar 'chi_i %% H0)%CF.
+ by rewrite -dprodl_IirrE -mod_IirrE //; set j := mod_Iirr _; exists j.
+ have kerH0Cj: H0C \subset cfker 'chi_j.
+ by rewrite Dj sub_cfker_mod ?join_subG ?normG // quotientYidl ?cfker_sdprod.
+ rewrite inertia_mod_pre // -(inertia_dprodl defHCbar) ?normal_norm //.
+ rewrite -inertia_mod_pre // -Dj eqEsubset sub_Inertia //=.
+ rewrite -(quotientSGK _ sH0C_HC) ?subIset ?nH0C_HU -?inertia_quo //.
+ rewrite -(quotientYidr nH0C_H) joingA (joing_idPl sH0H) in frobHU.
+ rewrite -?quo_IirrE ?(inertia_Frobenius_ker (FrobeniusWker frobHU)) //.
+ by rewrite quo_Iirr_eq0 // -irr_eq1 Dj cfMod_eq1 // cfDprodl_eq1 irr_eq1.
+have{I_XH0_C} irr_IndHC r: r \in Iirr_kerD HC H H0 -> 'Ind 'chi_r \in irr HU.
+ rewrite !inE => /andP[ker'H kerH0]; apply: inertia_Ind_irr => //.
+ apply: subset_trans (sub_inertia_Res _ (normal_norm nsHHU)) _.
+ rewrite -{kerH0}(quo_IirrK _ kerH0) // mod_IirrE // in ker'H *.
+ have /codomP[[i j] Dr] := dprod_Iirr_onto defHCbar (quo_Iirr H0 r).
+ rewrite {r}Dr dprod_IirrE cfResMod ?joing_subl ?sub_cfker_mod //= in ker'H *.
+ rewrite cfDprod_Resl linearZ inertia_scale_nz ?irr1_neq0 ?I_XH0_C //.
+ by apply: contraNneq ker'H => ->; rewrite irr0 cfDprod_cfun1l cfker_sdprod.
+have [nb_mu H0C_mu] := nb_redM_H0; set part_a' := ({in X_ H0C', _}).
+have Part_a s: s \in X_ H0 -> exists r, 'chi_s = 'Ind[HU, HC] 'chi_r.
+ rewrite !inE => /andP[Ks'H KsH0]; have [r sHCr] := constt_cfRes_irr HC s.
+ have{KsH0} KrH0: H0 \subset cfker 'chi_r.
+ by rewrite (sub_cfker_constt_Res_irr sHCr) // ?normal_norm.
+ have{Ks'H} Kr'H: ~~ (H \subset cfker 'chi_r).
+ by rewrite (sub_cfker_constt_Res_irr sHCr) ?joing_subl // ?normal_norm.
+ have [|s1 Ds1] := irrP _ (irr_IndHC r _); first by rewrite !inE Kr'H.
+ rewrite -constt_Ind_Res Ds1 constt_irr inE in sHCr.
+ by rewrite (eqP sHCr) -Ds1; exists r.
+have [nH0HC nH0C'] := (normal_norm nsH0HC, subset_trans (der_sub 1 _) nH0C).
+have Part_a': part_a'.
+ move=> s /setDP[KsH0C' Ks'H]; have [|r Ds] := Part_a s.
+ by rewrite inE Ks'H (subsetP (Iirr_kerS _ _) _ KsH0C') ?joing_subl.
+ suffices lin_r: 'chi_r \is a linear_char.
+ by split; [rewrite Du Ds cfInd1 ?lin_char1 ?mulr1 | exists 'chi_r].
+ have KrH0C': H0C' \subset cfker 'chi_r.
+ rewrite inE Ds sub_cfker_Ind_irr // in KsH0C'.
+ by rewrite (subset_trans sHUM) ?normal_norm.
+ rewrite lin_irr_der1 (subset_trans _ KrH0C') //= (norm_joinEr nH0C').
+ rewrite -quotientSK ?(subset_trans (der_sub 1 _)) ?quotient_der //= -/C.
+ by rewrite -(der_dprod 1 defHCbar) (derG1P abHbar) dprod1g.
+split=> // [s /Part_a[r ->] | | {Part_a' part_a'}red_H0C'].
+- by rewrite Du cfInd1 // dvdC_mulr // Cint_Cnat ?Cnat_irr1.
+- split=> // mu_j /H0C_mu H0C_mu_j; have [s XH0Cs Dmuj] := seqIndP H0C_mu_j.
+ have [|s1u [xi lin_xi Ds]] := Part_a' s.
+ by rewrite (subsetP _ _ XH0Cs) ?Iirr_kerDS // genS ?setUS ?der_sub.
+ split=> //; first by rewrite Dmuj cfInd1 // s1u -natrM -(index_sdprod defM).
+ by rewrite Dmuj Ds cfIndInd //; exists xi.
+have C1: C :=: 1%g.
+ apply: contraTeq red_H0C' => ntC; apply/allPn.
+ have sCM: C \subset M := subset_trans sCU (subset_trans sUHU sHUM).
+ have{sCM} solCbar: solvable (C / H0).
+ by rewrite quotient_sol ?(solvableS sCM) ?mmax_sol.
+ have [|{ntC solCbar} j lin_j nz_j] := solvable_has_lin_char _ solCbar.
+ rewrite -(isog_eq1 (quotient_isog _ _)) ?(subset_trans sCU) //.
+ by rewrite coprime_TIg ?(coprimegS sCU) ?(coprimeSg sH0H).
+ have [i lin_i nz_i] := solvable_has_lin_char ntHbar solHbar.
+ pose r := mod_Iirr (dprod_Iirr defHCbar (i, j)).
+ have KrH0: H0 \subset cfker 'chi_r by rewrite mod_IirrE ?cfker_mod.
+ have Kr'H: ~~ (H \subset cfker 'chi_r).
+ rewrite -subsetIidl -cfker_Res ?joing_subl ?irr_char // mod_IirrE //.
+ rewrite cfResMod ?joing_subl // sub_cfker_mod // dprod_IirrE.
+ by rewrite cfDprodKl ?lin_char1 // subGcfker -irr_eq1.
+ have [|s Ds] := irrP _ (irr_IndHC r _); first by rewrite !inE Kr'H.
+ have Ks'H: s \notin Iirr_ker HU H.
+ by rewrite inE -Ds sub_cfker_Ind_irr ?normal_norm.
+ exists ('Ind 'chi_s).
+ rewrite mem_seqInd ?gFnormal // inE Ks'H inE -Ds.
+ rewrite sub_cfker_Ind_irr // ?(subset_trans sHUM) ?normal_norm //=.
+ rewrite mod_IirrE // join_subG cfker_mod // sub_cfker_mod ?quotient_der //.
+ apply: subset_trans (dergS 1 (quotientS H0 (joing_subr H C))) _.
+ by rewrite -lin_irr_der1 dprod_IirrE cfDprod_lin_char.
+ apply: contra nz_j => red_j; have /implyP := H0C_mu ('Ind 'chi_s).
+ rewrite mem_filter red_j !mem_seqInd ?gFnormal // !in_setD Ks'H !inE -Ds.
+ rewrite irr_eq1 !sub_cfker_Ind_irr ?(normal_norm nsH0HU) //.
+ rewrite mod_IirrE // join_subG cfker_mod //= sub_cfker_mod // dprod_IirrE.
+ by move/(sub_cfker_Res (subxx _)); rewrite cfDprodKr ?lin_char1 ?subGcfker.
+rewrite /= -/C C1 joingG1 in frobHU; split=> //; move/FrobeniusWker in frobHU.
+have nsHbHU: Hbar <| (HU / H0) by rewrite quotient_normal.
+have ->: (p ^ q).-1 = (#|X_ H0| * u)%N.
+ rewrite -oF -cardsT -im_phi card_injm // -(card_Iirr_abelian abHbar).
+ rewrite -(cardsC1 0) (card_imset_Ind_irr nsHbHU) => [|i|i y]; last first.
+ - by rewrite !inE conjg_Iirr_eq0.
+ - by rewrite !inE => nz_i; rewrite inertia_Ind_irr ?inertia_Frobenius_ker.
+ rewrite index_quotient_eq ?(subset_trans sHUM) ?subIset ?sH0H ?orbT //.
+ apply/eqP; rewrite Du /= C1 joingG1 mulnC eqn_pmul2r //.
+ rewrite -(card_imset _ (can_inj (mod_IirrK _))) // -imset_comp.
+ apply/eqP/eq_card=> s; apply/imsetP/idP=> [[i nz_i -> /=] | Xs].
+ rewrite !inE mod_IirrE 1?{1}cfker_mod // andbT in nz_i *.
+ rewrite cfIirrE ?inertia_Ind_irr ?inertia_Frobenius_ker // sub_cfker_mod //.
+ by rewrite sub_cfker_Ind_irr ?quotientS ?normal_norm // subGcfker.
+ have [[]] := (Part_a s Xs, setDP Xs).
+ rewrite /= C1 joingG1 !inE => r Ds [kerH0s].
+ have:= kerH0s; rewrite Ds !sub_cfker_Ind_irr ?normal_norm // => kerH0 ker'H.
+ exists (quo_Iirr H0 r).
+ by rewrite !inE -subGcfker quo_IirrE // cfker_quo ?quotientSGK.
+ by rewrite quo_IirrE // cfIndQuo // -Ds -quo_IirrE // irrK quo_IirrK.
+suffices ->: #|X_ H0| = p.-1 by rewrite -(subnKC (prime_gt1 p_pr)) mulKn.
+rewrite -nb_mu (size_red_subseq_seqInd_typeP MtypeP _ H0C_mu) //; last first.
+- exact/allP/filter_all.
+- by rewrite filter_uniq ?seqInd_uniq.
+apply/esym/eq_card => i; rewrite inE mem_filter mem_seqInd ?gFnormal //.
+rewrite andb_idl // => Xi; rewrite (allP red_H0C') //.
+by rewrite mem_seqInd ?gFnormal //= C1 (trivgP (der_sub 1 _)) joingG1.
+Qed.
+
+(* This combination of (9.8)(b) and (9.9)(b) covers most uses of these lemmas *)
+(* in sections 10-14. *)
+Lemma typeP_reducible_core_Ind (ptiWM := FT_primeTI_hyp MtypeP) :
+ [/\ size mu_ = p.-1, has predT mu_,
+ {subset mu_ <= [seq primeTIred ptiWM j | j in predC1 0]}
+ & {in mu_, forall mu_j, isIndHC mu_j}].
+Proof.
+have [[sz_mu _] /mulG_sub[sHHU _]] := (nb_redM_H0, sdprodW defHU).
+rewrite has_predT sz_mu -subn1 subn_gt0 prime_gt1 //; split=> // [mu_j|].
+ rewrite mem_filter => /andP[red_chi /seqIndP[s /setDP[_ kerH's] Dchi]].
+ have [[j Ds] | [/idPn[]]] := prTIres_irr_cases ptiWM s; last by rewrite -Dchi.
+ rewrite Dchi Ds cfInd_prTIres image_f ?inE //=.
+ by apply: contraNneq kerH's => j0; rewrite inE Ds j0 prTIres0 cfker_cfun1.
+have[/typeP_Galois_characters[_ _ []] // | Gal'M] := boolP typeP_Galois.
+by have [_ []] := typeP_nonGalois_characters Gal'M.
+Qed.
+
+(* This is Peterfalvi (9.10), formulated as a constructive alternative. *)
+Lemma typeP_reducible_core_cases :
+ {t : Iirr M & 'chi_t \in S_ H0C' /\ 'chi_t 1%g = (q * u)%:R
+ & {xi | xi \is a linear_char & 'chi_t = 'Ind[M, HC] xi}}
+ + [/\ typeP_Galois, [Frobenius HU / H0 = Hbar ><| (U / H0)],
+ cyclic U, #|U| = (p ^ q).-1 %/ p.-1
+ & FTtype M == 2 -> [Frobenius HU = H ><| U]].
+Proof.
+have [GalM | Gal'M] := boolP typeP_Galois; last first.
+ pose eqInHCb nu r := ('chi_r \is a linear_char) && (nu == 'Ind[M, HC] 'chi_r).
+ pose isIndHCb (nu : 'CF(M)) :=
+ (nu 1%g == (q * u)%:R) && [exists r, eqInHCb nu r].
+ suffices /sig2W[t H0C't]: exists2 t, 'chi_t \in S_ H0C' & isIndHCb 'chi_t.
+ case/andP=> /eqP t1qu /exists_inP/sig2W[r lin_r /eqP def_t].
+ by left; exists t => //; exists 'chi_r.
+ have [_ _ [t [t1qu H0Ct IndHCt]] _] := typeP_nonGalois_characters Gal'M.
+ exists t; first by rewrite (seqIndS _ H0Ct) ?Iirr_kerDS ?genS ?setUS ?der_sub.
+ rewrite /isIndHCb t1qu eqxx; have [xi lin_xi ->] := IndHCt.
+ by apply/exists_inP; exists (cfIirr xi); rewrite cfIirrE ?lin_char_irr.
+have [_ IndHC_SH0C' _] := typeP_Galois_characters GalM; rewrite all_predC.
+case: hasP => [/sig2W[eta H0C'eta /irrP/sig_eqW[t Dt]] _ | _ [//|C1 <- frobHU]].
+ have /sig2_eqW[s /IndHC_SH0C'[s1u IndHCs] Deta] := seqIndP H0C'eta.
+ have [joinHU [xi lin_xi Ds]] := (sdprodWY defHU, sig2_eqW IndHCs).
+ left; exists t; first split; rewrite -Dt // Deta.
+ by rewrite cfInd1 ?der_sub // -(index_sdprod defM) s1u -natrM.
+ by exists xi; rewrite ?Ds ?cfIndInd ?der_sub // -joinHU genS ?setUS ?subsetIl.
+have cycU: cyclic U.
+ rewrite (isog_cyclic (quotient1_isog _)) -C1.
+ by have [_ _ []] := typeP_Galois_P GalM.
+right; split=> //; first by rewrite /u /Ubar C1 -(card_isog (quotient1_isog _)).
+case/(compl_of_typeII maxM MtypeP) => /= _ _ _ UtypeF <-.
+have [_ -> _] := typeF_context UtypeF.
+by apply/forall_inP=> S /and3P[_ /cyclicS->].
+Qed.
+
+Import ssrint.
+
+(* This is Peterfalvi (9.11) *)
+(* We had to cover a small gap in step (9.11.4) of the proof, which starts by *)
+(* proving that U1 \subset {1} u A(M), then asserts this obviously implies *)
+(* HU1 \subset {1} u A(M). It is not, as while {1} u A(M) does contain H, it *)
+(* is not (necessarily) a subgroup. We had to use the solvability of HU1 in a *)
+(* significant way (using Philip Hall's theorems) to bridge the gap; it's *)
+(* also possible to exploit lemma (2.1) (partition_cent_rcoset in PFsection1) *)
+(* in a slightly different argument, but the inference is nontrivial in *)
+(* either case. *)
+Lemma Ptype_core_coherence : coherent (S_ H0C') M^# tau.
+Proof.
+have [nsHUM sW1M /mulG_sub[sHUM _] nHUW1 tiHUW1] := sdprod_context defM.
+have [nsHHU sUHU /mulG_sub[sHHU _] nHU tiHU] := sdprod_context defHU.
+have nsCU: C <| U := normalS sCU (joing_subl _ _) nsCUW1.
+have [_ nCU] := andP nsCU; have sC'C: C^`(1)%g \subset C := der_sub 1 _.
+have coHC := coprimegS sCU coHU; have coH0C := coprimeSg sH0H coHC.
+have [nsH0C_M nsHC_M nsH0U'_M nsH0C'_M] := nsH0xx_M; have [_ nH0H]:= andP nsH0H.
+have nH0HU := subset_trans sHUM nH0M; have nH0U := subset_trans sUHU nH0HU.
+have nH0C := subset_trans sCU nH0U; have nH0C' := subset_trans sC'C nH0C.
+have sHCHU: HC \subset HU by rewrite join_subG sHHU (subset_trans sCU).
+have [nsHCHU nHC] := (normalS sHCHU sHUM nsHC_M, subset_trans sCU nHU).
+have tiHCbar: Hbar :&: (C / H0)%g = 1%g by rewrite coprime_TIg ?coprime_morph.
+have defHCbar: Hbar \x (C / H0) = (HC / H0)%g.
+ by rewrite dprodEY ?quotientY // [C]unlock/= astabQ quotient_setIpre subsetIr.
+have{tiHCbar} defHC'bar: (HC / H0)^`(1)%g = (C^`(1) / H0)%g.
+ by rewrite -(der_dprod 1 defHCbar) (derG1P abHbar) dprod1g quotient_der.
+have sU'U := der_sub 1 U; have nH0U' := subset_trans sU'U nH0U.
+have sU'C: U' \subset C.
+ by rewrite [C]unlock subsetI sub_astabQ sU'U nH0U' quotient_cents.
+have uS0: uniq (S_ H0C') by apply: seqInd_uniq.
+have [rmR scohS0]: exists R : 'CF(M) -> seq 'CF(G), subcoherent (S_ H0C') tau R.
+ move: (FTtypeP_coh_base _ _) (FTtypeP_subcoherent maxM MtypeP) => R scohR.
+ exists R; apply: (subset_subcoherent scohR).
+ split=> //; last exact: cfAut_seqInd.
+ by apply: seqIndS; rewrite Iirr_kerDS ?sub1G ?Fcore_sub_FTcore.
+have [GalM | Gal'M] := boolP typeP_Galois.
+ have [_ XOC'u _ _] := typeP_Galois_characters GalM.
+ apply: uniform_degree_coherence scohS0 _.
+ apply: all_pred1_constant (#|M : HU| * u)%:R _ _; rewrite all_map.
+ by apply/allP=> _ /seqIndP[s /XOC'u[s1u _] ->] /=; rewrite natrM cfInd1 ?s1u.
+have:= typeP_nonGalois_characters Gal'M.
+set U1 := 'C_U(_ | _); set a := #|_ : _|.
+case: (_ Gal'M) => /= H1 [oH1 nH1U _ defHbar aP] in U1 a *.
+rewrite -/U1 -/a in aP; case: aP => a_gt1 a_dv_p1 cycU1 _.
+case=> [a_dv_XH0 [nb_mu IndHCmu] has_irrHC lb_Sqa]; rewrite -[S_ _]/(S_ H0C').
+have defHb1 := defHbar; rewrite (big_setD1 1%g) ?group1 ?conjsg1 //= in defHb1.
+have [[_ H1c _ defH1c] _ _ _] := dprodP defHb1; rewrite defH1c in defHb1.
+have [nsH1H _] := dprod_normal2 defHb1; have [sH1H _] := andP nsH1H.
+have nsU1U: U1 <| U; last have [sU1U nU1U] := andP nsU1U.
+ by rewrite norm_normalI // astabQ norm_quotient_pre ?norms_cent.
+have Da: a = #|HU : H <*> U1|.
+ rewrite /a -!divgS /= ?join_subG ?sHHU ?norm_joinEr ?(subset_trans sU1U) //=.
+ by rewrite -(sdprod_card defHU) coprime_cardMg ?(coprimegS sU1U) ?divnMl.
+have sCU1: C \subset U1 by rewrite [C]unlock setIS ?astabS.
+have a_dv_u: a %| u by rewrite Da Du indexgS ?genS ?setUS.
+have [a_gt0 q_gt0 u_gt0 p1_gt0]: [/\ 0 < a, 0 < q, 0 < u & 0 < p.-1]%N.
+ rewrite !cardG_gt0 ltnW // -subn1 subn_gt0 prime_gt1 //.
+have [odd_p odd_q odd_a]: [/\ odd p, odd q & odd a].
+ by rewrite mFT_odd -oH1 (oddSg sH1H) ?(dvdn_odd a_dv_u) ?mFT_quo_odd.
+have Dp: p = (2 * p.-1./2 + 1)%N.
+ by rewrite mul2n -[p]odd_double_half odd_p half_double addn1.
+(* Start of main proof. *)
+pose S1 := filter [pred zeta : 'CF(M) | zeta 1%g == (q * a)%:R] (S_ H0C').
+have ntS1: (0 < size S1)%N.
+ have [lb_dv lbS1] := lb_Sqa; apply: leq_trans (leq_trans lbS1 _).
+ by rewrite ltn_divRL // mul0n muln_gt0 p1_gt0 cardG_gt0.
+ rewrite -size_filter uniq_leq_size ?filter_uniq ?seqInd_uniq // => chi.
+ rewrite !mem_filter -andbA /= => /and3P[_ ->].
+ by apply: seqIndS; rewrite Iirr_kerDS // genS ?setUS ?dergS ?subsetIl.
+have sS10: cfConjC_subset S1 (S_ H0C').
+ split=> [||chi]; first by rewrite filter_uniq.
+ by apply: mem_subseq; apply: filter_subseq.
+ rewrite !mem_filter !inE cfunE => /andP[/eqP <- S0chi].
+ by rewrite cfAut_seqInd // andbT conj_Cnat ?(Cnat_seqInd1 S0chi).
+have cohS1: coherent S1 M^# tau.
+ apply: uniform_degree_coherence (subset_subcoherent scohS0 sS10) _.
+ by apply: all_pred1_constant (q * a)%:R _ _; rewrite all_map filter_all.
+pose S3 := filter [predC S1] (S_ H0C'); move: {2}_.+1 (ltnSn (size S3)) => nS.
+move: @S3 (sS10) (cohS1); have: {subset S1 <= S1} by [].
+elim: nS {-1}S1 => // nS IHnS S2 => sS12 S3 sS20 cohS2; rewrite ltnS => leS3nS.
+have [ntS3|] := boolP (size S3 > 0)%N; last first.
+ rewrite size_filter -has_count has_predC negbK => /allP sS02.
+ exact: subset_coherent sS02 cohS2.
+(* Ultimateley we'll contradict the maximality of S2 in (9.11.1) & (9.11.8). *)
+suff [chi]: exists2 chi, chi \in S3 & coherent (chi :: chi^* :: S2)%CF M^# tau.
+ rewrite mem_filter => /andP[/= S2'chi S0chi]; have [uS2 sS2S0 ccS2] := sS20.
+ move/IHnS; apply=> [psi /sS12 S1psi||]; first by rewrite 2?mem_behead.
+ split.
+ - rewrite /= !inE negb_or S2'chi (contra (ccS2 _)) ?cfConjCK // eq_sym.
+ by rewrite (seqInd_conjC_neq _ _ _ S0chi) ?mFT_odd.
+ - by apply/allP; rewrite /= S0chi cfAut_seqInd //=; apply/allP.
+ apply/allP; rewrite /= !inE cfConjCK !eqxx orbT /=.
+ by apply/allP=> psi /ccS2; rewrite !inE orbA orbC => ->.
+ apply: leq_trans leS3nS; rewrite ltnNge; apply: contra S2'chi.
+ case/leq_size_perm=> [|psi|/(_ chi)]; first by rewrite filter_uniq.
+ by rewrite !mem_filter !inE orbA negb_or -andbA => /andP[].
+ by rewrite !mem_filter !inE eqxx S0chi !andbT => /esym/negbFE.
+(* This is step (9.11.1). *) clear nS IHnS leS3nS.
+without loss [[eqS12 irrS1 H0C_S1] [Da_p defC] [S3qu ne_qa_qu] [oS1 oS1ua]]:
+ / [/\ [/\ S1 =i S2, {subset S1 <= irr M} & {subset S1 <= S_ H0C}],
+ a = p.-1./2 /\ C :=: U',
+ (forall chi, chi \in S3 -> chi 1%g == (q * u)%:R) /\ (q * u != q * a)%N
+ & size S1 = (p.-1 * u %/ a ^ 2)%N /\ size S1 = (2 * u %/ a)%N].
+- move=> IHwlog; have{sS20} [[uS2 sS20 ccS2] [uS1 _ _]] := (sS20, sS10).
+ pose is_qu := [pred chi : 'CF(M) | chi 1%g == (q * u)%:R].
+ pose isn't_qu := [pred chi | is_qu chi ==> all is_qu S3].
+ have /hasP[chi S3chi qu'chi]: has isn't_qu S3.
+ rewrite /isn't_qu; have [_|] := boolP (all _ _); last by rewrite has_predC.
+ by rewrite (eq_has (fun _ => implybT _)) has_predT.
+ have [S2'chi S0chi]: chi \notin S2 /\ chi \in S_ H0C'.
+ by apply/andP; rewrite mem_filter in S3chi.
+ have [s X0C's Dchi] := seqIndP S0chi.
+ have Dchi1: chi 1%g = q%:R * 'chi_s 1%g.
+ by rewrite Dchi cfInd1 // -(index_sdprod defM).
+ (* We'll show lb0 <= lb1 <= lb <= lb3 <= sumnS S1' <= sumnS S2 <= lb0, *)
+ (* with equality under conditions that imply the conclusion of (9.11.1). *)
+ pose lb0 := (2 * q * a)%:R * chi 1%g.
+ pose lb1 : algC := (2 * a * q ^ 2 * u)%:R.
+ pose lb2 : algC := (p.-1 * q ^ 2 * u)%:R.
+ pose lb3 : algC := (p.-1 * q ^ 2 * #|U : U'|)%:R.
+ pose S1' := filter [predI irr M & S_ H0U'] S1.
+ pose szS1' := ((p.-1 * #|U : U'|) %/ a ^ 2)%N; set lbS1' := _ %/ _ in lb_Sqa.
+ pose Snorm (psi : 'CF(M)) := psi 1%g ^+ 2 / '[psi].
+ pose sumnS Si := \sum_(psi <- Si) Snorm psi.
+ have lb01: lb0 <= lb1 ?= iff (chi 1%g == (q * u)%:R).
+ rewrite /lb1 mulnA -mulnA natrM /lb0 mulnAC mono_lerif; last first.
+ by apply: ler_pmul2l; rewrite ltr0n !muln_gt0 a_gt0.
+ apply: lerif_eq; rewrite Dchi1 natrM ler_pmul2l ?gt0CG //.
+ have [KsH0C' _] := setDP X0C's; rewrite inE in KsH0C'.
+ have [t sHCt] := constt_cfRes_irr HC s.
+ have KtH0C': H0C' \subset cfker 'chi_t.
+ apply: subset_trans (cfker_constt (cfRes_char _ (irr_char s)) sHCt).
+ by rewrite cfker_Res ?irr_char // subsetI genS ?setUSS.
+ rewrite -constt_Ind_Res in sHCt.
+ apply: ler_trans (char1_ge_constt (cfInd_char _ (irr_char t)) sHCt) _.
+ rewrite cfInd1 // -Du lin_char1 ?mulr1 // lin_irr_der1.
+ apply: subset_trans KtH0C'; rewrite /= (norm_joinEr nH0C') /= -/C.
+ rewrite -quotientSK ?(subset_trans (der_sub _ _)) ?(subset_trans sHCHU) //.
+ by rewrite -defHC'bar quotient_der ?(subset_trans sHCHU).
+ have lb12: lb1 <= lb2 ?= iff (a == p.-1./2).
+ rewrite -(@eqn_pmul2l 2) // -(canLR (addnK 1) Dp) subn1 lerif_nat.
+ rewrite !(mono_leqif (fun _ _ => leq_pmul2r _)) ?expn_gt0 ?q_gt0 //.
+ apply: leqif_eq; rewrite dvdn_leq // Gauss_dvd //.
+ by rewrite {1}Dp addn1 dvdn_mulr.
+ by rewrite prime_coprime ?dvdn2 ?negbK.
+ have lb23: lb2 <= lb3 ?= iff (C :==: U') :> algC.
+ rewrite lerif_nat [u]card_quotient //.
+ rewrite (mono_leqif (fun _ _ => leq_pmul2l _)) ?muln_gt0 ?p1_gt0 ?q_gt0 //.
+ rewrite -(mono_leqif (fun _ _ => leq_pmul2l (cardG_gt0 C))) Lagrange //.
+ rewrite -(Lagrange sU'U) (mono_leqif (fun _ _ => leq_pmul2r _)) //.
+ by rewrite eq_sym; apply: subset_leqif_cards.
+ have lb3S1': lb3 <= sumnS S1' ?= iff (size S1' == szS1').
+ rewrite /szS1' -(divnMr (cardG_gt0 U')) mulnAC -mulnA Lagrange // -/lbS1'.
+ have{lb_Sqa} [dv_lb lbSqa] := lb_Sqa; rewrite [sumnS S1']big_seq.
+ rewrite (eq_bigr (fun _ => ((q * a) ^ 2)%:R)) => [|psi]; last first.
+ rewrite !mem_filter -!andbA => /and4P[/irrP[r ->] _ /=/eqP r1qa _].
+ by rewrite /Snorm cfnorm_irr divr1 r1qa natrX.
+ rewrite -big_seq (big_nth 0) -natr_sum sum_nat_const_nat subn0.
+ rewrite mulnC natrM [*%R]lock /lb3 natrM natf_indexg ?der_sub // mulrA.
+ rewrite -natrM mulnAC -(divnK dv_lb) mulnAC mulnA natrM mulfK ?neq0CG //.
+ rewrite -/lbS1' -mulnA -expnMn natrM mulrC -lock mono_lerif; last first.
+ by apply: ler_pmul2l; rewrite ltr0n !muln_gt0 a_gt0 q_gt0.
+ rewrite eq_sym lerif_nat; apply: leqif_eq; rewrite (leq_trans lbSqa) //.
+ rewrite -size_filter uniq_leq_size ?filter_uniq ?seqInd_uniq // => psi.
+ rewrite !mem_filter -!andbA /= => /and3P[-> -> S0psi]; rewrite S0psi.
+ by apply: seqIndS S0psi; rewrite Iirr_kerDS //= genS ?setUS ?dergS.
+ have lbS1'2: sumnS S1' <= sumnS S2 ?= iff ~~ has [predC S1'] S2.
+ have Ds2: perm_eq S2 (S1' ++ filter [predC S1'] S2).
+ rewrite -(perm_filterC (mem S1')) perm_cat2r.
+ rewrite uniq_perm_eq ?filter_uniq // => psi.
+ by rewrite mem_filter andb_idr //= mem_filter => /andP[_ /sS12].
+ rewrite [sumnS S2](eq_big_perm _ Ds2) big_cat /= -/(sumnS S1') big_filter.
+ rewrite -all_predC -big_all_cond !(big_tnth _ _ S2) big_andE.
+ rewrite -{1}[_ S1']addr0 mono_lerif; last exact: ler_add2l.
+ set sumS2' := \sum_(i | _) _; rewrite -[0]/(sumS2' *+ 0) -sumrMnl.
+ apply: lerif_sum => i _; apply/lerifP; rewrite lt0r !mulf_eq0 invr_eq0.
+ set psi := tnth _ i; have Spsi := sS20 psi (mem_tnth _ _).
+ rewrite !negb_or (seqInd1_neq0 _ Spsi) //= (cfnorm_seqInd_neq0 _ Spsi) //=.
+ by rewrite divr_ge0 ?exprn_ge0 ?cfnorm_ge0 ?Cnat_ge0 ?(Cnat_seqInd1 Spsi).
+ have [lb0S2 | ] := boolP (lb0 < sumnS S2).
+ exists chi => //; have /hasP[xi S1xi _]: has predT S1 by rewrite has_predT.
+ have xi1: xi 1%g = (q * a)%:R.
+ by rewrite mem_filter in S1xi; have [/eqP] := andP S1xi.
+ apply: ((extend_coherent scohS0) _ xi) => //; first by rewrite S0chi sS12.
+ split=> //; last by rewrite mulrAC xi1 -natrM mulnA.
+ rewrite xi1 Dchi1 irr1_degree -natrM dvdC_nat dvdn_pmul2l ?cardG_gt0 //.
+ rewrite -dvdC_nat /= !nCdivE -irr1_degree a_dv_XH0 //.
+ by rewrite (subsetP (Iirr_kerDS _ _ _) _ X0C's) ?joing_subl.
+ have lb1S2 := lerif_trans lb12 (lerif_trans lb23 (lerif_trans lb3S1' lbS1'2)).
+ rewrite ltr_neqAle !(lerif_trans lb01 lb1S2) andbT has_predC !negbK.
+ case/and5P=> /eqP chi1qu /eqP Da_p /eqP defC /eqP sz_S1' /allP sS21'.
+ have defS1': S1' = S1.
+ apply/eqP; rewrite -(geq_leqif (size_subseq_leqif (filter_subseq _ S1))).
+ by rewrite uniq_leq_size // => psi /sS12/sS21'.
+ apply: IHwlog; split=> //.
+ + split=> psi; do 1?[rewrite -defS1' mem_filter andbC => /and3P[_ _] //=].
+ by apply/idP/idP=> [/sS12 | /sS21']; rewrite ?defS1'.
+ by congr (_ \in S_ _); apply/group_inj; rewrite /= defC.
+ + split; first by apply/allP; apply: contraLR qu'chi; rewrite /= chi1qu eqxx.
+ rewrite -eqC_nat -chi1qu; apply: contra S2'chi => chi1qa.
+ by rewrite sS12 // mem_filter /= chi1qa.
+ rewrite -defS1' sz_S1' /szS1' -defC -card_quotient // -/u.
+ by split=> //; rewrite -mulnn {1}Dp addn1 -Da_p mulnAC divnMr.
+have nCW1: W1 \subset 'N(C).
+ by rewrite (subset_trans (joing_subr U W1)) ?normal_norm.
+(* This is step (9.11.2). *) clear sS20 cohS2 sS12 has_irrHC lb_Sqa sU'C.
+have [tiU1 le_u_a2]: {in W1^#, forall w, U1 :&: U1 :^ w = C} /\ (u <= a ^ 2)%N.
+ have tiU1 w: w \in W1^# -> U1 :&: U1 :^ w = C; last split => //.
+ case/setD1P=> ntw W1w; have nH0w := subsetP (subset_trans sW1M nH0M) w W1w.
+ pose wb := coset H0 w; have W1wb: wb \in W1bar^#.
+ rewrite !inE mem_quotient ?(contraNneq _ ntw) // => /coset_idr H0w.
+ rewrite -in_set1 -set1gE -tiHUW1 inE (subsetP sHHU) // (subsetP sH0H) //.
+ by rewrite H0w.
+ have ntH1 w1: H1 :^ w1 :!=: 1%g by rewrite -cardG_gt1 cardJg oH1 prime_gt1.
+ pose t_ w1 :=
+ if pred2 1%g wb w1 then sval (has_nonprincipal_irr (ntH1 w1)) else 0.
+ pose theta :=
+ cfDprodl defHCbar (cfBigdprod defHbar (fun w1 => 'chi_(t_ w1))).
+ have lin_theta : theta \is a linear_char.
+ rewrite cfDprodl_lin_char ?cfBigdprod_lin_char // => w1 _.
+ by rewrite irr_prime_lin ?cardJg ?oH1.
+ have nsH0HC: H0 <| HC.
+ by rewrite /normal join_subG nH0H sub_gen ?subsetU ?sH0H.
+ move defK: H0C => K. (* to avoid divergence in Coq kernel *)
+ have kerK: K \subset cfker (theta %% H0).
+ rewrite -defK sub_cfker_mod ?join_subG ?normG ?quotientYidl //.
+ exact: cfker_sdprod.
+ have sKHC: K \subset HC by rewrite -defK genS ?setSU.
+ have nsKHC: K <| HC by rewrite (normalS sKHC (normal_sub nsHC_M)) -?defK.
+ have sH0K: H0 \subset K by rewrite -defK joing_subl.
+ have nsKHU: K <| HU.
+ by rewrite (normalS (subset_trans sKHC sHCHU) sHUM) -?defK.
+ have [t2 Dt2]: {t2 : Iirr (HC / K) | 'chi_t2 %% K = theta %% H0}%CF.
+ exists (cfIirr ((theta %% H0) / K)).
+ by rewrite cfIirrE ?cfQuoK ?cfQuo_irr ?cfMod_irr ?lin_char_irr.
+ have nsHChatHU: HC / K <| HU / K by rewrite quotient_normal.
+ have sHChatHU := normal_sub nsHChatHU.
+ pose That := 'I_(HU / K)['chi_t2]%G.
+ have sThatHU: That \subset (HU / K)%G := Inertia_sub _ _.
+ have abThatHC: abelian (That / (HC / K)).
+ rewrite (abelianS (quotientS _ sThatHU)) //.
+ rewrite (isog_abelian (third_isog _ _ _)) // defC.
+ rewrite -(isog_abelian (quotient_sdprodr_isog defHU _)) ?gFnormal //.
+ by rewrite sub_der1_abelian.
+ have hallHChat: Hall That (HC / K).
+ rewrite /Hall -(card_isog (third_isog sH0K nsH0HC nsKHC)) /=.
+ rewrite sub_Inertia // -[in #|_|]defK /= quotientYidl //.
+ rewrite -(card_isog (sdprod_isog (dprodWsdC defHCbar))).
+ apply: coprime_dvdr (indexSg (sub_Inertia _ sHChatHU) sThatHU) _.
+ apply: coprime_dvdr (index_quotient _) _.
+ by rewrite subIset // normal_norm.
+ by rewrite -Du coprime_morphl // coprime_morphr.
+ have [s t2HUs] := constt_cfInd_irr t2 sHChatHU.
+ have s_1: ('chi_s %% K)%CF 1%g = #|U : U1 :&: U1 :^ w|%:R.
+ rewrite cfMod1.
+ have [||_ _ ->] // := cfInd_Hall_central_Inertia _ abThatHC.
+ rewrite -cfMod1 Dt2 cfMod1 lin_char1 //= mulr1 -inertia_mod_quo // Dt2.
+ rewrite index_quotient_eq ?normal_norm ?Inertia_sub ?setIS //; last first.
+ by rewrite (subset_trans sKHC) ?sub_inertia.
+ rewrite /= inertia_morph_pre //= -quotientE inertia_dprodl; first 1 last.
+ - by rewrite quotient_norms ?normal_norm.
+ - rewrite /= -(quotientYidl nH0C) quotient_norms ?normal_norm //.
+ by rewrite -defK in nsKHU.
+ have nH1wHU w1: w1 \in (W1 / H0)%g -> (HU / H0)%g \subset 'N(H1 :^ w1).
+ move=> W1w1; rewrite -(normsP (quotient_norms H0 nHUW1) _ W1w1) normJ.
+ rewrite conjSg /= -(sdprodW defHU) quotientMl ?mul_subG //.
+ exact: normal_norm.
+ rewrite indexgI /= inertia_bigdprod_irr // (big_setD1 1%g) ?group1 //=.
+ rewrite 2!{1}setIA setIid (bigD1 wb) //= {1 2}/t_ /= !eqxx ?orbT /=.
+ rewrite !(inertia_irr_prime _ p_pr) ?cardJg //=;
+ try by case: (has_nonprincipal_irr _).
+ rewrite conjsg1 centJ setIA -setIIr /=.
+ elim/big_rec: _ => [|w1 Uk /andP[/setD1P[ntw1 Ww1] w'w1] IHk]; last first.
+ rewrite /t_ -if_neg negb_or ntw1 w'w1 irr0 Inertia1 -?setIIr 1?setIA //.
+ rewrite /normal nH1wHU //= -(normsP (quotient_norms H0 nHUW1) _ Ww1).
+ by rewrite conjSg (subset_trans sH1H) ?quotientS.
+ rewrite setIT !morphpreI morphpreJ ?(subsetP nH0W1) //= -astabQ.
+ rewrite quotientGK //; last by rewrite /normal (subset_trans sH0H).
+ rewrite -(sdprodWY (sdprod_modl defHU _)); last first.
+ rewrite subsetI -sub_conjgV.
+ rewrite (normsP (gFnorm _ _)) ?groupV ?(subsetP sW1M) //= andbb.
+ by rewrite sub_astabQ nH0H sub_abelian_cent.
+ rewrite -(index_sdprodr defHU) ?subsetIl // conjIg (normsP nUW1) //.
+ by rewrite -setIIr.
+ apply/esym/eqP; rewrite eqEcard subsetI -sub_conjgV.
+ rewrite (normsP _ _ (groupVr W1w)) ?sCU1 /=; last first.
+ by rewrite (subset_trans (joing_subr U W1)) ?normal_norm.
+ have{s_1} : pred2 u a #|U : U1 :&: U1 :^ w|.
+ rewrite /= -!eqC_nat -{}s_1 -mod_IirrE //.
+ pose phi := 'Ind[M] 'chi_(mod_Iirr s).
+ have Sphi: phi \in S_ H0C'.
+ rewrite mem_seqInd ?gFnormal // !inE mod_IirrE //.
+ rewrite andbC (subset_trans _ (cfker_mod _ _)) //=; last first.
+ by rewrite -defK genS ?setUS ?der_sub.
+ rewrite sub_cfker_mod ?(subset_trans sHHU) ?normal_norm //.
+ have sHHC: H \subset HC by rewrite joing_subl.
+ rewrite -(sub_cfker_constt_Ind_irr t2HUs) ?quotientS //; last first.
+ by rewrite quotient_norms ?normal_norm.
+ rewrite -sub_cfker_mod ?(subset_trans sHHU (normal_norm nsKHU)) //.
+ rewrite Dt2 sub_cfker_mod //.
+ apply: contra (valP (has_nonprincipal_irr (ntH1 1%g))).
+ move/eq_cfker_Res; rewrite cfDprodlK => kerHbar.
+ have:= sH1H; rewrite -{1}(conjsg1 H1) -kerHbar => /eq_cfker_Res.
+ by rewrite cfBigdprodKabelian ?group1 // /t_ /= eqxx -subGcfker => ->.
+ have [/S3qu | ] := boolP (phi \in S3).
+ rewrite cfInd1 // natrM -(index_sdprod defM).
+ by rewrite (inj_eq (mulfI (neq0CG _))) => ->.
+ rewrite mem_filter Sphi andbT negbK /= -eqS12 mem_filter Sphi andbT /=.
+ rewrite cfInd1 // natrM -(index_sdprod defM) (inj_eq (mulfI (neq0CG _))).
+ by rewrite orbC => ->.
+ case/pred2P=> [iUCu | iUCa].
+ rewrite -(leq_pmul2r u_gt0) -{1}iUCu /u card_quotient ?Lagrange //.
+ by rewrite /= -setIA subsetIl.
+ rewrite subset_leq_card // subIset // [C]unlock subsetI subsetIl sub_astabQ.
+ rewrite subIset ?nH0U //= centsC -(bigdprodWY defHbar) gen_subG.
+ apply/orP; left; apply/bigcupsP=> w1 Ww1; rewrite centsC centJ -sub_conjgV.
+ rewrite (normsP _ _ (groupVr Ww1)) ?quotient_norms //.
+ by rewrite /U1 astabQ quotient_setIpre subsetIr.
+ rewrite prime_meetG //; apply/trivgPn; exists w; rewrite // !inE W1w.
+ rewrite (sameP setIidPr eqP) eqEcard subsetIr /= cardJg.
+ by rewrite -(leq_pmul2r a_gt0) -{2}iUCa !Lagrange //= -setIA subsetIl.
+ have /trivgPn[w W1w ntw]: W1 :!=: 1%g by rewrite -cardG_gt1 prime_gt1.
+ rewrite -(leq_pmul2l u_gt0) mulnn.
+ have nCU1 := subset_trans sU1U nCU.
+ have {1}->: u = (#|(U1 / C)%g| * a)%N.
+ by rewrite mulnC /u !card_quotient // Lagrange_index.
+ rewrite expnMn leq_pmul2r ?expn_gt0 ?orbF // -mulnn.
+ rewrite -{2}[U1](conjsgK w) quotientJ ?groupV ?(subsetP nCW1) //.
+ rewrite cardJg -TI_cardMg /= -/U1 ?subset_leq_card //.
+ rewrite mul_subG ?quotientS ?subsetIl //.
+ by rewrite -(normsP nUW1 w W1w) conjSg subsetIl.
+ by rewrite -quotientGI // tiU1 ?trivg_quotient // !inE ntw.
+pose S4 := filter [predD S_ H0C & redM] S3.
+have sS43: {subset S4 <= S3} by apply: mem_subseq; apply: filter_subseq.
+(* This is step (9.11.3). *)
+have nsHM: H <| M by apply: gFnormal.
+have oS4: (q * u * size S4 + p.-1 * (q + u))%N = (p ^ q).-1.
+ rewrite mulnAC {1}[q](index_sdprod defM) -[S4]filter_predI.
+ rewrite (size_irr_subseq_seqInd _ (filter_subseq _ _)) //; last first.
+ by move=> xi; rewrite mem_filter -!andbA negbK => /andP[].
+ set Xn := finset _; pose sumH0C := \sum_(s in X_ H0C) 'chi_s 1%g ^+ 2.
+ have /eqP: sumH0C = (q * size S1 * a ^ 2 + (#|Xn| + p.-1) * u ^ 2)%:R.
+ rewrite [q](index_sdprod defM) natrD natrM natrX.
+ rewrite (size_irr_subseq_seqInd _ (filter_subseq _ _)) //= -/S1.
+ have sH0CC': {subset S_ H0C <= S_ H0C'}.
+ by apply: seqIndS; rewrite Iirr_kerDS // genS ?setUS ?der_sub.
+ rewrite [sumH0C](big_setID [set s | 'Ind 'chi_s \in S1]) /=; congr (_ + _).
+ rewrite mulr_natl -[rhs in _ = rhs]sumr_const; apply: eq_big => s.
+ by rewrite in_setI inE andb_idl // => /H0C_S1; rewrite mem_seqInd.
+ rewrite 2!inE mem_filter andbCA /= cfInd1 // -(index_sdprod defM) natrM.
+ by case/andP=> /eqP/(mulfI (neq0CG _))->.
+ rewrite (eq_bigr (fun _ => u%:R ^+ 2)) => [|s]; last first.
+ rewrite 2!inE eqS12 => /andP[S2's H0Cs]; congr (_ ^+ 2).
+ have /S3qu/eqP: 'Ind 'chi_s \in S3.
+ by rewrite mem_filter /= S2's sH0CC' ?mem_seqInd.
+ by rewrite natrM cfInd1 // -(index_sdprod defM) => /(mulfI (neq0CG _)).
+ rewrite sumr_const -mulr_natl natrM natrX -nb_mu; congr (_%:R * _).
+ have [_ s_mu_H0C] := nb_redM_H0.
+ rewrite (size_red_subseq_seqInd_typeP MtypeP _ s_mu_H0C); last first.
+ - by apply/allP; apply: filter_all.
+ - by rewrite filter_uniq ?seqInd_uniq.
+ rewrite -/mu_ -[#|_|](cardsID Xn) (setIidPr _); last first.
+ apply/subsetP=> s; rewrite inE in_setD mem_filter /= -!andbA -eqS12.
+ rewrite mem_seqInd ?gFnormal // => /and4P[_ -> S1'xi _].
+ by rewrite inE S1'xi.
+ congr (_ + _)%N; apply: eq_card => i; rewrite inE -/mu_ 2!inE.
+ rewrite -[seqInd M _]/(S_ H0C') mem_filter /= andbC 2!inE eqS12 -!andbA.
+ rewrite -(mem_seqInd nsHUM) // -/(S_ H0C); set xi := 'Ind _.
+ apply/idP/idP=> [/and3P[-> H0Cxi] | mu_xi].
+ rewrite H0Cxi sH0CC' //= andbT negbK mem_filter unfold_in => ->.
+ by rewrite (seqIndS _ H0Cxi) // Iirr_kerDS ?joing_subl.
+ have [xi1u H0Cxi _] := IndHCmu _ mu_xi.
+ rewrite H0Cxi -eqS12 mem_filter sH0CC' //= !andbT xi1u eqC_nat ne_qa_qu.
+ by rewrite andbT negbK mem_filter in mu_xi *; case/andP: mu_xi.
+ rewrite oS1 -mulnA divnK ?dvdn_mul // !mulnA -mulnDl mulnC natrM {}/sumH0C.
+ rewrite /X_ -Iirr_kerDY joingC joingA (joing_idPl sH0H) /=.
+ rewrite sum_Iirr_kerD_square ?genS ?setSU //; last first.
+ by apply: normalS nsH0C_M; rewrite // -(sdprodWY defHU) genS ?setUSS.
+ rewrite -Du (inj_eq (mulfI (neq0CG _))) -(prednK (indexg_gt0 _ _)).
+ rewrite mulrSr addrK eqC_nat addnC mulnDl addnAC (mulnC q) -addnA -mulnDr.
+ move/eqP <-; congr _.-1.
+ have nH0HC: HC \subset 'N(H0) by rewrite join_subG nH0H.
+ rewrite -(index_quotient_eq _ _ nH0HC) ?genS ?setSU //; last first.
+ by rewrite setIC subIset ?joing_subl.
+ rewrite quotientYidl // -(index_sdprod (dprodWsdC defHCbar)).
+ by case: Ptype_Fcore_factor_facts.
+have /hasP[psi1 S1psi1 _]: has predT S1 by rewrite has_predT.
+pose gamma := 'Ind[M, H <*> U1] 1; pose alpha := gamma - psi1.
+(* This is step (9.11.4). *)
+pose nm_alpha : algC := a%:R + 1 + (q.-1 * a ^ 2)%:R / u%:R.
+have [Aalpha Nalpha]: alpha \in 'CF(M, 'A(M)) /\ '[alpha] = nm_alpha.
+ have sHU1_HU: H <*> U1 \subset HU by rewrite -(sdprodWY defHU) genS ?setUS.
+ have sHU1_M := subset_trans sHU1_HU sHUM.
+ have sHU1_A1: H <*> U1 \subset 1%g |: 'A(M).
+ pose pi := \pi(H); rewrite -subDset; apply/subsetP=> y /setD1P[nty HU1y].
+ apply/bigcupP; rewrite notMtype1 /=; have sHMs := Fcore_sub_FTcore maxM.
+ have defHU1: H ><| U1 = H <*> U1 := sdprod_subr defHU sU1U.
+ have nsH_HU1: H <| H <*> U1 by have [] := sdprod_context defHU1.
+ have [HUy [_ nH_HU1]] := (subsetP sHU1_HU y HU1y, normalP nsH_HU1).
+ have hallH: pi.-Hall(H <*> U1) H.
+ by rewrite Hall_pi // -(coprime_sdprod_Hall_l defHU1) (coprimegS sU1U).
+ have hallU1: pi^'.-Hall(H <*> U1) U1.
+ by rewrite -(compl_pHall _ hallH) sdprod_compl.
+ have [pi'y | pi_y] := boolP (pi^'.-elt y); last first.
+ exists y.`_pi; last by rewrite 3!inE nty HUy cent1C groupX ?cent1id.
+ rewrite !inE (sameP eqP constt1P) pi_y (subsetP sHMs) //.
+ by rewrite (mem_normal_Hall hallH) ?groupX ?p_elt_constt.
+ have solHU1: solvable (H <*> U1) by rewrite (solvableS sHU1_M) ?mmax_sol.
+ have [||z HU1z U1yz] := Hall_Jsub _ hallU1 _ pi'y; rewrite ?cycle_subG //.
+ have /trivgPn[x /setIP[Hx cxyz] ntx]: 'C_H[y ^ z] != 1%g.
+ apply: contraTneq (prime_gt1 p_pr) => regHy; rewrite -oH1 cardG_gt1 negbK.
+ move: U1yz; rewrite -cycleJ subsetI sub_astabQ => /and3P[sYU nHY cH1Y].
+ rewrite centsC in cH1Y; rewrite -(setIidPl cH1Y) -(setIidPl sH1H) -setIA.
+ rewrite -coprime_quotient_cent ?(coprimegS sYU) // cent_cycle regHy.
+ by rewrite quotient1 setIg1.
+ exists (x ^ z^-1)%g; last by rewrite 3!inE nty HUy cent1J mem_conjgV cent1C.
+ by rewrite 2!inE conjg_eq1 ntx (subsetP sHMs) // -mem_conjg nH_HU1.
+ have{sHU1_A1} Aalpha: alpha \in 'CF(M, 'A(M)).
+ have A'1: 1%g \notin 'A(M) by have /subsetD1P[] := FTsupp_sub M.
+ rewrite -['A(M)](setU1K A'1) cfun_onD1 !cfunE subr_eq0 cfInd1 // cfun11.
+ rewrite mulr1 -(Lagrange_index sHUM) // -(index_sdprod defM) -/q.
+ rewrite -(index_sdprodr defHU) ?subsetIl // -/a eq_sym andbC.
+ have:= S1psi1; rewrite mem_filter /= => /andP[-> _] /=.
+ rewrite rpredB //.
+ apply: cfun_onS (cfInd_on sHU1_M (cfun_onG _)).
+ rewrite class_supportEr; apply/bigcupsP=> w Mw.
+ by rewrite sub_conjg conjUg conjs1g (normsP (FTsupp_norm M)) ?groupV.
+ have /seqIndP[s /setDP[_ ker'H ] ->] := H0C_S1 _ S1psi1.
+ rewrite (prDade_Ind_irr_on (FT_prDade_hypF maxM MtypeP)) //.
+ by rewrite inE in ker'H.
+ have ->: '[alpha] = '[gamma] + 1.
+ have /irrP[t Dt] := irrS1 _ S1psi1.
+ rewrite cfnormBd; first by rewrite Dt cfnorm_irr.
+ have /seqIndP[s /setDP[_ ker'H ] Dpsi1] := H0C_S1 _ S1psi1.
+ apply: contraNeq ker'H; rewrite Dt /gamma -irr0 -irr_consttE => tHU1_0.
+ rewrite inE -(sub_cfker_Ind_irr _ sHUM) ?gFnorm // -Dpsi1 Dt.
+ rewrite -(sub_cfker_constt_Ind_irr tHU1_0) ?gFnorm ?joing_subl //.
+ by rewrite irr0 cfker_cfun1 joing_subl.
+ split=> //; rewrite /nm_alpha addrAC natrM mulrAC mulrC; congr (_ + 1).
+ rewrite -{1}(mulnK a a_gt0) natf_div ?dvdn_mull // -mulrDr mulnn natrX.
+ have /sdprod_isom[nH_UW1 isomMH]: H ><| (U <*> W1) = M.
+ rewrite sdprodEY ?join_subG ?nHU ?(subset_trans sW1M) ?gFnorm //.
+ by rewrite joingA (sdprodWY defHU) (sdprodWY defM).
+ rewrite /= -(setIidPl sHHU) norm_joinEr // setIAC -setIA -group_modl //.
+ by rewrite (setIC W1) tiHUW1 mulg1.
+ have sU1_UW1: U1 \subset U <*> W1 by rewrite subIset ?joing_subl.
+ rewrite /gamma -(cfMod_cfun1 _ H) cfIndMod ?joing_subl //.
+ rewrite cfMod_iso //= quotientYidl ?(subset_trans sU1_UW1) //.
+ rewrite -(restrm_quotientE _ sU1_UW1) -(cfIsom_cfun1 (restr_isom _ isomMH)).
+ rewrite (cfIndIsom isomMH) // {nH_UW1 isomMH}cfIsom_iso.
+ rewrite -(cfIndInd _ (joing_subl U W1)) // cfInd_cfun1 //= -/U1 -/a.
+ rewrite linearZ cfnormZ normr_nat /=; congr (_ * _).
+ have defUW1: U ><| W1 = U <*> W1.
+ by rewrite sdprodEY // -(setIidPl sUHU) -setIA tiHUW1 setIg1.
+ apply: canLR (mulKf (neq0CG _)) _; rewrite -(sdprod_card defUW1) natrM -/q.
+ rewrite mulrAC mulrDr mulrCA -{1}(Lagrange sU1U) /= -/U1 -/a -(Lagrange sCU).
+ rewrite -card_quotient // !natrM !mulfK ?neq0CiG ?neq0CG //.
+ transitivity (\sum_(x in U <*> W1) \sum_(w1 in W1) \sum_(w2 in W1)
+ (x ^ w1 \in U1 :&: U1 :^ w2)%g%:R : algC).
+ - apply: eq_bigr => x _; rewrite (cfIndEsdprod _ _ defUW1) mulr_suml.
+ apply: eq_bigr => w1 W1w1; rewrite rmorph_sum mulr_sumr.
+ rewrite (reindex_inj invg_inj) (eq_bigl _ _ (groupV W1)) /=.
+ rewrite (reindex_acts 'R _ (groupVr W1w1)) ?astabsR //=.
+ apply: eq_bigr => w2 _; rewrite inE !cfuniE // rmorph_nat -natrM mulnb.
+ by congr (_ && _)%:R; rewrite invMg invgK conjgM -mem_conjg.
+ rewrite exchange_big /= mulr_natr -sumr_const; apply: eq_bigr => w1 W1w1.
+ transitivity (\sum_(w in W1) #|U1 :&: U1 :^ w|%:R : algC).
+ rewrite exchange_big /=; apply: eq_bigr => w W1w.
+ rewrite (reindex_acts 'J _ (groupVr W1w1)) ?astabsJ ?normsG ?joing_subr //=.
+ symmetry; rewrite big_mkcond -sumr_const /= big_mkcond /=.
+ apply: eq_bigr => x _; rewrite conjgKV.
+ by case: setIP => [[/(subsetP sU1_UW1)-> //] | _]; rewrite if_same.
+ rewrite (big_setD1 1%g) //= conjsg1 setIid; congr (_ + _).
+ rewrite [q](cardsD1 1%g) group1 /= mulr_natl -sumr_const.
+ by apply: eq_bigr => w W1w; rewrite tiU1.
+(* This is step (9.11.5). *)
+have [gtS4alpha s4gt0]: (size S4)%:R > '[alpha] /\ (size S4 > 0)%N.
+ suffices gtS4alpha: (size S4)%:R > '[alpha].
+ by split=> //; rewrite -ltC_nat (ler_lt_trans (cfnorm_ge0 alpha)).
+ rewrite Nalpha -(@ltr_pmul2r _ u%:R) ?ltr0n // mulrDl divfK ?neq0CG //.
+ rewrite -(ltr_pmul2l (gt0CG W1)) -/q -mulrSr -!(natrM, natrD) ltC_nat.
+ rewrite mulnA mulnAC -(ltn_add2r (p.-1 * (q + u))) oS4 {1}Dp addn1 -Da_p /=.
+ apply: leq_ltn_trans (_ : q.+2 * a ^ 3 + q ^ 2 * a ^ 2 + 2 * q * a < _)%N.
+ rewrite (addnC q) 2!mulnDr addnA (mulnAC _ a q) leq_add2r.
+ rewrite mulnA addnAC -mulnDl mulnS -addnA -mulnDl addn2 mulnCA -mulnA.
+ rewrite -[q in (_ <= _ + q * _)%N](prednK q_gt0) (mulSn q.-1) addnA.
+ by rewrite leq_add2r mulnA -mulnDl addnC leq_mul.
+ have q_gt2: (2 < q)%N.
+ by rewrite ltn_neqAle prime_gt1 ?(contraTneq _ odd_q) => // <-.
+ apply: leq_trans (_ : a.*2 ^ q + 'C(q, 2) * a.*2 ^ 2 + q * a.*2 <= _)%N.
+ rewrite -mul2n (mulnCA q) (mulnA 2) ltn_add2r !expnMn -addSn leq_add //.
+ apply: leq_ltn_trans (_ : q.-1.*2.+1 * a ^ q < _)%N.
+ rewrite leq_mul ?leq_pexp2l //.
+ by rewrite -(subnKC q_gt2) -addnn !addnS !ltnS leq_addl.
+ rewrite ltn_pmul2r ?expn_gt0 ?a_gt0 // -doubleS.
+ by rewrite -(prednK q_gt0) expnS mul2n leq_double ltn_expl.
+ rewrite mulnA leq_pmul2r ?expn_gt0 ?a_gt0 // -(subnKC q_gt2).
+ rewrite mulnCA mulnA addSn -mul_Sm_binm bin1 -mulnA leq_pmul2l //.
+ by rewrite mulnS -addSnnS leq_addr.
+ rewrite Dp -Da_p mul2n (addnC a.*2) expnDn -(subnKC q_gt2) !addSn add0n.
+ rewrite 3!big_ord_recl big_ord_recr /= !exp1n /= bin1 binn !mul1n /bump /=.
+ by do 2!rewrite addnC leq_add2l; apply: leq_addl.
+have{cohS1} [tau1 cohS1] := cohS1; have [[Itau1 Ztau1] Dtau1] := cohS1.
+have sS30: cfConjC_subset S3 (S_ H0C').
+ split=> [|chi|chi]; first by rewrite filter_uniq ?seqInd_uniq.
+ by rewrite mem_filter => /andP[].
+ rewrite !mem_filter /= -!eqS12 => /andP[S1'chi S_chi].
+ rewrite cfAut_seqInd // (contra _ S1'chi) //.
+ by have [_ _ ccS1] := sS10; move/ccS1; rewrite cfConjCK.
+have scohS3: subcoherent S3 tau rmR := subset_subcoherent scohS0 sS30.
+have [tau3 cohS3]: coherent S3 M^# tau.
+ apply: uniform_degree_coherence scohS3 _.
+ apply: all_pred1_constant (q * u)%:R _ _.
+ by rewrite all_map; apply/allP=> chi /S3qu.
+have [IZtau3 Dtau3] := cohS3; have [Itau3 Ztau3] := IZtau3.
+have notA1: 1%g \notin 'A(M) by have /subsetD1P[] := FTsupp_sub M.
+have sS0_1A: {subset S_ H0C' <= 'CF(M, 1%g |: 'A(M))}.
+ move=> _ /seqIndP[s /setDP[_ ker'H] ->]; rewrite inE in ker'H.
+ by rewrite (prDade_Ind_irr_on (FT_prDade_hypF maxM MtypeP)).
+have sS0A: {subset 'Z[S_ H0C', M^#] <= 'Z[irr M, 'A(M)]}.
+ move=> chi; rewrite (zcharD1_seqInd_Dade _ notA1) //.
+ by apply: zchar_sub_irr; apply: seqInd_vcharW.
+have Zalpha: alpha \in 'Z[irr M].
+ rewrite rpredB ?char_vchar ?cfInd_char ?rpred1 //.
+ exact: seqInd_char (H0C_S1 _ S1psi1).
+have ZAalpha: alpha \in 'Z[irr M, 'A(M)] by rewrite zchar_split Zalpha.
+have [Itau Ztau]: {in 'Z[irr M, 'A(M)], isometry tau, to 'Z[irr G]}.
+ apply: sub_iso_to (Dade_Zisometry _); last exact: zcharW.
+ by apply: zchar_onS; apply: FTsupp_sub0.
+have oSgamma: {in S_ H0C', forall lam, '[gamma, lam] = 0}.
+ move=> _ /seqIndP[s /setDP[_ ker'H ] ->].
+ rewrite ['Ind _]cfun_sum_constt cfdot_sumr big1 // => t sMt.
+ rewrite cfdotZr [gamma]cfun_sum_constt cfdot_suml big1 ?mulr0 // => t0 gMt0.
+ rewrite cfdotZl cfdot_irr (negPf (contraNneq _ ker'H)) ?mulr0 // => Dt0.
+ rewrite inE (sub_cfker_constt_Ind_irr sMt) ?gFnorm // -Dt0.
+ rewrite /gamma -irr0 in gMt0.
+ rewrite -(sub_cfker_constt_Ind_irr gMt0) ?gFnorm ?joing_subl //.
+ by rewrite irr0 cfker_cfun1 joing_subl.
+ by rewrite (subset_trans _ sHUM) // join_subG sHHU subIset ?sUHU.
+(* This is step (9.11.6). *)
+have [/eqP psi1qa Spsi1]: psi1 1%g == (q * a)%:R /\ psi1 \in S_ H0C'.
+ by move: S1psi1; rewrite mem_filter => /andP[].
+have o_alpha_S3: orthogonal alpha^\tau (map tau3 S3).
+ rewrite /orthogonal /= andbT all_map.
+ apply: contraFT (ltr_geF gtS4alpha) => /allPn[lam0 S3lam0 /= alpha_lam0].
+ set ca := '[_, _] in alpha_lam0; pose al0 := (-1) ^+ (ca < 0)%R *: alpha.
+ have{alpha_lam0} al0_lam0: '[al0^\tau, tau3 lam0] > 0.
+ have Zca: ca \in Cint by rewrite Cint_cfdot_vchar ?Ztau // Ztau3 ?mem_zchar.
+ by rewrite linearZ cfdotZl (canLR (signrMK _) (CintEsign Zca)) normr_gt0.
+ rewrite -Itau // -(cfnorm_sign (ca < 0)%R) -linearZ /= -/al0.
+ have S4_dIirrK: {in map tau3 S4, cancel (dirr_dIirr id) (@dchi _ _)}.
+ apply: dirr_dIirrPE => _ /mapP[lam S4lam ->].
+ rewrite mem_filter -andbA negbK in S4lam.
+ have [/irrP[i Dlam] _ S3lam] := and3P S4lam.
+ by rewrite dirrE Itau3 ?Ztau3 ?mem_zchar //= Dlam cfnorm_irr.
+ rewrite -(size_map tau3) -(size_map (dirr_dIirr id)).
+ rewrite -(card_uniqP _); last first.
+ rewrite !map_inj_in_uniq ?filter_uniq ?seqInd_uniq //.
+ apply: sub_in2 (Zisometry_inj Itau3) => lam.
+ by rewrite mem_filter => /andP[_ /mem_zchar->].
+ exact: can_in_inj S4_dIirrK.
+ apply: ler_trans (_ : #|dirr_constt al0^\tau|%:R <= _); last first.
+ have Zal0: al0^\tau \in 'Z[irr G] by rewrite Ztau ?rpredZsign.
+ rewrite cnorm_dconstt // -sumr_const ler_sum // => i al0_i.
+ by rewrite sqr_Cint_ge1 ?gtr_eqF -?dirr_consttE // Cint_Cnat ?Cnat_dirr.
+ rewrite leC_nat subset_leq_card //; apply/subsetP=> _ /mapP[nu S4nu ->].
+ rewrite dirr_consttE S4_dIirrK //; congr (_ > 0): al0_lam0.
+ rewrite {al0}linearZ !cfdotZl /=; congr (_ * _) => {ca}; apply/eqP.
+ have{nu S4nu} [lam S4lam ->] := mapP S4nu.
+ rewrite mem_filter in S4lam; have{S4lam} [_ S3lam] := andP S4lam.
+ have Zdlam: lam0 - lam \in 'Z[S3, M^#].
+ rewrite zcharD1E rpredB ?mem_zchar //= !cfunE subr_eq0.
+ by have [/eqP->] := (S3qu _ S3lam, S3qu _ S3lam0).
+ rewrite -subr_eq0 -cfdotBr -raddfB Dtau3 //.
+ rewrite Itau // ?sS0A //; last exact: zchar_filter Zdlam.
+ suffices{lam S3lam Zdlam} oS3a: {in S3, forall lam, '[alpha, lam] = 0}.
+ by rewrite cfdotBr subr_eq0 !oS3a.
+ move=> lam; rewrite mem_filter /= -eqS12 => /andP[S1'lam H0C'lam].
+ by rewrite cfdotBl oSgamma // (seqInd_ortho _ Spsi1) ?(memPn S1'lam) // subr0.
+have{s4gt0 gtS4alpha} /hasP[lam1 S4lam1 _]: has predT S4 by rewrite has_predT.
+have [/irrP[l1 Dl1] S3lam1]: lam1 \in irr M /\ lam1 \in S3.
+ by move: S4lam1; rewrite mem_filter -andbA negbK => /and3P[].
+have [S1'lam1 Slam1]: lam1 \notin S1 /\ lam1 \in S_ H0C'.
+ by move: S3lam1; rewrite mem_filter eqS12 => /andP[].
+have S3lam1s: lam1^*%CF \in S3 by have [[_ _ ->]] := scohS3.
+have ZS3dlam1: lam1 - lam1^*%CF \in 'Z[S3, M^#].
+ rewrite zcharD1E rpredB ?mem_zchar //.
+ by have:= seqInd_sub_aut_zchar nsHUM conjC Slam1; rewrite zcharD1 => /andP[].
+have ZAdlam1: lam1 - lam1^*%CF \in 'Z[irr M, 'A(M)].
+ rewrite sS0A // zchar_split rpredB ?mem_zchar ?cfAut_seqInd //.
+ by rewrite (zchar_on ZS3dlam1).
+pose beta := lam1 - (u %/ a)%:R *: psi1.
+have ZAbeta: beta \in 'Z[irr M, 'A(M)].
+ apply: sS0A; rewrite zcharD1E rpredB ?scaler_nat ?rpredMn ?mem_zchar //=.
+ by rewrite !cfunE subr_eq0 psi1qa -natrM mulnCA divnK // S3qu.
+have [_ _ poSS _ _] := scohS0; have [_ oSS] := pairwise_orthogonalP poSS.
+have o1S1: orthonormal S1.
+ rewrite orthonormalE filter_pairwise_orthogonal // andbT.
+ by apply/allP=> _ /irrS1/irrP[t ->]; rewrite /= cfnorm_irr.
+have o1S4: orthonormal S4.
+ rewrite orthonormalE !filter_pairwise_orthogonal // andbT.
+ apply/allP=> nu; rewrite mem_filter /= -andbA negbK.
+ by case/andP=> /irrP[t ->]; rewrite cfnorm_irr.
+have n1psi1: '[psi1] = 1 by have [_ -> //] := orthonormalP o1S1; rewrite eqxx.
+have n1lam1: '[lam1] = 1 by have [_ -> //] := orthonormalP o1S4; rewrite eqxx.
+have oS14tau: orthogonal (map tau1 S1) (map tau3 S4).
+ apply/orthogonalP=> psi _ S1psi /mapP[lam /sS43 S3lam ->].
+ apply: {psi lam S3lam}orthogonalP S1psi (map_f tau3 S3lam).
+ apply: (coherent_ortho scohS0 sS10 cohS1 sS30 cohS3) => psi /=.
+ by rewrite mem_filter !inE eqS12 => /andP[-> _].
+have [Gamma [S4_Gamma normGamma [b Dbeta]]]:
+ exists Gamma, [/\ Gamma \in 'Z[map tau3 S4], '[Gamma] = 1
+ & exists b : bool, beta^\tau
+ = Gamma - (u %/ a)%:R *: tau1 psi1 + b%:R *: \sum_(psi <- S1) tau1 psi].
+- have [G S4G [G' [Dbeta _ oG'4]]] := orthogonal_split (map tau3 S4) beta^\tau.
+ have [B S1B [Delta [dG' _ oD1]]] := orthogonal_split (map tau1 S1) G'.
+ have sZS43: {subset 'Z[S4] <= 'Z[S3]} := zchar_subset sS43.
+ have [Itau34 Ztau34] := sub_iso_to sZS43 sub_refl IZtau3.
+ have Z_G: G \in 'Z[map tau3 S4].
+ have [_ -> ->] := orthonormal_span (map_orthonormal Itau34 o1S4) S4G.
+ rewrite big_seq rpred_sum // => xi S4xi; rewrite rpredZ_Cint ?mem_zchar //.
+ rewrite -(addrK G' G) -Dbeta cfdotBl (orthoPl oG'4) // subr0.
+ rewrite Cint_cfdot_vchar ?Ztau //.
+ by have{xi S4xi} [xi S4xi ->] := mapP S4xi; rewrite Ztau34 ?mem_zchar.
+ have oD4: orthogonal Delta (map tau3 S4).
+ apply/orthoPl=> xi S4xi; rewrite -(addKr B Delta) addrC -dG' cfdotBl.
+ by rewrite (orthoPl oG'4) // (span_orthogonal oS14tau) ?subrr // memv_span.
+ have [_ -> dB] := orthonormal_span (map_orthonormal Itau1 o1S1) S1B.
+ pose b := (u %/ a)%:R + '[B, tau1 psi1].
+ have betaS1_B: {in S1, forall psi, '[beta^\tau, tau1 psi] = '[B, tau1 psi]}.
+ move=> psi S1psi; rewrite Dbeta dG' !cfdotDl (orthoPl oD1) ?map_f // addr0.
+ rewrite cfdotC (span_orthogonal oS14tau) ?rmorph0 ?add0r //.
+ by rewrite memv_span ?map_f.
+ have Zb: b \in Cint.
+ rewrite rpredD ?rpred_nat // -betaS1_B // Cint_cfdot_vchar ?Ztau //.
+ by rewrite Ztau1 ?mem_zchar.
+ have{dB} dB: B = - (u %/ a)%:R *: tau1 psi1 + b *: \sum_(psi <- S1) tau1 psi.
+ rewrite dB big_map !(big_rem _ S1psi1) /= scalerDr addrA -scalerDl addKr.
+ rewrite scaler_sumr; congr (_ + _); apply: eq_big_seq => psi.
+ rewrite mem_rem_uniq ?filter_uniq ?seqInd_uniq // => /andP[/= psi_1' S1psi].
+ apply/esym/eqP; rewrite -subr_eq0 -scalerBl -addrA -!betaS1_B // -cfdotBr.
+ have [/eqP psi_qa Spsi]: psi 1%g == (q * a)%:R /\ psi \in S_ H0C'.
+ by move: S1psi; rewrite mem_filter => /andP[].
+ have Z1dpsi: psi1 - psi \in 'Z[S1, M^#].
+ by rewrite zcharD1E rpredB ?mem_zchar //= !cfunE psi1qa psi_qa subrr.
+ rewrite -raddfB Dtau1 // Itau //; last first.
+ by rewrite sS0A // zchar_split rpredB ?mem_zchar ?(zchar_on Z1dpsi).
+ rewrite cfdotC cfdotBr cfdotZr !cfdotBl 2?oSS ?(memPn S1'lam1) // subrr.
+ by rewrite add0r n1psi1 oSS // subr0 mulr1 rmorphN conjCK subrr scale0r.
+ have Gge1: 1 <= '[G] ?= iff ('[G] == 1).
+ rewrite eq_sym; apply: lerif_eq.
+ have N_G: '[G] \in Cnat.
+ apply: Cnat_cfnorm_vchar; apply: zchar_sub_irr Z_G => _ /mapP[nu S4nu ->].
+ by rewrite Ztau34 ?mem_zchar.
+ rewrite -(truncCK N_G) ler1n lt0n -eqC_nat truncCK {N_G}// cfnorm_eq0.
+ have: '[beta^\tau, (lam1 - lam1^*%CF)^\tau] != 0.
+ rewrite Itau // cfdotBl cfdotZl !cfdotBr n1lam1.
+ rewrite (seqInd_conjC_ortho _ _ _ Slam1) ?mFT_odd // subr0.
+ rewrite !oSS ?cfAut_seqInd -?(inv_eq (@cfConjCK _ _)) ?(memPn S1'lam1) //.
+ by rewrite !(subr0, mulr0) oner_eq0.
+ by have [_ _ ->] := sS10.
+ rewrite Dbeta -Dtau3 //; apply: contraNneq => ->.
+ rewrite add0r raddfB cfdotBr !(orthoPl oG'4) ?map_f ?subr0 //.
+ rewrite mem_filter /= negbK /= S3lam1s irr_aut.
+ move: S4lam1; rewrite mem_filter /= negbK /= -andbA => /and3P[-> H0Clam1 _].
+ by rewrite cfAut_seqInd.
+ have ubG: '[G] + (b ^+ 2 - b) * (u %/ a).*2%:R + '[Delta] = 1.
+ apply: (addrI ((u %/ a) ^ 2)%:R); transitivity '[beta^\tau].
+ rewrite -!addrA addrCA Dbeta cfnormDd; last first.
+ by rewrite cfdotC (span_orthogonal oG'4) ?rmorph0 // memv_span ?inE.
+ congr (_ + _); rewrite !addrA dG' cfnormDd; last first.
+ by rewrite cfdotC (span_orthogonal oD1) ?rmorph0 // memv_span ?inE.
+ congr (_ + _); rewrite dB scaleNr [- _ + _]addrC cfnormB !cfnormZ.
+ rewrite normr_nat Cint_normK // scaler_sumr cfdotZr rmorph_nat.
+ rewrite cfnorm_map_orthonormal // cfproj_sum_orthonormal //.
+ rewrite Itau1 ?mem_zchar // n1psi1 mulr1 rmorphM rmorph_nat conj_Cint //.
+ rewrite -mulr2n oS1ua -muln_divA // mul2n -addrA addrCA -natrX mulrBl.
+ by congr (_ + (_ - _)); rewrite -mulrnAl -mulrnA muln2 mulrC.
+ rewrite Itau // cfnormBd; last first.
+ by rewrite cfdotZr oSS ?mulr0 // (memPnC S1'lam1).
+ by rewrite cfnormZ normr_nat n1psi1 n1lam1 mulr1 addrC -natrX.
+ have ubDelta: '[G] <= '[G] + '[Delta] ?= iff (Delta == 0).
+ rewrite addrC -lerif_subLR subrr -cfnorm_eq0 eq_sym.
+ by apply: lerif_eq; apply: cfnorm_ge0.
+ have{ubG} ubDeltaG: '[G] + '[Delta] <= 1 ?= iff pred2 0 1 b.
+ rewrite -{1}ubG addrAC [_ + _ + _] addrC -lerif_subLR subrr /=.
+ set n := _%:R; rewrite mulrC -{1}(mulr0 n) mono_lerif; last first.
+ by apply: ler_pmul2l; rewrite ltr0n double_gt0 divn_gt0 // dvdn_leq.
+ rewrite /= -(subr_eq0 b 1) -mulf_eq0 mulrBr mulr1 eq_sym.
+ apply: lerif_eq; rewrite subr_ge0.
+ have [-> | nz_b] := eqVneq b 0; first by rewrite expr2 mul0r.
+ rewrite (ler_trans (real_ler_norm _)) ?Creal_Cint // -[`|b|]mulr1.
+ by rewrite -Cint_normK // ler_pmul2l ?normr_gt0 // norm_Cint_ge1.
+ have [_ /esym] := lerif_trans Gge1 (lerif_trans ubDelta ubDeltaG).
+ rewrite eqxx => /and3P[/eqP normG1 /eqP Delta0 /pred2P b01].
+ exists G; split=> //; exists (b != 0).
+ rewrite Dbeta dG' Delta0 addr0 dB scaleNr addrA; congr (_ + _ *: _).
+ by case: b01 => ->; rewrite ?eqxx ?oner_eq0.
+(* Final step (9.11.8). *)
+have alpha_beta: '[alpha^\tau, beta^\tau] = (u %/ a)%:R.
+ rewrite Itau // cfdotBr cfdotZr rmorph_nat !cfdotBl !oSgamma // !sub0r.
+ by rewrite n1psi1 mulrN opprK mulr1 addrC oSS ?subr0 // (memPn S1'lam1).
+have [X S1X [Delta [Dalpha _ oD1]]]:= orthogonal_split (map tau1 S1) alpha^\tau.
+pose x := 1 + '[X, tau1 psi1].
+have alphaS1_X: {in S1, forall psi, '[alpha^\tau, tau1 psi] = '[X, tau1 psi]}.
+ by move=> psi S1psi; rewrite Dalpha cfdotDl (orthoPl oD1) ?map_f // addr0.
+have Zx: x \in Cint.
+ rewrite rpredD ?rpred1 // -alphaS1_X // Cint_cfdot_vchar ?Ztau //.
+ by rewrite Ztau1 ?mem_zchar.
+have{alphaS1_X S1X} defX: X = x *: (\sum_(psi <- S1) tau1 psi) - tau1 psi1.
+ have [_ -> ->] := orthonormal_span (map_orthonormal Itau1 o1S1) S1X.
+ rewrite addrC -scaleN1r big_map !(big_rem _ S1psi1) /= scalerDr addrA.
+ rewrite -scalerDl addKr scaler_sumr; congr (_ + _); apply: eq_big_seq => psi.
+ rewrite mem_rem_uniq ?filter_uniq ?seqInd_uniq // => /andP[/= psi_1' S1psi].
+ apply/esym/eqP; rewrite -subr_eq0 -scalerBl -addrA -!alphaS1_X // -cfdotBr.
+ have [/eqP psi_qa Spsi]: psi 1%g == (q * a)%:R /\ psi \in S_ H0C'.
+ by move: S1psi; rewrite mem_filter => /andP[].
+ have Z1dpsi: psi1 - psi \in 'Z[S1, M^#].
+ by rewrite zcharD1E rpredB ?mem_zchar //= !cfunE psi1qa psi_qa subrr.
+ rewrite -raddfB Dtau1 // Itau //; last first.
+ by rewrite sS0A // zchar_split rpredB ?mem_zchar ?(zchar_on Z1dpsi).
+ rewrite cfdotBr !cfdotBl !oSgamma // n1psi1 cfdotC oSS // rmorph0.
+ by rewrite !subr0 add0r subrr scale0r.
+have{x Zx X defX Delta Dalpha oD1} b_mod_ua: (b == 0 %[mod u %/ a])%C.
+ rewrite -oppr0 -eqCmodN (eqCmod_trans _ (eqCmodm0 _)) // {2}nCdivE.
+ rewrite -alpha_beta Dbeta -addrA cfdotDr.
+ rewrite (span_orthogonal o_alpha_S3) ?add0r; first 1 last.
+ - by rewrite memv_span ?inE.
+ - apply: subvP (zchar_span S4_Gamma); apply: sub_span; apply: mem_subseq.
+ by rewrite map_subseq ?filter_subseq.
+ rewrite Dalpha addrC cfdotDl (span_orthogonal oD1); first 1 last.
+ - by rewrite memv_span ?inE.
+ - rewrite addrC rpredB ?rpredZ //; last by rewrite memv_span ?map_f.
+ by rewrite big_seq rpred_sum // => psi S1psi; rewrite memv_span ?map_f.
+ rewrite add0r addrC defX cfdotBr cfdotBl cfdotZl cfdotZr !scaler_sumr.
+ rewrite cfdotZr !rmorph_nat cfdotBl Itau1 ?mem_zchar // n1psi1.
+ rewrite cfnorm_map_orthonormal // cfdotC !cfproj_sum_orthonormal //.
+ rewrite rmorph_nat oS1ua -muln_divA // natrM !mulrA addrC mulrC addrA.
+ rewrite -mulNr -mulrDl eqCmod_sym eqCmod_addl_mul // addrC !rpredB ?rpred1 //.
+ by rewrite !rpredM ?rpred_nat.
+have{b_mod_ua alpha_beta} b0: b = 0%N :> nat.
+ have:= b_mod_ua; rewrite /eqCmod subr0 dvdC_nat => /eqnP.
+ rewrite modn_small // (leq_ltn_trans (leq_b1 b)) // ltn_divRL // mul1n.
+ by rewrite ltn_neqAle -(eqn_pmul2l q_gt0) eq_sym ne_qa_qu dvdn_leq.
+exists lam1 => //; suffices: coherent (lam1 :: lam1^* :: S1)%CF M^# tau.
+ by apply: subset_coherent => phi; rewrite !inE eqS12.
+move: Dbeta; rewrite b0 scale0r addr0.
+apply: (extend_coherent_with scohS0 sS10 cohS1); first by [].
+rewrite rpred_nat psi1qa -natrM mulnCA (eqP (S3qu _ S3lam1)) divnK //.
+rewrite cfdotC (span_orthogonal oS14tau) ?(zchar_span S4_Gamma) ?conjC0 //.
+by rewrite rpredZ ?memv_span ?map_f.
+Qed.
+
+End Nine.