diff options
Diffstat (limited to 'mathcomp/odd_order/PFsection6.v')
| -rw-r--r-- | mathcomp/odd_order/PFsection6.v | 1649 |
1 files changed, 1649 insertions, 0 deletions
diff --git a/mathcomp/odd_order/PFsection6.v b/mathcomp/odd_order/PFsection6.v new file mode 100644 index 0000000..d74185a --- /dev/null +++ b/mathcomp/odd_order/PFsection6.v @@ -0,0 +1,1649 @@ +(* (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 ssralg poly finset center. +Require Import fingroup morphism perm automorphism quotient action zmodp. +Require Import gfunctor gproduct cyclic pgroup commutator gseries nilpotent. +Require Import sylow abelian maximal hall frobenius. +Require Import matrix mxalgebra mxrepresentation vector ssrnum algC algnum. +Require Import classfun character inertia vcharacter integral_char. +Require Import PFsection1 PFsection2 PFsection3 PFsection4 PFsection5. + +(******************************************************************************) +(* This file covers Peterfalvi, Section 6: *) +(* Some Coherence Theorems *) +(* Defined here: *) +(* odd_Frobenius_quotient K L M <-> *) +(* L has odd order, M <| L, K with K / M is nilpotent, and L / H1 is a *) +(* Frobenius group with kernel K / H1, where H1 / M = (K / M)^(1). *) +(* This is the statement of Peterfalvi, Hypothesis (6.4), except for *) +(* the K <| L and subcoherence assumptions, to be required separately. *) +(******************************************************************************) + +Set Implicit Arguments. +Unset Strict Implicit. +Unset Printing Implicit Defensive. + +Import GroupScope GRing.Theory Num.Theory. +Local Open Scope ring_scope. + +(* The main section *) +Section Six. + +Variables (gT : finGroupType) (G : {group gT}). +Implicit Types H K L M : {group gT}. + +(* Grouping lemmas that assume Hypothesis (6.1). *) +Section GeneralCoherence. + +Variables K L : {group gT}. +Local Notation S M := (seqIndD K L K M). +Local Notation calS := (S 1). + +Variables (R : 'CF(L) -> seq 'CF(G)) (tau : {linear 'CF(L) -> 'CF(G)}). + +(* These may need to be grouped, in order to make the proofs of 6.8, 10.10, *) +(* and 12.6 more manageable. *) +Hypotheses (nsKL : K <| L) (solK : solvable K). +Hypothesis Itau : {in 'Z[calS, L^#] &, isometry tau}. +Hypothesis scohS : subcoherent calS tau R. + +Let sKL : K \subset L. Proof. exact: normal_sub. Qed. +Let nKL : L \subset 'N(K). Proof. exact: normal_norm. Qed. +Let orthS: pairwise_orthogonal calS. Proof. by case: scohS. Qed. +Let sSS M : {subset S M <= calS}. Proof. exact: seqInd_sub. Qed. +Let ccS M : conjC_closed (S M). Proof. exact: cfAut_seqInd. Qed. +Let uniqS M : uniq (S M). Proof. exact: seqInd_uniq. Qed. +Let nrS : ~~ has cfReal calS. Proof. by case: scohS => [[]]. Qed. + +Lemma exists_linInd M : + M \proper K -> M <| K -> exists2 phi, phi \in S M & phi 1%g = #|L : K|%:R. +Proof. +move=> ltMK nsMK; have [sMK nMK] := andP nsMK. +have ntKM: (K / M)%g != 1%g by rewrite -subG1 quotient_sub1 // proper_subn. +have [r /andP[_ r1] ntr] := solvable_has_lin_char ntKM (quotient_sol M solK). +exists ('Ind[L, K] ('chi_r %% M)%CF); last first. + by rewrite cfInd1 // cfModE // morph1 (eqP r1) mulr1. +apply/seqIndP; exists (mod_Iirr r); last by rewrite mod_IirrE. +rewrite !inE subGcfker mod_IirrE ?cfker_mod //= andbT. +apply: contraNneq ntr => /(canRL (mod_IirrK nsMK))->. +by rewrite quo_IirrE // irr0 ?cfker_cfun1 ?cfQuo_cfun1. +Qed. + +(* This is Peterfalvi (6.2). *) +Lemma coherent_seqIndD_bound (A B C D : {group gT}) : + [/\ A <| L, B <| L, C <| L & D <| L] -> + (*a*) [/\ A \proper K, B \subset D, D \subset C, C \subset K + & D / B \subset 'Z(C / B)]%g -> + (*b1*) coherent (S A) L^# tau -> + (*b2*) coherent (S B) L^# tau + \/ #|K : A|%:R - 1 <= 2%:R * #|L : C|%:R * sqrtC #|C : D|%:R. +Proof. +move=> [nsAL nsBL nsCL nsDL] [ltAK sBD sDC sCK sDbZC] cohA. +have [|not_ineq] := boolP (_ <= _); [by right | left]. +have sBC := subset_trans sBD sDC; have sBK := subset_trans sBC sCK. +have [sAK nsBK] := (proper_sub ltAK, normalS sBK sKL nsBL). +have{sBC} [nsAK nsBC] := (normalS sAK sKL nsAL, normalS sBC sCK nsBK). +pose wf S1 := [/\ uniq S1, {subset S1 <= calS} & conjC_closed S1]. +pose S1 := [::] ++ S A; set S2 := [::] in S1; rewrite -[S A]/S1 in cohA. +have wfS1: wf S1 by split; [apply: uniqS | apply: sSS | apply: ccS]. +move: {2}_.+1 (ltnSn (size calS - size S1)) => n. +elim: n => // n IHn in (S2) S1 wfS1 cohA *; rewrite ltnS => leSnS1. +have [uniqS1 sS1S ccS1] := wfS1. +have [sAB1 | /allPn[psi /= SBpsi notS1psi]] := altP (@allP _ (mem S1) (S B)). + by apply: subset_coherent cohA. +have [neq_psi_c SBpsic] := (hasPn nrS _ (sSS SBpsi), ccS SBpsi). +have wfS1': wf [:: psi, psi^* & S1]%CF. + split=> [|xi|xi]; rewrite /= !inE 1?andbC. + - rewrite negb_or eq_sym neq_psi_c notS1psi uniqS1 (contra (ccS1 _)) //. + by rewrite cfConjCK. + - by case/predU1P=> [|/predU1P[|/sS1S]] -> //; rewrite (@sSS B). + do 2![case/predU1P=> [-> |]; first by rewrite ?cfConjCK eqxx ?orbT // eq_sym]. + by move/ccS1=> ->; rewrite !orbT. +apply: (IHn [:: psi, psi^* & S2]%CF) => //; last first. + rewrite -subSn ?uniq_leq_size //; try by case: wfS1'. + by rewrite /= subSS (leq_trans _ leSnS1) // leq_sub2l ?leqW. +have [phi SAphi phi1] := exists_linInd ltAK nsAK. +have: [/\ phi \in S1, psi \in calS & psi \notin S1]. + by rewrite mem_cat SAphi orbT (@sSS B). +have /seqIndP[i /setDP[kBi _] def_psi] := SBpsi; rewrite inE in kBi. +move/(extend_coherent scohS); apply; rewrite // {phi SAphi}phi1; split=> //. + by rewrite def_psi cfInd1 // dvdC_mulr // CintE Cnat_irr1. +have Spos xi: xi \in calS -> 0 <= xi 1%g by move/Cnat_seqInd1/Cnat_ge0. +rewrite big_cat sum_seqIndD_square //= -subr_gt0 -addrA ltr_paddl //=. + rewrite big_seq sumr_ge0 // => xi S2xi. + by rewrite !mulr_ge0 ?invr_ge0 ?cfnorm_ge0 ?Spos ?sS1S // mem_cat S2xi. +rewrite mulrC -mulrBl pmulr_rgt0 ?gt0CiG // subr_gt0. +rewrite real_ltrNge ?rpredB ?rpredM ?rpred_nat ?rpred1 //; last first. + by rewrite realE Spos ?(sSS SBpsi). +apply: contra not_ineq => /ler_trans-> //. +rewrite -mulrA ler_pmul2l ?ltr0n // def_psi cfInd1 //. +rewrite -(Lagrange_index sKL sCK) natrM -mulrA ler_pmul2l ?gt0CiG //. +exact: irr1_bound_quo sDbZC. +Qed. + +(* This is Peterfalvi, Theorem (6.3). *) +Theorem bounded_seqIndD_coherent M H H1 : + [/\ M <| L, H <| L & H1 <| L] -> + [/\ M \subset H1, H1 \subset H & H \subset K] -> + (*a*) nilpotent (H / M)%g -> + (*b*) coherent (S H1) L^# tau -> + (*c*) (#|H : H1| > 4 * #|L : K| ^ 2 + 1)%N -> + coherent (S M) L^# tau. +Proof. +move: H1 => A [nsML nsHL nsAL] [sMA sAH sHK] nilHb cohA lbHA. +elim: {A}_.+1 {-2}A (ltnSn #|A|) => // m IHm A leAm in nsAL sMA sAH cohA lbHA *. +have [/group_inj-> // | ltMA] := eqVproper sMA; have [sAL nAL] := andP nsAL. +have{ltMA} [B maxB sMB]: {B : {group gT} | maxnormal B A L & M \subset B}. + by apply: maxgroup_exists; rewrite ltMA normal_norm. +have /andP[ltBA nBL] := maxgroupp maxB; have [sBA not_sAB] := andP ltBA. +have [sBH sBL] := (subset_trans sBA sAH, subset_trans sBA sAL). +have nsBL: B <| L by apply/andP. +suffices{m IHm leAm} cohB: coherent (S B) L^# tau. + apply: IHm cohB _ => //; first exact: leq_trans (proper_card ltBA) _. + by rewrite (leq_trans lbHA) // dvdn_leq // indexgS. +have /andP[sHL nHL] := nsHL. +have sAbZH: (A / B \subset 'Z(H / B))%g. + have nBA := subset_trans sAL nBL; have nsBA : B <| A by apply/andP. + have minBb: minnormal (A / B)%g (L / B)%g. + apply/mingroupP; split=> [|Db /andP[ntDb nDLb] sDAb]. + by rewrite -subG1 quotient_sub1 // not_sAB quotient_norms. + have: Db <| (L / B)%g by rewrite /normal (subset_trans sDAb) ?quotientS. + case/(inv_quotientN nsBL)=> D defDb sBD /andP[sDL nDL]. + apply: contraNeq ntDb => neqDAb; rewrite defDb quotientS1 //. + case/maxgroupP: maxB => /= _ /(_ D) {1}<- //. + rewrite -(quotient_proper (normalS sBD sDL nsBL)) // -defDb. + by rewrite properEneq sDAb neqDAb. + apply/setIidPl; case/mingroupP: minBb => /andP[ntAb nALb]. + apply; rewrite ?subsetIl //. + have nZHb := char_norm_trans (center_char (H / B)) (quotient_norms _ nHL). + rewrite andbC normsI //= meet_center_nil //=; last first. + by rewrite quotient_normal // (normalS sAH sHL). + suffices /homgP[f /= <-]: (H / B)%g \homg (H / M)%g by rewrite morphim_nil. + by apply: homg_quotientS; rewrite ?(subset_trans sHL) ?normal_norm. +have [defA | ltAH] := eqVproper sAH. + by rewrite addn1 defA indexgg in lbHA. +have [sAK ltAK] := (subset_trans sAH sHK, proper_sub_trans ltAH sHK). +case: (@coherent_seqIndD_bound A B H A) => // /idPn[]. +apply: contraL lbHA; rewrite -ltnNge -ltC_nat -(Lagrange_index sHK sAH) natrM. +set x := #|H : A|%:R => ub_x. +have nz_x2: sqrtC x != 0 by rewrite sqrtC_eq0 neq0CiG. +have x2_gt0: 0 < sqrtC x by rewrite ltr_def nz_x2 sqrtC_ge0 ler0n. +have{ub_x}: sqrtC x - (sqrtC x)^-1 <= (2 * #|L : K|)%:R. + rewrite -(ler_pmul2r (gt0CiG K H)) -natrM -mulnA Lagrange_index //. + rewrite natrM -(ler_pmul2r x2_gt0) mulrC mulrBl mulrBr. + rewrite !mulrA -expr2 sqrtCK divff // (ler_trans _ ub_x) // mulrC. + by rewrite ler_add2l ler_opp2 mul1r ler1n. +rewrite -(@ler_pexpn2r _ 2) -?topredE /= ?ler0n //; last first. + rewrite subr_ge0 -(ler_pmul2r x2_gt0) -expr2 mulVf // sqrtCK. + by rewrite ler1n. +rewrite -natrX expnMn -(ler_add2r 2%:R) -addnS natrD. +apply: ltr_le_trans; rewrite sqrrB // exprVn sqrtCK divff //. +by rewrite addrAC subrK addrC -subr_gt0 addrK invr_gt0 gt0CiG. +Qed. + +(* This is the statement of Peterfalvi, Hypothesis (6.4). *) +Definition odd_Frobenius_quotient M (H1 := K^`(1) <*> M) := + [/\ (*a*) odd #|L|, + (*b*) [/\ M <| L, M \subset K & nilpotent (K / M)] + & (*c*) [Frobenius L / H1 with kernel K / H1] ]%g. + +(* This is Peterfalvi (6.5). *) +Lemma non_coherent_chief M (H1 := (K^`(1) <*> M)%G) : + odd_Frobenius_quotient M -> + coherent (S M) L^# tau +\/ [/\ (*a*) chief_factor L H1 K /\ (#|K : H1| <= 4 * #|L : K| ^ 2 + 1)%N + & (*b*) exists2 p : nat, p.-group (K / M)%g /\ ~~ abelian (K / M)%g + & (*c*) ~~ (#|L : K| %| p - 1)]. +Proof. +case=> oddL [nsML sMK nilKb]; rewrite /= -(erefl (gval H1)) => frobLb. +set e := #|L : K|; have odd_e: odd e := dvdn_odd (dvdn_indexg L K) oddL. +have{odd_e} mod1e_lb m: (odd m -> m > 1 -> m == 1 %[mod e] -> 2 * e + 1 <= m)%N. + move=> odd_m m_gt1; rewrite eqn_mod_dvd ?(ltnW m_gt1) //. + rewrite -[m]odd_double_half odd_m subn1 /= -mul2n addn1 ltnS leq_pmul2l //. + rewrite Gauss_dvdr; last by rewrite coprime_sym prime_coprime // dvdn2 odd_e. + by apply: dvdn_leq; rewrite -(subnKC m_gt1). +have nsH1L: H1 <| L by rewrite normalY // (char_normal_trans (der_char 1 K)). +have sH1K: H1 \subset K by rewrite join_subG der_sub. +have cohH1: coherent (S H1) L^# tau. + apply: uniform_degree_coherence (subset_subcoherent scohS _) _ => //. + apply/(@all_pred1_constant _ #|L : K|%:R)/allP=> _ /mapP[chi Schi ->] /=. + have [i /setIdP[_]] := seqIndP Schi; rewrite inE join_subG -lin_irr_der1. + by do 2![case/andP]=> _ /eqP chi1 _ ->; rewrite cfInd1 // chi1 mulr1. +have sMH1: M \subset H1 by apply: joing_subr. +have [ubK | lbK] := leqP; last by left; apply: bounded_seqIndD_coherent lbK. +have{ubK} ubK: (#|K : H1| < (2 * e + 1) ^ 2)%N. + rewrite sqrnD expnMn (leq_ltn_trans ubK) // -subn_gt0 addKn. + by rewrite !muln_gt0 indexg_gt0. +have [-> | neqMH1] := eqVneq M H1; [by left | right]. +have{neqMH1} ltMH1: M \proper H1 by rewrite properEneq neqMH1. +have{frobLb} [[E1b frobLb] [sH1L nH1L]] := (existsP frobLb, andP nsH1L). +have [defLb ntKb _ _ /andP[sE1L _]] := Frobenius_context frobLb. +have nH1K: K \subset 'N(H1) := subset_trans sKL nH1L. +have chiefH1: chief_factor L H1 K. + have ltH1K: H1 \proper K by rewrite /proper sH1K -quotient_sub1 ?subG1. + rewrite /chief_factor nsKL andbT; apply/maxgroupP; rewrite ltH1K. + split=> // H2 /andP[ltH2K nH2L] sH12; have sH2K := proper_sub ltH2K. + have /eqVproper[// | ltH21] := sH12; case/idPn: ubK; rewrite -leqNgt. + have dv_e H3: H1 \subset H3 -> H3 \subset K -> L \subset 'N(H3) -> + #|H3 : H1| == 1 %[mod e]. + - move=> sH13 sH3K nH3L; rewrite eqn_mod_dvd // subn1. + rewrite /e -(index_quotient_eq _ sKL nH1L) ?subIset ?sH1K ?orbT //. + rewrite -[#|_ : _|]divgS ?quotientS // -(sdprod_card defLb) mulKn //. + rewrite -card_quotient ?(subset_trans (subset_trans sH3K sKL)) //. + rewrite regular_norm_dvd_pred ?(subset_trans sE1L) ?quotient_norms //. + apply: semiregular_sym; apply: sub_in1 (Frobenius_reg_compl frobLb). + by apply/subsetP; rewrite setSD ?quotientS. + have dv_H21 := dv_e H2 sH12 sH2K nH2L. + have dv_KH2: #|K : H2| == 1 %[mod e]. + have:= dv_e K sH1K (subxx K) nKL; rewrite -(Lagrange_index sH2K sH12). + by rewrite -modnMmr (eqP dv_H21) modnMmr muln1. + have odd_iK := dvdn_odd (dvdn_indexg _ _) (oddSg (subset_trans _ sKL) oddL). + have iK_gt1 H3 H4: H4 \proper H3 -> (#|H3 : H4| > 1)%N. + by rewrite indexg_gt1 => /andP[]. + by rewrite -(Lagrange_index sH2K sH12) leq_mul ?mod1e_lb ?odd_iK ?iK_gt1. +split=> //; have nMK := subset_trans sKL (normal_norm nsML). +have not_abKb: ~~ abelian (K / M). + apply: contra (proper_subn ltMH1) => /derG1P/trivgP. + rewrite /= join_subG subxx andbT -quotient_der ?quotient_sub1 //. + exact: subset_trans (der_sub 1 K) nMK. +have /is_abelemP[p p_pr /and3P[pKb _ _]]: is_abelem (K / H1)%g. + have: solvable (K / H1)%g by apply: quotient_sol solK. + by case/(minnormal_solvable (chief_factor_minnormal chiefH1)). +have [_ p_dv_Kb _] := pgroup_pdiv pKb ntKb. +have iso3M := third_isog sMH1 (normalS sMK sKL nsML) (normalS sH1K sKL nsH1L). +have pKM: p.-group (K / M)%g. + have /dprodP[_ defKM cKMpp' tiKMpp'] := nilpotent_pcoreC p nilKb. + rewrite -defKM (eqP (forall_inP (nilpotent_sol nilKb) 'O_p^'(_)%G _)). + by rewrite mulg1 pcore_pgroup. + have /isomP[inj_quo im_quo] := quotient_isom (cents_norm cKMpp') tiKMpp'. + rewrite subsetI pcore_sub /= -(injmSK inj_quo) // (morphim_der _ 1) //. + rewrite {inj_quo}im_quo /= -[Q in Q^`(1)%g]quotientMidl defKM. + rewrite -quotient_der ?gFnorm ?quotientS //. + rewrite -quotient_sub1 ?(subset_trans (pcore_sub _ _) (der_norm _ _)) //. + rewrite -[(_ / _)%g]setIid coprime_TIg //. + apply: pnat_coprime (quotient_pgroup _ (pcore_pgroup _ _)). + apply: pgroupS (quotientS _ (pcore_sub _ _)) _. + rewrite /= -quotient_der // -(quotientYidr (subset_trans (der_sub 1 K) nMK)). + by rewrite (isog_pgroup _ iso3M) ?(normalS sMK sKL nsML). +exists p => //; apply: contra not_abKb => e_dv_p1. +rewrite cyclic_abelian // Phi_quotient_cyclic //. +have /homgP[f <-]: (K / M / 'Phi(K / M) \homg K / H1)%g. + apply: homg_trans (isog_hom iso3M). + rewrite homg_quotientS ?gFnorm ?quotient_norms //=. + rewrite quotientYidr ?(subset_trans (der_sub 1 K)) // quotient_der //. + by rewrite (Phi_joing pKM) joing_subl. +rewrite {f}morphim_cyclic // abelian_rank1_cyclic; last first. + by rewrite sub_der1_abelian ?joing_subl. +rewrite (rank_pgroup pKb) (leq_trans (p_rank_le_logn _ _)) //. +rewrite -ltnS -(ltn_exp2l _ _ (prime_gt1 p_pr)) -p_part part_pnat_id //. +rewrite card_quotient // (leq_trans ubK) // leq_exp2r //. +have odd_p: odd p := dvdn_odd p_dv_Kb (quotient_odd _ (oddSg sKL oddL)). +by rewrite mod1e_lb // ?eqn_mod_dvd ?prime_gt0 ?prime_gt1. +Qed. + +(* This is Peterfalvi (6.6). *) +Lemma seqIndD_irr_coherence (Z : {group gT}) (calX := seqIndD K L Z 1) : + odd_Frobenius_quotient 1%G -> + [/\ Z <| L, Z :!=: 1 & Z \subset 'Z(K)]%g -> + {subset calX <= irr L} -> + calX =i [pred chi in irr L | ~~ (Z \subset cfker chi)] + /\ coherent calX L^#tau. +Proof. +move=> Frob_quo1 [nsZL ntZ sZ_ZK] irrX; have [sZL nZL] := andP nsZL. +have abZ: abelian Z by rewrite (abelianS sZ_ZK) ?center_abelian. +have /andP[sZK nZK]: Z <| K := sub_center_normal sZ_ZK. +split=> [chi|]. + apply/idP/andP=> [Xchi | [/irrP[r ->{chi}] nkerZr]]. + rewrite irrX //; case/seqIndP: Xchi => t /setIdP[nkerZt _] ->. + by rewrite inE in nkerZt; rewrite sub_cfker_Ind_irr. + have [t Res_r_t] := neq0_has_constt (Res_irr_neq0 K r). + pose chi := 'Ind[L] 'chi_t; have chi_r: '[chi, 'chi_r] != 0. + by rewrite -cfdot_Res_r cfdotC fmorph_eq0 -irr_consttE. + have Xchi: chi \in calX. + apply/seqIndP; exists t; rewrite // !inE sub1G andbT. + rewrite -(sub_cfker_Ind_irr t sKL nZL). + apply: contra nkerZr => /subset_trans-> //. + by rewrite cfker_constt // cfInd_char ?irr_char //. + case/irrX/irrP: Xchi chi_r (Xchi) => r' ->. + by rewrite cfdot_irr pnatr_eq0 -lt0n; case: eqP => // ->. +have [|[]] := non_coherent_chief Frob_quo1. + by apply: subset_coherent; apply: seqInd_sub. +have [oddL _] := Frob_quo1; rewrite /= joingG1 => frobLb _ [p []]. +set e := #|L : K|; have e_gt0: (e > 0)%N by apply: indexg_gt0. +have isoK1 := isog_symr (quotient1_isog K). +rewrite (isog_abelian isoK1) {isoK1}(isog_pgroup _ isoK1). +have [-> | ntK pK _ not_e_dv_p1] := eqsVneq K [1]; first by rewrite abelian1. +have{ntK} [p_pr p_dv_K _] := pgroup_pdiv pK ntK. +set Y := calX; pose d (xi : 'CF(L)) := logn p (truncC (xi 1%g) %/ e). +have: conjC_closed Y by apply: cfAut_seqInd. +have: perm_eq (Y ++ [::]) calX by rewrite cats0. +have: {in Y & [::], forall xi1 xi2, d xi1 <= d xi2}%N by []. +elim: {Y}_.+1 {-2}Y [::] (ltnSn (size Y)) => // m IHm Y X' leYm leYX' defX ccY. +have sYX: {subset Y <= calX}. + by move=> xi Yxi; rewrite -(perm_eq_mem defX) mem_cat Yxi. +have sX'X: {subset X' <= calX}. + by move=> xi X'xi; rewrite -(perm_eq_mem defX) mem_cat X'xi orbT. +have uniqY: uniq Y. + have: uniq calX := seqInd_uniq L _. + by rewrite -(perm_eq_uniq defX) cat_uniq => /and3P[]. +have sYS: {subset Y <= calS} by move=> xi /sYX/seqInd_sub->. +case homoY: (constant [seq xi 1%g | xi : 'CF(L) <- Y]). + exact: uniform_degree_coherence (subset_subcoherent scohS _) homoY. +have Ndg: {in calX, forall xi : 'CF(L), xi 1%g = (e * p ^ d xi)%:R}. + rewrite /d => _ /seqIndP[i _ ->]; rewrite cfInd1 // -/e. + have:= dvd_irr1_cardG i; have /CnatP[n ->] := Cnat_irr1 i. + rewrite -natrM natCK dvdC_nat mulKn // -p_part => dv_n_K. + by rewrite part_pnat_id // (pnat_dvd dv_n_K). +have [chi Ychi leYchi]: {chi | chi \in Y & {in Y, forall xi, d xi <= d chi}%N}. + have [/eqP/nilP Y0 | ntY] := posnP (size Y); first by rewrite Y0 in homoY. + pose i := [arg max_(i > Ordinal ntY) d Y`_i]. + exists Y`_i; [exact: mem_nth | rewrite {}/i; case: arg_maxP => //= i _ max_i]. + by move=> _ /(nthP 0)[j ltj <-]; apply: (max_i (Ordinal ltj)). +have{homoY} /hasP[xi1 Yxi1 lt_xi1_chi]: has (fun xi => d xi < d chi)%N Y. + apply: contraFT homoY => geYchi; apply: (@all_pred1_constant _ (chi 1%g)). + rewrite all_map; apply/allP=> xi Yxi; rewrite /= !Ndg ?sYX // eqr_nat. + rewrite eqn_pmul2l // eqn_exp2l ?prime_gt1 //. + by rewrite eqn_leq leYchi //= leqNgt (hasPn geYchi). +pose Y' := rem chi^*%CF (rem chi Y); pose X'' := [:: chi, chi^*%CF & X']. +have ccY': conjC_closed Y'. + move=> xi; rewrite !(inE, mem_rem_uniq) ?rem_uniq //. + by rewrite !(inv_eq (@cfConjCK _ _)) cfConjCK => /and3P[-> -> /ccY->]. +have Xchi := sYX _ Ychi; have defY: perm_eq [:: chi, chi^*%CF & Y'] Y. + rewrite (perm_eqrP (perm_to_rem Ychi)) perm_cons perm_eq_sym perm_to_rem //. + by rewrite mem_rem_uniq ?inE ?ccY // (seqInd_conjC_neq _ _ _ Xchi). +apply: perm_eq_coherent (defY) _. +have d_chic: d chi^*%CF = d chi. + by rewrite /d cfunE conj_Cnat // (Cnat_seqInd1 Xchi). +have /andP[uniqY' Y'x1]: uniq Y' && (xi1 \in Y'). + rewrite !(inE, mem_rem_uniq) ?rem_uniq // Yxi1 andbT -negb_or. + by apply: contraL lt_xi1_chi => /pred2P[] ->; rewrite ?d_chic ltnn. +have xi1P: [/\ xi1 \in Y', chi \in calS & chi \notin Y']. + by rewrite Y'x1 sYS ?(inE, mem_rem_uniq) ?rem_uniq // eqxx andbF. +have sY'Y: {subset Y' <= Y} by move=> xi /mem_rem/mem_rem. +apply: (extend_coherent scohS) xi1P _; first by split=> // xi /sY'Y/sYS. +have{defX} defX: perm_eq (Y' ++ X'') calX. + by rewrite (perm_catCA Y' [::_; _]) catA -(perm_eqrP defX) perm_cat2r. +have{d_chic} le_chi_X'': {in X'', forall xi, d chi <= d xi}%N. + by move=> xi /or3P[/eqP-> | /eqP-> | /leYX'->] //; rewrite d_chic. +rewrite !Ndg ?sYX // dvdC_nat dvdn_pmul2l // dvdn_exp2l 1?ltnW //; split=> //. + apply: IHm defX ccY' => [|xi xi' /sY'Y/leYchi le_xi_chi /le_chi_X'']. + by rewrite -ltnS // (leq_trans _ leYm) // -(perm_eq_size defY) ltnW. + exact: leq_trans. +have pos_p n: (0 < p ^ n)%N by rewrite expn_gt0 prime_gt0. +rewrite -!natrM; apply: (@ltr_le_trans _ (e ^ 2 * (p ^ d chi) ^ 2)%:R). + rewrite ltr_nat -expnMn -mulnn mulnAC !mulnA 2?ltn_pmul2r //. + rewrite -mulnA mulnCA ltn_pmul2l // -(subnK lt_xi1_chi) addnS expnS. + rewrite expnD mulnA ltn_pmul2r // -(muln1 3) leq_mul //. + rewrite ltn_neqAle prime_gt1 // eq_sym (sameP eqP (prime_oddPn p_pr)). + by rewrite (dvdn_odd p_dv_K) // (oddSg sKL). +have [r] := seqIndP (sYX _ Ychi); rewrite !inE => /andP[nkerZr _] def_chi. +have d_r: 'chi_r 1%g = (p ^ d chi)%:R. + by apply: (mulfI (neq0CiG L K)); rewrite -cfInd1 // -def_chi -natrM Ndg. +pose sum_p2d S := (\sum_(xi <- S) p ^ (d xi * 2))%N. +pose sum_xi1 (S : seq 'CF(L)) := \sum_(xi <- S) xi 1%g ^+ 2 / '[xi]. +have def_sum_xi1 S: {subset S <= calX} -> sum_xi1 S = (e ^ 2 * sum_p2d S)%:R. + move=> sSX; rewrite big_distrr natr_sum /=; apply: eq_big_seq => xi /sSX Xxi. + rewrite expnM -expnMn natrX -Ndg //. + by have /irrP[i ->] := irrX _ Xxi; rewrite cfnorm_irr divr1. +rewrite -/(sum_xi1 _) def_sum_xi1 ?leC_nat 1?dvdn_leq => [|||_ /sY'Y/sYX] //. + by rewrite muln_gt0 expn_gt0 e_gt0 [_ Y'](bigD1_seq xi1) //= addn_gt0 pos_p. +have coep: coprime e p. + have:= Frobenius_ker_coprime frobLb; rewrite coprime_sym. + have /andP[_ nK'L] := char_normal_trans (der_char 1 K) nsKL. + rewrite index_quotient_eq ?subIset ?der_sub ?orbT {nK'L}// -/e. + have ntKb: (K / K^`(1))%g != 1%g by case/Frobenius_kerP: frobLb. + have [_ _ [k ->]] := pgroup_pdiv (quotient_pgroup _ pK) ntKb. + by rewrite coprime_pexpr. +rewrite -expnM Gauss_dvd ?coprime_expl ?coprime_expr {coep}// dvdn_mulr //=. +have /dvdn_addl <-: p ^ (d chi * 2) %| e ^ 2 * sum_p2d X''. + rewrite big_distrr big_seq dvdn_sum //= => xi /le_chi_X'' le_chi_xi. + by rewrite dvdn_mull // dvdn_exp2l ?leq_pmul2r. +rewrite -mulnDr -big_cat (eq_big_perm _ defX) -(natCK (e ^ 2 * _)) /=. +rewrite -def_sum_xi1 // /sum_xi1 sum_seqIndD_square ?normal1 ?sub1G //. +rewrite indexg1 -(natrB _ (cardG_gt0 Z)) -natrM natCK. +rewrite -(Lagrange_index sKL sZK) mulnAC dvdn_mull //. +have /p_natP[k defKZ]: p.-nat #|K : Z| by rewrite (pnat_dvd (dvdn_indexg K Z)). +rewrite defKZ dvdn_exp2l // -(leq_exp2l _ _ (prime_gt1 p_pr)) -{k}defKZ. +rewrite -leC_nat expnM natrX -d_r ?(ler_trans (irr1_bound r).1) //. +rewrite ler_nat dvdn_leq ?indexgS ?(subset_trans sZ_ZK) //=. +by rewrite -cap_cfcenter_irr bigcap_inf. +Qed. + +End GeneralCoherence. + +(* This is Peterfalvi (6.7). *) +(* In (6.8) we only know initially the P is Sylow in L; perhaps the lemma *) +(* should be stated with this equivalent (but weaker) assumption. *) +Lemma constant_irr_mod_TI_Sylow (Z L P : {group gT}) p i : + p.-Sylow(G) P -> odd #|L| -> normedTI P^# G L -> + [/\ Z <| L, Z :!=: 1%g & Z \subset 'Z(P)] -> + {in Z^# &, forall x y, #|'C_L[x]| = #|'C_L[y]| } -> + let phi := 'chi[G]_i in + {in Z^# &, forall x y, phi x = phi y} -> + {in Z^#, forall x, phi x \in Cint /\ (#|P| %| phi x - phi 1%g)%C}. +Proof. +move=> sylP oddL tiP [/andP[sZL nZL] ntZ sZ_ZP] prZL; move: i. +pose a := @gring_classM_coef _ G; pose C (i : 'I_#|classes G|) := enum_val i. +have [[sPG pP p'PiG] [sZP cPZ]] := (and3P sylP, subsetIP sZ_ZP). +have [ntP sLG memJ_P1] := normedTI_memJ_P tiP; rewrite setD_eq0 subG1 in ntP. +have nsPL: P <| L. + by have [_ _ /eqP<-] := and3P tiP; rewrite normD1 normal_subnorm. +have [p_pr _ [e oP]] := pgroup_pdiv pP ntP. +have [sZG [sPL _]] := (subset_trans sZP sPG, andP nsPL). +pose dC i (A : {set gT}) := [disjoint C i & A]. +have actsGC i: {acts G, on C i | 'J}. + apply/actsP; rewrite astabsJ /C; have /imsetP[x _ ->] := enum_valP i. + by apply/normsP; apply: classGidr. +have{actsGC} PdvKa i j s: + ~~ dC i Z^# -> ~~ dC j Z^# -> dC s Z -> (#|P| %| a i j s * #|C s|)%N. +- pose Omega := [set uv in [predX C i & C j] | mulgm uv \in C s]%g. + pose to_fn uv x := prod_curry (fun u v : gT => (u ^ x, v ^ x)%g) uv. + have toAct: is_action setT to_fn. + by apply: is_total_action => [[u v]|[u v] x y] /=; rewrite ?conjg1 ?conjgM. + move=> Zi Zj Z's; pose to := Action toAct. + have actsPO: [acts P, on Omega | to]. + apply/(subset_trans sPG)/subsetP=> x Gx; rewrite !inE. + apply/subsetP=> [[u v] /setIdP[/andP/=[Ciu Cjv] Csuv]]. + by rewrite !inE /= -conjMg !actsGC // Ciu Cjv. + have <-: #|Omega| = (a i j s * #|C s|)%N. + have /repr_classesP[_ defCs] := enum_valP s; rewrite -/(C s) in defCs. + rewrite -sum1_card mulnC -sum_nat_const. + rewrite (partition_big mulgm (mem (C s))) => [|[u v] /setIdP[]//]. + apply: eq_bigr; rewrite /= defCs => _ /imsetP[z Gz ->]. + rewrite -[a i j s]sum1_card -!/(C _) (reindex_inj (act_inj to z)) /=. + apply: eq_bigl => [[u v]]; rewrite !inE /= -conjMg (inj_eq (conjg_inj _)). + by apply: andb_id2r => /eqP->; rewrite {2}defCs mem_imset ?andbT ?actsGC. + suffices regPO: {in Omega, forall uv, 'C_P[uv | to] = 1%g}. + rewrite -(acts_sum_card_orbit actsPO) dvdn_sum // => _ /imsetP[uv Ouv ->]. + by rewrite card_orbit regPO // indexg1. + case=> u v /setIdP[/andP[/= Ciu Cjv] Csuv]; apply: contraTeq Z's. + case/trivgPn=> x /setIP[Px /astab1P[/= cux cvx]] nt_x. + suffices inZ k y: y \in C k -> ~~ dC k Z^# -> y ^ x = y -> y \in Z. + apply/exists_inP; exists (u * v)%g => //=. + by rewrite groupM // (inZ i u, inZ j v). + rewrite /dC /C; have /imsetP[_ _ ->{k} /class_transr <-] := enum_valP k. + case/exists_inP=> _ /imsetP[g Gg ->] /setD1P[nt_yg Zyg] yx. + have xy: (x ^ y = x)%g by rewrite /conjg (conjgCV x) -{2}yx conjgK mulKg. + rewrite -(memJ_conjg _ g) (normsP nZL) //. + rewrite -(memJ_P1 y) ?inE //=; first by rewrite nt_yg (subsetP sZP). + rewrite -order_eq1 -(orderJ y g) order_eq1 nt_yg. + rewrite (mem_normal_Hall (pHall_subl sPL sLG sylP)) //. + by rewrite -(p_eltJ _ _ g) (mem_p_elt pP) ?(subsetP sZP). + rewrite -(memJ_P1 x) // ?xy ?inE ?nt_x // -[y](conjgK g) groupJ ?groupV //. + by rewrite (subsetP sZG). +pose a2 i j := (\sum_(s | ~~ dC s Z^#) a i j s)%N. +pose kerZ l := {in Z^# &, forall x y, 'chi[G]_l x = 'chi_l y}. +move=> l phi kerZl z Z1z; move: l @phi {kerZl}(kerZl : kerZ l). +have [ntz Zz] := setD1P Z1z. +have [[Pz Lz] Gz] := (subsetP sZP z Zz, subsetP sZL z Zz, subsetP sZG z Zz). +pose inC y Gy := enum_rank_in (@mem_classes _ y G Gy) (y ^: G). +have CE y Gy: C (inC y Gy) = y ^: G by rewrite /C enum_rankK_in ?mem_classes. +pose i0 := inC _ (group1 G); pose i1 := inC z Gz; pose i2 := inC _ (groupVr Gz). +suffices Ea2 l (phi := 'chi[G]_l): + kerZ l -> (phi z *+ a2 i1 i1 == phi 1%g + phi z *+ a2 i1 i2 %[mod #|P|])%A. +- move=> l phi kerZphi. + have Zphi1: phi 1%g \in Cint by rewrite irr1_degree rpred_nat. + have chi0 x: x \in Z -> 'chi[G]_0 x = 1. + by rewrite irr0 cfun1E => /(subsetP sZG) ->. + have: kerZ 0 by move=> x y /setD1P[_ Zx] /setD1P[_ Zy]; rewrite !chi0. + move/Ea2/(eqAmodMl (Aint_irr l z)); rewrite !{}chi0 // -/phi eqAmod_sym. + rewrite mulrDr mulr1 !mulr_natr => /eqAmod_trans/(_ (Ea2 l kerZphi)). + rewrite eqAmodDr -/phi eqAmod_rat ?rpred_nat ?(rpred_Cint _ Zphi1) //. + move=> PdvDphi; split; rewrite // -[phi z](subrK (phi 1%g)) rpredD //. + by have /dvdCP[b Zb ->] := PdvDphi; rewrite rpredM ?rpred_nat. + have nz_Z1: #|Z^#|%:R != 0 :> algC. + by rewrite pnatr_eq0 cards_eq0 setD_eq0 subG1. + rewrite -[phi z](mulfK nz_Z1) rpred_div ?rpred_nat // mulr_natr. + rewrite -(rpredDl _ (rpred_Cint _ Zphi1)) //. + rewrite -[_ + _](mulVKf (neq0CG Z)) rpredM ?rpred_nat //. + have: '['Res[Z] phi, 'chi_0] \in Crat. + by rewrite rpred_Cnat ?Cnat_cfdot_char ?cfRes_char ?irr_char. + rewrite irr0 cfdotE (big_setD1 _ (group1 Z)) cfun1E cfResE ?group1 //=. + rewrite rmorph1 mulr1; congr (_ * (_ + _) \in Crat). + rewrite -sumr_const; apply: eq_bigr => x Z1x; have [_ Zx] := setD1P Z1x. + by rewrite cfun1E cfResE ?Zx // rmorph1 mulr1; apply: kerZphi. +move=> kerZphi; pose alpha := 'omega_l['K_i1]; pose phi1 := phi 1%g. +have tiZG: {in Z^#, forall y, 'C_G[y] \subset L}. + move=> y /setD1P[nty /(subsetP sZP)Py]. + apply/subsetP=> u /setIP[Gu /cent1P cuy]. + by rewrite -(memJ_P1 y) // /conjg -?cuy ?mulKg !inE nty. +have Dalpha s: ~~ dC s Z^# -> alpha = 'omega_l['K_s]. + case/exists_inP=> x /= /gring_mode_class_sum_eq-> Z1x. + have Ci1z: z \in C i1 by rewrite CE class_refl. + rewrite [alpha](gring_mode_class_sum_eq _ Ci1z) -/phi (kerZphi z x) //. + have{tiZG} tiZG: {in Z^#, forall y, 'C_G[y] = 'C_L[y]}. + by move=> y /tiZG/setIidPr; rewrite setIA (setIidPl sLG). + by rewrite -!index_cent1 -!divgS ?subsetIl //= !tiZG ?(prZL z x). +have Ci01: 1%g \in C i0 by rewrite CE class_refl. +have rCi10: repr (C i0) = 1%g by rewrite CE class1G repr_set1. +have Dalpha2 i j: ~~ dC i Z^# -> ~~ dC j Z^# -> + (phi1 * alpha ^+ 2 == phi1 * ((a i j i0)%:R + alpha *+ a2 i j) %[mod #|P|])%A. +- move=> Z1i Z1j. + have ->: phi1 * alpha ^+ 2 = \sum_s (phi1 *+ a i j s) * 'omega_l['K_s]. + rewrite expr2 {1}(Dalpha i Z1i) (Dalpha j Z1j). + rewrite -gring_irr_modeM ?gring_class_sum_central //. + rewrite gring_classM_expansion raddf_sum mulr_sumr; apply: eq_bigr => s _. + by rewrite scaler_nat raddfMn mulrnAl mulrnAr. + rewrite (bigID (fun s => dC s Z^#)) (bigD1 i0) //=; last first. + by rewrite [dC _ _]disjoints_subset CE class1G sub1set !inE eqxx. + rewrite (gring_mode_class_sum_eq _ Ci01) mulfK ?irr1_neq0 //. + rewrite class1G cards1 mulr1 mulrDr mulr_natr -addrA eqAmodDl. + rewrite /eqAmod -addrA rpredD //; last first. + rewrite -mulr_natr natr_sum !mulr_sumr -sumrB rpred_sum // => s Z1s. + by rewrite -Dalpha // mulr_natr mulrnAl mulrnAr subrr rpred0. + apply: rpred_sum => // s /andP[Z1'Cs ntCs]; rewrite mulrnAl mulrC. + have /imsetP[x _ defCs] := enum_valP s. + have Cs_x: x \in C s by rewrite /C defCs class_refl. + rewrite (gring_mode_class_sum_eq _ Cs_x) divfK ?irr1_neq0 // -defCs -/(C s). + rewrite -mulrnAl -mulrnA mulnC -[_%:R]subr0 mulrBl. + apply: eqAmodMr; first exact: Aint_irr. + rewrite eqAmod0_rat ?rpred_nat // dvdC_nat PdvKa //. + rewrite -(setD1K (group1 Z)) [dC _ _]disjoint_sym disjoints_subset. + rewrite subUset sub1set inE -disjoints_subset disjoint_sym. + rewrite (contra _ ntCs) // [C s]defCs => /class_transr. + by rewrite -(inj_eq enum_val_inj) defCs -/(C _) CE => ->. +have zG'z1: (z^-1 \notin z ^: G)%g. + have genL2 y: y \in L -> <[y]> = <[y ^+ 2]>. + move=> Ly; apply/eqP; rewrite [_ == _]generator_coprime. + by rewrite coprime_sym prime_coprime // dvdn2 (oddSg _ oddL) ?cycle_subG. + apply: contra (ntz) => /imsetP[y Gy zy]. + have cz_y2: (y ^+ 2 \in 'C[z])%g. + by rewrite !inE conjg_set1 conjgM -zy conjVg -zy invgK. + rewrite -cycle_eq1 genL2 // cycle_eq1 -eq_invg_mul zy (sameP eqP conjg_fixP). + rewrite (sameP commgP cent1P) cent1C -cycle_subG genL2 ?cycle_subG //. + by rewrite -(memJ_P1 z) -?zy ?in_setD ?groupV ?inE ?ntz. +have a110: a i1 i1 i0 = 0%N. + apply: contraNeq zG'z1 => /existsP[[u v] /setIdP[/andP[/=]]]. + rewrite rCi10 -!/(C _) !CE -eq_invg_mul => /imsetP[x Gx ->] /class_transr <-. + by move/eqP <-; rewrite -conjVg classGidl ?class_refl. +have a120: a i1 i2 i0 = #|C i1|. + rewrite -(card_imset _ (@can_inj _ _ (fun y => (y, y^-1)%g) (@fst _ _) _)) //. + apply/eq_card=> [[u v]]; rewrite !inE rCi10 -eq_invg_mul -!/(C _) !CE -andbA. + apply/and3P/imsetP=> /= [[zGu _ /eqP<-] | [y zGy [-> ->]]]; first by exists u. + by rewrite classVg inE invgK. +have Z1i1: ~~ dC i1 Z^#. + by apply/exists_inP; exists z; rewrite //= CE class_refl. +have Z1i2: ~~ dC i2 Z^#. + apply/exists_inP; exists z^-1%g; first by rewrite /= CE class_refl. + by rewrite /= in_setD !groupV !inE ntz. +have{Dalpha2}: (phi1 * (alpha *+ a2 i1 i1) + == phi1 * (#|C i1|%:R + alpha *+ a2 i1 i2) %[mod #|P|])%A. +- rewrite -a120; apply: eqAmod_trans (Dalpha2 i1 i2 Z1i1 Z1i2). + by have:= Dalpha2 _ _ Z1i1 Z1i1; rewrite a110 add0r eqAmod_sym. +rewrite mulrDr !mulrnAr mulr1 -/phi1. +have ->: phi1 * alpha = phi z *+ #|C i1|. + have Ci1z: z \in C i1 by rewrite CE class_refl. + rewrite [alpha](gring_mode_class_sum_eq _ Ci1z) mulrC divfK ?irr1_neq0 //. + by rewrite mulr_natl CE. +rewrite -!mulrnA !(mulnC #|C _|) !mulrnA -mulrnDl. +have [|r _ /dvdnP[q Dqr]] := @Bezoutl #|C i1| #|P|. + by rewrite CE -index_cent1. +have Zq: q%:R \in Aint by apply: rpred_nat. +move/(eqAmodMr Zq); rewrite ![_ *+ #|C _| * _]mulrnAl -!mulrnAr -mulrnA -Dqr. +have /eqnP->: coprime #|C i1| #|P|. + rewrite (p'nat_coprime _ pP) // (pnat_dvd _ p'PiG) // CE -index_cent1. + by rewrite indexgS // subsetI sPG sub_cent1 (subsetP cPZ). +rewrite add1n !mulrS !mulrDr !mulr1 natrM !mulrA. +set u := _ * r%:R; set v := _ * r%:R; rewrite -[u](subrK v) mulrDl addrA. +rewrite eqAmodDr; apply: eqAmod_trans; rewrite eqAmod_sym addrC. +rewrite eqAmod_addl_mul // -mulrBl mulr_natr. +by rewrite !(rpredB, rpredD, rpredMn, Aint_irr). +Qed. + +(* This is Peterfalvi, Theorem (6.8). *) +(* We omit the semi-direct structure of L in assumption (a), since it is *) +(* implied by our statement of assumption (c). *) +Theorem Sibley_coherence (L H W1 : {group gT}) : + (*a*) [/\ odd #|L|, nilpotent H & normedTI H^# G L] -> + (*b*) let calS := seqIndD H L H 1 in let tau := 'Ind[G, L] in + (*c*) [\/ (*c1*) [Frobenius L = H ><| W1] + | (*c2*) exists2 W2 : {group gT}, prime #|W2| /\ W2 \subset H^`(1)%G + & exists A0, exists W : {group gT}, exists defW : W1 \x W2 = W, + prime_Dade_hypothesis G L H H H^# A0 defW] -> + coherent calS L^# tau. +Proof. +set A := H^# => [][oddL nilH tiA] S tau structL. +set case_c1 := [Frobenius L = H ><| W1] in structL. +have sLG: L \subset G by have [_ _ /eqP <-] := and3P tiA; apply: subsetIl. +have [defL ntH ntW1]: [/\ H ><| W1 = L, H :!=: 1 & W1 :!=: 1]%g. + have [/Frobenius_context[]// | [W2 _ [A0 [W [defW []]]]]] := structL. + by move=> _ [[-> -> _ _] [ntW2 /subG1_contra->]]. +have [nsHL _ /mulG_sub[sHL sW1L] _ _] := sdprod_context defL. +have [uccS nrS]: cfConjC_subset S S /\ ~~ has cfReal S. + by do 2?split; rewrite ?seqInd_uniq ?seqInd_notReal //; apply: cfAut_seqInd. +have defZS: 'Z[S, L^#] =i 'Z[S, A] by apply: zcharD1_seqInd. +have c1_irr: case_c1 -> {subset S <= irr L}. + move/FrobeniusWker=> frobL _ /seqIndC1P[i nz_i ->]. + exact: irr_induced_Frobenius_ker. +move defW2: 'C_H(W1)%G => W2; move defW: (W1 <*> W2)%G => W. +have{defW} defW: W1 \x W2 = W. + rewrite -defW dprodEY // -defW2 ?subsetIr // setICA setIA. + by have [_ _ _ ->] := sdprodP defL; rewrite setI1g. +pose V := cyclicTIset defW; pose A0 := A :|: class_support V L. +pose c2hyp := prime_Dade_hypothesis G L H H A A0 defW. +have c1W2: case_c1 -> W2 = 1%G by move/Frobenius_trivg_cent/group_inj <-. +have{structL} c2W2: ~~ case_c1 -> [/\ prime #|W2|, W2 \subset H^`(1)%G & c2hyp]. + case: structL => [-> // | [W20 [prW20 sW20H'] W20hyp] _]. + have{W20hyp} [A00 [W0 [defW0 W20hyp]]] := W20hyp. + suffices /group_inj defW20: W2 :=: W20. + have eqW0: W0 = W by apply: group_inj; rewrite -defW0 -defW20. + rewrite -defW20 eqW0 in prW20 sW20H' defW0 W20hyp; split=> //. + rewrite /c2hyp (eq_irrelevance defW defW0) /A0. + by have [_ _ <-] := prDade_def W20hyp. + have [[_ _ _ cycW1] [_ _ _ prW120] _] := prDade_prTI W20hyp. + have [x defW1] := cyclicP cycW1; rewrite -defW2 /= defW1 cent_cycle prW120 //. + by rewrite !inE defW1 cycle_id -cycle_eq1 -defW1 ntW1. +have{c2W2} [prW2 sW2H' c2W2] := all_and3 c2W2. +have{sW2H'} sW2H': W2 \subset H^`(1)%G. + by have [/c1W2-> | /sW2H'//] := boolP case_c1; apply: sub1G. +pose sigma := cyclicTIiso (c2W2 _). +have [R scohS oRW]: exists2 R, subcoherent S tau R & forall c2 : ~~ case_c1, + {in [predI S & irr L] & irr W, forall phi w, orthogonal (R phi) (sigma c2 w)}. +- have sAG: A \subset G^# by rewrite setSD // (subset_trans (normal_sub nsHL)). + have Itau: {in 'Z[S, L^#], isometry tau, to 'Z[irr G, G^#]}. + split=> [xi1 xi2 | xi]. + rewrite !defZS => /zchar_on Axi1 /zchar_on Axi2. + exact: normedTI_isometry Axi1 Axi2. + rewrite !zcharD1E => /andP[Zxi /eqP xi1_0]. + rewrite cfInd1 // xi1_0 mulr0 eqxx cfInd_vchar //. + by apply: zchar_trans_on Zxi; apply: seqInd_vcharW. + have [/= Hc1 | Hc2] := boolP (idfun case_c1). + suffices [R]: {R | subcoherent S tau R} by exists R => // /negP[]. + by apply: irr_subcoherent => //; first by case: uccS (c1_irr Hc1). + have ddA0 := c2W2 Hc2. + have [R [subcohR oRW _]] := prDade_subcoherent ddA0 uccS nrS. + exists R => [|not_c1 phi w irrSphi irr_w]; last first. + by rewrite /sigma -(cycTIiso_irrel ddA0) oRW. + set tau0 := Dade _ in subcohR. + have Dtau: {in 'CF(L, A), tau =1 tau0}. + have nAL: L \subset 'N(A) by rewrite normD1 normal_norm. + move=> phi Aphi; rewrite /tau0 -(restr_DadeE ddA0 (subsetUl _ _) nAL) //. + by rewrite /restr_Dade Dade_Ind. + have [Sok _ oSS Rok oRR] := subcohR; split=> // phi Sphi. + have [ZR oNR <-] := Rok _ Sphi; split=> //. + by rewrite Dtau ?irr_vchar_on ?sub_conjC_vchar ?(seqInd_vchar nsHL Sphi). +have [nsH'H nsH'L] := (der_normal 1 H, char_normal_trans (der_char 1 H) nsHL). +have [nH'L solH] := (normal_norm nsH'L, nilpotent_sol nilH). +have ltH'H: H^`(1)%g \proper H by rewrite ?(nil_comm_properl nilH) ?subsetIidl. +have coHW1: coprime #|H| #|W1|. + have [/Frobenius_coprime// | /c2W2[_ [[_ _]]]] := boolP case_c1. + by rewrite (coprime_sdprod_Hall_r defL). +have oW1: #|W1| = #|L : H| by rewrite -divgS // -(sdprod_card defL) mulKn. +have frobL1: [Frobenius L / H^`(1) = (H / H^`(1)) ><| (W1 / H^`(1))]%g. + apply: (Frobenius_coprime_quotient defL nsH'L) => //; split=> // x W1x. + have [/Frobenius_reg_ker-> //|] := boolP case_c1; first exact: sub1G. + by case/c2W2=> _ [_ [_ _ _ ->]]. +have odd_frobL1: odd_Frobenius_quotient H L 1. + have ? := FrobeniusWker frobL1. + by split=> //=; rewrite ?joingG1 // normal1 sub1G quotient_nil. +without loss [/p_groupP[p p_pr pH] not_cHH]: / p_group H /\ ~~ abelian H. + have [//| [_] [p []]] := non_coherent_chief nsHL solH scohS odd_frobL1. + rewrite (isog_abelian (quotient1_isog H)) -(isog_pgroup p (quotient1_isog H)). + by move=> /pgroup_p-> -> _; apply. +have sylH: p.-Sylow(G) H. (* required for (6.7) *) + have sylH: p.-Sylow(L) H. + apply/and3P; split=> //; rewrite -oW1 p'natE // -prime_coprime //. + by case/pgroup_pdiv: pH coHW1 => // _ _ [m ->]; rewrite coprime_pexpl. + have [P sylP sHP] := Sylow_superset (subset_trans sHL sLG) pH. + have [sPG pP _] := and3P sylP; have nilP := pgroup_nil pP. + rewrite -(nilpotent_sub_norm nilP sHP) // (sub_normal_Hall sylH) //. + exact: pgroupS (subsetIl P _) pP. + by have [_ _ /eqP <-] := and3P tiA; rewrite normD1 setSI. +pose caseA := 'Z(H) :&: W2 == [1]. +have caseB_P: ~~ caseA -> [/\ ~~ case_c1, W2 :!=: [1] & W2 \subset 'Z(H)]. + rewrite /caseA; have [-> |] := eqsVneq W2 [1]; first by rewrite setIg1 eqxx. + have [/c1W2->/eqP[]// | /prW2 pW2 ->] := boolP case_c1. + by rewrite setIC => /prime_meetG->. +pose Z := if caseA then ('Z(H) :&: H^`(1))%G else W2. +have /subsetIP[sZZ sZH']: Z \subset 'Z(H) :&: H^`(1)%g. + by rewrite /Z; case: ifPn => // /caseB_P[/c2W2[]] *; apply/subsetIP. +have caseB_cZL: ~~ caseA -> Z \subset 'Z(L). + move=> inB; have [_ _ /subsetIP[sW2H cW2H]] := caseB_P inB. + have [_ mulHW1 _ _] := sdprodP defL. + rewrite /Z (negPf inB) subsetI (subset_trans sW2H) //. + by rewrite -mulHW1 centM subsetI cW2H -defW2 subsetIr. +have nsZL: Z <| L. + have [inA | /caseB_cZL/sub_center_normal//] := boolP caseA. + by rewrite /Z inA (char_normal_trans _ nsHL) // charI ?gFchar. +have ntZ: Z :!=: 1%g. + rewrite /Z; case: ifPn => [_ | /caseB_P[]//]. + by rewrite /= setIC meet_center_nil // (sameP eqP derG1P). +have nsZH := sub_center_normal sZZ; have [sZH nZH] := andP nsZH. +have regZL: {in Z^# &, forall x y, #|'C_L[x]| = #|'C_L[y]| }. + have [inA | /caseB_cZL cZL] := boolP caseA; last first. + suffices defC x: x \in Z^# -> 'C_L[x] = L by move=> x y /defC-> /defC->. + by case/setD1P=> _ /(subsetP cZL)/setIP[_]; rewrite -sub_cent1 => /setIidPl. + suffices defC x: x \in Z^# -> 'C_L[x] = H by move=> x y /defC-> /defC->. + case/setD1P=> ntx Zx; have /setIP[Hx cHx] := subsetP sZZ x Zx. + have [_ <- _ _] := sdprodP defL; rewrite -group_modl ?sub_cent1 //=. + suffices ->: 'C_W1[x] = 1%g by rewrite mulg1. + have [/Frobenius_reg_compl-> // | in_c2] := boolP case_c1; first exact/setD1P. + have [_ [_ [_ _ _ regW1] _] _ _] := c2W2 in_c2. + apply: contraNeq ntx => /trivgPn[y /setIP[W1y cxy] nty]. + rewrite -in_set1 -set1gE -((_ =P [1]) inA) -(regW1 y) 2!inE ?nty //. + by rewrite inE cent1C cHx Hx. +have Zconst_modH := + constant_irr_mod_TI_Sylow sylH oddL tiA (And3 nsZL ntZ sZZ) regZL. +pose X := seqIndD H L Z 1; pose Y := seqIndD H L H H^`(1). +have ccsXS: cfConjC_subset X S by apply: seqInd_conjC_subset1. +have ccsYS: cfConjC_subset Y S by apply: seqInd_conjC_subset1. +have [[uX sXS ccX] [uY sYS ccY]] := (ccsXS, ccsYS). +have X'Y: {subset Y <= [predC X]}. + move=> _ /seqIndP[i /setIdP[_ kH'i] ->]; rewrite inE in kH'i. + by rewrite !inE mem_seqInd ?normal1 // !inE sub1G (subset_trans sZH'). +have irrY: {subset Y <= irr L}. + move=> _ /seqIndP[i /setIdP[not_kHi kH'i] ->]; rewrite !inE in not_kHi kH'i. + have kH'iInd: H^`(1)%g \subset cfker ('Ind[L] 'chi_i). + by rewrite sub_cfker_Ind_irr ?normal_norm. + rewrite -(cfQuoK nsH'L kH'iInd) -cfIndQuo // -quo_IirrE //. + set i1 := quo_Iirr _ i; have /irrP[k ->]: 'Ind 'chi_i1 \in irr (L / H^`(1)). + apply: irr_induced_Frobenius_ker; first exact: FrobeniusWker frobL1. + apply: contraNneq not_kHi; rewrite -(quo_IirrK nsH'H kH'i) -/i1 => ->. + by rewrite mod_IirrE // irr0 cfMod_cfun1 ?cfker_cfun1. + by rewrite -mod_IirrE ?mem_irr. +have uniY: {in Y, forall phi : 'CF(L), phi 1%g = #|W1|%:R}. + move=> _ /seqIndP[i /setIdP[_ kH'i] ->]; rewrite inE -lin_irr_der1 in kH'i. + rewrite cfInd1 // -divgS // -(sdprod_card defL) mulKn //. + by case/andP: kH'i => _ /eqP->; rewrite mulr1. +have scohY: subcoherent Y tau R by apply: (subset_subcoherent scohS). +have [tau1 cohY]: coherent Y L^# tau. + apply/(uniform_degree_coherence scohY)/(@all_pred1_constant _ #|W1|%:R). + by apply/allP=> _ /mapP[phi Yphi ->]; rewrite /= uniY. +have [[Itau1 Ztau1] Dtau1] := cohY. +have [eta1 Yeta1]: exists eta1, eta1 \in Y. + pose IY := Iirr_kerD H H H^`(1)%G. + have [IY0 | [j IYj]] := set_0Vmem IY; last first. + by exists ('Ind 'chi_j); apply/seqIndP; exists j. + have /idPn[]: \sum_(j in IY) ('chi_j 1%g) ^+ 2 == 0 by rewrite IY0 big_set0. + rewrite sum_Iirr_kerD_square ?der_sub // indexgg mul1r subr_eq0. + by rewrite pnatr_eq1 indexg_eq1 proper_subn. +have caseA_coh12: caseA -> coherent (X ++ Y) L^# tau. + move=> haveA. + have scohX: subcoherent X tau R by apply: subset_subcoherent ccsXS. + have irrX: {subset X <= irr L}. + have [/c1_irr irrS | in_c2] := boolP case_c1. + move=> phi Xphi; apply: irrS; apply: seqIndS phi Xphi. + by rewrite Iirr_kerDS // (subset_trans sZH') ?der_sub. + move/(_ in_c2) in prW2; have [_ ptiL _ _] := c2W2 in_c2. + have [[_ _ _ cycW1] [ntW2 sW2H cycW2 prW1H] oddW] := ptiL. + have nZL := normal_norm nsZL; have nZW1 := subset_trans sW1L nZL. + have isoW2: (W2 / Z)%g \isog W2. + apply/isog_symr/quotient_isog; first exact: subset_trans sW2H nZH. + by rewrite -(setIidPr sZZ) setIAC ((_ =P [1]) haveA) setI1g. + have [|defWb ptiLZ] := primeTIhyp_quotient ptiL _ sZH nsZL. + by rewrite (isog_eq1 isoW2). + pose Ichi := primeTI_Ires ptiL; pose IchiZ := primeTI_Ires ptiLZ. + have eq_Ichi: codom (fun j1 => mod_Iirr (IchiZ j1)) =i codom Ichi. + apply/subset_cardP. + rewrite !card_codom; last first; try exact: prTIres_inj. + apply: inj_comp (prTIres_inj ptiLZ). + exact: can_inj (mod_IirrK (sub_center_normal sZZ)). + by rewrite !card_ord !NirrE (nclasses_isog isoW2). + apply/subsetP=> _ /codomP[/= j1 ->]. + have [[j2 /irr_inj->] | ] := prTIres_irr_cases ptiL (mod_Iirr (IchiZ j1)). + exact: codom_f. + case=> /idPn[]; rewrite mod_IirrE // cfIndMod // cfInd_prTIres. + apply: contra (prTIred_not_irr ptiLZ j1) => /irrP[ell Dell]. + by rewrite -[_ j1]cfModK // Dell -quo_IirrE ?mem_irr // -Dell cfker_mod. + move=> _ /seqIndP[k /setDP[_ kZ'k] ->]. + have [[j /irr_inj Dk] | [] //] := prTIres_irr_cases ptiL k. + case/negP: kZ'k; have: k \in codom Ichi by rewrite Dk codom_f. + by rewrite -eq_Ichi => /codomP[j1 ->]; rewrite !inE mod_IirrE ?cfker_mod. + have [//|] := seqIndD_irr_coherence nsHL solH scohS odd_frobL1 _ irrX. + rewrite -/X => defX [tau2 cohX]; have [[Itau2 Ztau2] Dtau2] := cohX. + have [xi1 Xxi1 Nd]: + exists2 xi1, xi1 \in X & forall xi, xi \in X -> (xi1 1%g %| xi 1%g)%C. + - pose IX := Iirr_kerD H Z 1%G; have [i0 IXi0]: exists i0, i0 \in IX. + apply/set0Pn; apply: contraNneq ntZ => IX_0. + have: \sum_(i in IX) ('chi_i 1%g) ^+ 2 == 0 by rewrite IX_0 big_set0. + rewrite sum_Iirr_kerD_square ?normal1 ?sub1G // indexg1 mulf_eq0. + by rewrite (negPf (neq0CiG H Z)) subr_eq0 trivg_card1 -eqC_nat. + have:= erefl [arg min_(i < i0 in IX) truncC ('chi_i 1%g)]. + have [//|{i0 IXi0} i1 IXi1 min_i1 _] := arg_minP. + exists ('Ind 'chi_i1); first by apply/seqIndP; exists i1. + move=> _ /seqIndP[i /min_i1 le_i1_i] ->; rewrite !cfInd1 //. + have pHP := p_natP (pnat_dvd _ pH). + move: (dvd_irr1_cardG i1) (dvd_irr1_cardG i) le_i1_i. + rewrite !irr1_degree -!natrM !dvdC_nat => /pHP[m1 ->] /pHP[m ->]. + rewrite !natCK leq_exp2l ?prime_gt1 // => /subnKC <-. + by rewrite expnD mulnA dvdn_mulr. + pose d (xi : 'CF(L)) : algC := (truncC (xi 1%g / xi1 1%g))%:R. + have{Nd} def_d xi: xi \in X -> xi 1%g = d xi * xi1 1%g. + rewrite /d => Xxi; move: Xxi (Nd _ Xxi) => /irrX/irrP[i ->]. + have /irrX/irrP[i1 ->] := Xxi1. + rewrite !irr1_degree dvdC_nat => /dvdnP[q ->]. + by rewrite natrM -irr1_degree mulfK ?irr1_neq0 // natCK. + have d_xi1: d xi1 = 1. + by apply: (mulIf (seqInd1_neq0 nsHL Xxi1)); rewrite mul1r -def_d. + have oXY: orthogonal X Y. + apply/orthogonalP=> xi eta Xxi Yeta; apply: orthoPr xi Xxi. + exact: (subset_ortho_subcoherent scohS sXS (sYS _ Yeta) (X'Y _ Yeta)). + have [_ [Itau Ztau] /orthogonal_free freeS _ _] := scohS. + have o_tauXY: orthogonal (map tau2 X) (map tau1 Y). + exact: (coherent_ortho scohS). + have [a Na Dxi11]: exists2 a, a \in Cnat & xi1 1%g = a * #|W1|%:R. + have [i1 _ ->] := seqIndP Xxi1. + exists ('chi_i1 1%g); first exact: Cnat_irr1. + by rewrite cfInd1 // -divgS // -(sdprod_card defL) ?mulKn // mulrC. + pose psi1 := xi1 - a *: eta1; have Za: a \in Cint by rewrite CintE Na. + have Zpsi1: psi1 \in 'Z[S, L^#]. + rewrite zcharD1E !cfunE (uniY _ Yeta1) -Dxi11 subrr eqxx. + by rewrite rpredB ?scale_zchar ?mem_zchar ?(sXS _ Xxi1) // sYS. + have [Y1 dY1 [X1 [dX1 _ oX1tauY]]] := orthogonal_split (map tau1 Y)(tau psi1). + have oY: orthonormal Y by apply: sub_orthonormal (irr_orthonormal L). + have oYtau: orthonormal (map tau1 Y) by apply: map_orthonormal. + have{dX1 Y1 dY1} [b Zb Dpsi1]: {b | b \in Cint & + tau psi1 = X1 - a *: tau1 eta1 + b *: (\sum_(eta <- Y) tau1 eta)}. + - exists ('[tau psi1, tau1 eta1] + a). + rewrite rpredD // Cint_cfdot_vchar ?Ztau1 ?seqInd_zcharW //. + exact: zcharW (Ztau _ Zpsi1). + rewrite {1}dX1 addrC -addrA; congr (_ + _). + have [_ -> ->] := orthonormal_span oYtau dY1. + rewrite -[Y1](addrK X1) -dX1 big_map !(big_rem eta1 Yeta1) /=. + rewrite cfdotBl (orthoPl oX1tauY) ?map_f // subr0. + rewrite scalerDr addrA; congr (_ + _). + by rewrite addrC -scaleNr -scalerDl addrK. + rewrite raddf_sum; apply: eq_big_seq => eta. + rewrite mem_rem_uniq ?seqInd_uniq // => /andP[eta1'eta /= Yeta]. + congr (_ *: _); rewrite cfdotBl (orthoPl oX1tauY) ?map_f // subr0 addrC. + apply: canRL (subrK _) _; rewrite -2!raddfB /=. + have Zeta: (eta - eta1) \in 'Z[Y, L^#]. + by rewrite zcharD1E rpredB ?seqInd_zcharW //= !cfunE !uniY ?subrr. + rewrite Dtau1 // Itau // ?(zchar_subset sYS) //. + rewrite cfdotBl cfdotZl !cfdotBr 2?(orthogonalP oXY) // subr0 add0r. + have [_ oYY] := orthonormalP oY; rewrite !oYY // eqxx. + by rewrite eq_sym (negPf eta1'eta) add0r mulrN mulr1 opprK. + pose psi := 'Res[L] (tau1 eta1). + have [X2 dX2 [xi' [dxi' _ oxi'X]]] := orthogonal_split X psi. + have oX: orthonormal X by apply: sub_orthonormal (irr_orthonormal L). + have Zpsi: psi \in 'Z[irr L] by rewrite cfRes_vchar ?Ztau1 ?seqInd_zcharW. + pose sumXd := \sum_(xi <- X) d xi *: xi. + have Zxi1Xd xi: xi \in X -> xi - d xi *: xi1 \in 'Z[X, L^#]. + move=> Xxi; rewrite zcharD1E !cfunE -def_d // subrr eqxx. + by rewrite rpredB ?scale_zchar ?seqInd_zcharW ?rpred_nat. + have{dxi' X2 dX2} [c Zc Dpsi]: {c | c \in Cint & psi = c *: sumXd + xi'}. + exists '[psi, xi1]; first by rewrite Cint_cfdot_vchar ?(seqInd_vcharW Xxi1). + rewrite {1}dxi'; congr (_ + _); have [_ -> ->] := orthonormal_span oX dX2. + rewrite -[X2](addrK xi') -dxi' raddf_sum; apply: eq_big_seq => /= xi Xxi. + rewrite cfdotBl (orthoPl oxi'X) // subr0 scalerA; congr (_ *: _). + apply/eqP; rewrite -subr_eq0 mulrC -[d xi]conj_Cnat ?Cnat_nat //. + rewrite -cfdotZr -cfdotBr cfdot_Res_l -Dtau2 ?Zxi1Xd //. + rewrite cfdotC raddfB raddfZ_Cnat ?Cnat_nat // cfdotBl cfdotZl. + by rewrite !(orthogonalP o_tauXY) ?map_f // mulr0 subr0 conjC0. + have Exi' z: z \in Z -> xi' z = xi' 1%g. + move=> Zz; rewrite [xi']cfun_sum_cfdot !sum_cfunE; apply: eq_bigr => ell _. + have [Xell |] := boolP ('chi_ell \in X). + by rewrite !cfunE (orthoPl oxi'X) ?mul0r. + by rewrite !cfunE defX inE /= mem_irr negbK => /subsetP/(_ z Zz)/cfker1->. + have Eba: '[psi, psi1] = b - a. + rewrite cfdot_Res_l -/tau Dpsi1 -addrA !cfdotDr cfdotNr cfdotZr. + rewrite cfdotC (orthoPl oX1tauY) ?map_f // conjC0 add0r addrC. + rewrite cfdotC raddf_sum cfproj_sum_orthonormal // !aut_Cint //. + by have [_ ->] := orthonormalP oYtau; rewrite ?map_f // eqxx mulr1. + have nz_xi11: xi1 1%g != 0 by have /irrX/irrP[i ->] := Xxi1; apply: irr1_neq0. + have {Eba} Ebc: (a %| b - c)%C. + rewrite -[b](subrK a) -Eba cfdotBr {1}Dpsi cfdotDl cfdotZl. + rewrite cfproj_sum_orthonormal // (orthoPl oxi'X) // addr0 d_xi1 mulr1. + rewrite addrC -addrA addKr addrC rpredB ?dvdC_refl //= cfdotZr aut_Cint //. + by rewrite dvdC_mulr // Cint_cfdot_vchar ?(seqInd_vcharW Yeta1). + have DsumXd: sumXd = (xi1 1%g)^-1 *: (cfReg L - (cfReg (L / Z)%g %% Z)%CF). + apply: canRL (scalerK nz_xi11) _; rewrite !cfReg_sum 2!linear_sum /=. + pose F (xi : 'CF(L)) := xi 1%g *: xi; transitivity (\sum_(xi <- X) F xi). + by apply: eq_big_seq => xi Xxi; rewrite scalerA mulrC -def_d. + rewrite (bigID (mem (Iirr_ker L Z))) /=; apply: canRL (addrK _) _. + rewrite addrC; congr (_ + _). + rewrite (eq_bigl _ _ (in_set _)) (reindex _ (mod_Iirr_bij nsZL)) /=. + apply: eq_big => [i | i _]; first by rewrite mod_IirrE ?cfker_mod. + by rewrite linearZ mod_IirrE // cfMod1. + transitivity (\sum_(xi <- [seq 'chi_i | i in [predC Iirr_ker L Z]]) F xi). + apply: eq_big_perm; apply: uniq_perm_eq => // [|xi]. + by rewrite (map_inj_uniq irr_inj) ?enum_uniq. + rewrite defX inE /=; apply/andP/imageP=> [[/irrP[i ->] kerZ'i] | [i]]. + by exists i; rewrite ?inE. + by rewrite !inE => ? ->; rewrite mem_irr. + by rewrite big_map big_filter; apply: eq_bigl => i; rewrite !inE. + have eta1tauZ z: z \in Z^# -> tau1 eta1 z - tau1 eta1 1%g = - c * #|H|%:R / a. + case/setD1P=> ntz Zz; transitivity (psi z - psi 1%g). + by rewrite !cfResE ?(subsetP (normal_sub nsZL)). + rewrite Dpsi DsumXd !cfunE Exi' ?cfuniE ?normal1 // set11 inE (negPf ntz). + rewrite mulr0 mulr1 sub0r Dxi11 cfker1 ?cfker_reg_quo //. + set cc := c * _ + _; rewrite 2!mulrDr -[rhs in _ - rhs]addrA -/cc. + rewrite addrC opprD {cc}subrK -(sdprod_card defL) mulnC natrM. + by rewrite invfM !mulrA divfK ?neq0CG // mulrAC -2!mulNr. + have{eta1tauZ} dvHpsi: (#|H| %| - c * #|H|%:R / a)%C. + have /dirrP[e [i Deta1]]: tau1 eta1 \in dirr G. + rewrite dirrE Ztau1 ?Itau1 ?seqInd_zcharW //=. + by have [_ ->] := orthonormalP oY; rewrite ?eqxx. + have [z ntz Zz] := trivgPn _ ntZ; have Z1z: z \in Z^# by apply/setD1P. + have /(Zconst_modH i)[|_] := Z1z. + move=> z1 z2 Zz1 Zz2; rewrite -(canLR (signrZK e) Deta1) !cfunE. + by apply/eqP; do 2!rewrite eq_sym (canRL (subrK _) (eta1tauZ _ _)) //. + by rewrite -(canLR (signrZK e) Deta1) !cfunE -mulrBr eta1tauZ // rpredMsign. + have nz_a: a != 0 by rewrite Dxi11 mulf_eq0 negb_or neq0CG andbT in nz_xi11. + have{dvHpsi} dv_ac: (a %| c)%C. + move: dvHpsi; rewrite !mulNr mulrAC rpredN => /dvdCP[q Zq]. + by move/(mulIf (neq0CG H))/(canRL (divfK nz_a))->; apply: dvdC_mull. + have{Ebc dv_ac} /dvdCP[q Zq Db]: (a %| b)%C by rewrite -[b](subrK c) rpredD. + pose m : algC := (size Y)%:R. + have Da1: 1 + a ^+ 2 = '[X1] + a ^+ 2 * ((q - 1) ^+ 2 + (m - 1) * q ^+ 2). + transitivity '[psi1]. + rewrite cfnormBd; last by rewrite cfdotZr (orthogonalP oXY) ?mulr0. + rewrite cfnormZ Cint_normK //. + have [[_ -> //] [_ -> //]]:= (orthonormalP oX, orthonormalP oY). + by rewrite !eqxx mulr1. + rewrite -Itau // Dpsi1 -addrA cfnormDd; last first. + rewrite addrC cfdotBr !cfdotZr cfdot_sumr (orthoPl oX1tauY) ?map_f //. + rewrite big_seq big1 ?mulr0 ?subrr // => eta Yeta. + by rewrite (orthoPl oX1tauY) ?map_f //. + congr (_ + _); rewrite cfnormD cfnormN !cfnormZ. + have [_ ->] := orthonormalP oYtau; rewrite ?map_f // eqxx mulr1. + rewrite cfnorm_map_orthonormal // -/m !Cint_normK // cfdotNl cfdotZl. + rewrite linear_sum cfdotC cfproj_sum_orthonormal // rmorphN rmorphM. + rewrite conjCK !aut_Cint // -mulr2n mulNrn -[_ - _]addrAC. + rewrite mulrDr -{1}[m](addNKr 1) mulrDr mulr1 addrA -sqrrB. + congr (_ + _); last by rewrite mulrCA -exprMn (mulrC a) addrC -Db mulrC. + by rewrite -exprMn -sqrrN opprB mulrBr mulr1 (mulrC a) -Db. + have{Da1} maxq: ~~ (2%:R <= (q - 1) ^+ 2 + (m - 1) * q ^+ 2). + have a2_gt1: a ^+ 2 > 1. + have /seqIndP[i1 /setDP[_ not_kerH'i1] Dxi1] := Xxi1. + apply: contraR not_kerH'i1; rewrite inE expr_gt1 ?Cnat_ge0 //. + have [n Da] := CnatP a Na; rewrite Da ltr1n -leqNgt leq_eqVlt. + rewrite ltnNge lt0n -!eqC_nat -{n}Da nz_a orbF => /eqP a_eq1. + rewrite (subset_trans sZH') // -lin_irr_der1 qualifE irr_char. + rewrite -(inj_eq (mulfI (neq0CiG L H))) -cfInd1 // -Dxi1 Dxi11 a_eq1. + by rewrite mul1r mulr1 -divgS //= -(sdprod_card defL) mulKn. + rewrite -(ler_pmul2l (ltr_trans ltr01 a2_gt1)) ltr_geF // mulr_natr. + apply: ler_lt_trans (_ : 1 + a ^+ 2 < _); last by rewrite ltr_add2r. + by rewrite Da1 -subr_ge0 addrK cfnorm_ge0. + clear psi Dpsi Zpsi Zb c sumXd DsumXd Zc xi' Exi' oxi'X. + wlog{Dpsi1 Itau1 Ztau1 Dtau1 oYtau b q maxq Db Zq} Dpsi1: + tau1 cohY o_tauXY oX1tauY / tau psi1 = X1 - a *: tau1 eta1. + - move=> IH; have [q0 | nz_q] := eqVneq q 0. + by apply: (IH tau1) => //; rewrite Dpsi1 Db q0 mul0r scale0r addr0. + have m1_ge1: 1 <= m - 1. + rewrite -(@ler_add2r _ 1) subrK (ler_nat _ 2). + exact: seqInd_nontrivial (irrY _ Yeta1) (Yeta1). + have q1: q = 1. + apply: contraNeq maxq; rewrite -subr_eq0 => nz_q1. + rewrite ler_add // ?sqr_Cint_ge1 ?rpredB //. + rewrite (ler_trans m1_ge1) // -{1}[m - 1]mulr1. + by rewrite ler_pmul2l ?sqr_Cint_ge1 // (ltr_le_trans ltr01). + have szY2: (size Y <= 2)%N. + move: maxq; rewrite q1 subrr exprS mul0r add0r mulrA !mulr1. + by rewrite -(ler_add2r 1) subrK -mulrSr ler_nat -leqNgt. + have defY: perm_eq Y (eta1 :: eta1^*)%CF. + have uYeta: uniq (eta1 :: eta1^*)%CF. + by rewrite /= andbT inE eq_sym; have [[_ /hasPn/=->]] := scohY. + rewrite perm_eq_sym uniq_perm_eq //. + have [|//]:= leq_size_perm uYeta _ szY2. + by apply/allP; rewrite /= Yeta1 ccY. + have memYtau1c: {subset map (tau1 \o cfAut conjC) Y <= map tau1 Y}. + by move=> _ /mapP[eta Yeta ->]; rewrite /= map_f ?ccY. + apply: (IH _ (dual_coherence scohY cohY szY2)). + - rewrite (map_comp -%R) orthogonal_oppr. + by apply/orthogonalP=> phi psi ? /memYtau1c; apply: (orthogonalP o_tauXY). + - rewrite (map_comp -%R) orthogonal_oppr. + by apply/orthoPl=> psi /memYtau1c; apply: (orthoPl oX1tauY). + rewrite Dpsi1 (eq_big_perm _ defY) Db q1 /= mul1r big_cons big_seq1. + by rewrite scalerDr addrA subrK -scalerN opprK. + have [[[Itau1 Ztau1] Dtau1] [_ oXX]] := (cohY, orthonormalP oX). + have n1X1: '[X1] = 1. + apply: (addIr '[a *: tau1 eta1]); rewrite -cfnormBd; last first. + by rewrite cfdotZr (orthoPl oX1tauY) ?mulr0 ?map_f. + rewrite -Dpsi1 Itau // cfnormBd; last first. + by rewrite cfdotZr (orthogonalP oXY) ?mulr0. + by rewrite !cfnormZ Itau1 ?seqInd_zcharW // oXX ?eqxx. + without loss{Itau2 Ztau2 Dtau2} defX1: tau2 cohX o_tauXY / X1 = tau2 xi1. + move=> IH; have ZX: {subset X <= 'Z[X]} by apply: seqInd_zcharW. + have dirrXtau xi: xi \in X -> tau2 xi \in dirr G. + by move=> Xxi; rewrite dirrE Ztau2 1?Itau2 ?ZX //= oXX ?eqxx. + have dirrX1: X1 \in dirr G. + rewrite dirrE n1X1 eqxx -[X1](subrK (a *: tau1 eta1)) -Dpsi1. + rewrite rpredD ?scale_zchar ?(zcharW (Ztau _ _)) //. + by rewrite Ztau1 ?seqInd_zcharW. + have oX1_Xd xi: + xi \in X -> xi != xi1 -> '[d xi *: tau2 xi1 - tau2 xi, X1] = d xi. + - move=> Xxi xi1'xi; have ZXxi := Zxi1Xd xi Xxi. + rewrite -[X1](subrK (a *: tau1 eta1)) -Dpsi1 cfdotDr cfdotZr addrC. + rewrite cfdotBl cfdotZl 2?(orthogonalP o_tauXY) ?map_f //. + rewrite !(mulr0, subr0, conjC0) add0r -{1}raddfZ_Cnat ?Cnat_nat //. + rewrite -opprB cfdotNl -raddfB Dtau2 //. + rewrite Itau //; last exact: zchar_subset ZXxi. + rewrite cfdotBr cfdotZr addrC !cfdotBl !cfdotZl. + rewrite 2?(orthogonalP oXY) // !(mulr0, oppr0, add0r, conjC0). + by rewrite !oXX // eqxx (negPf xi1'xi) add0r opprK mulr1. + have Xxi2: xi1^*%CF \in X by apply: ccX. + have xi1'2: xi1^*%CF != xi1 by have [[_ /hasPn->]] := scohX. + have xi2tau_irr: - tau2 xi1^*%CF \in dirr G by rewrite dirr_opp dirrXtau. + have d_xi2: d xi1^*%CF = 1. + by rewrite /d cfunE conj_Cnat // (Cnat_seqInd1 Xxi1). + have [||def_X1]:= cfdot_add_dirr_eq1 (dirrXtau _ Xxi1) xi2tau_irr dirrX1. + - by rewrite -[tau2 xi1]scale1r -d_xi2 oX1_Xd. + - exact: IH. + have sX_xi12: {subset X <= xi1 :: xi1^*%CF}. + apply/allP/allPn=> [[xi3 Xxi3 /norP[xi1'3 /norP[xi2'3 _]]]]. + suffices d3_0: d xi3 = 0. + by have:= seqInd1_neq0 nsHL Xxi3; rewrite def_d // d3_0 mul0r eqxx. + rewrite -oX1_Xd // def_X1 cfdotNr cfdotBl cfdotZl !Itau2 ?ZX //. + by rewrite !oXX // (negPf xi2'3) eq_sym (negPf xi1'2) mulr0 add0r opprK. + have{sX_xi12 defX} defX: perm_eq X (xi1 :: xi1^*%CF). + have uXxi: uniq (xi1 :: xi1^*)%CF by rewrite /= andbT inE eq_sym. + rewrite perm_eq_sym uniq_perm_eq // => xi. + by apply/idP/idP; [rewrite !inE => /pred2P[]-> | apply: sX_xi12]. + have szX2: (size X <= 2)%N by rewrite (perm_eq_size defX). + apply: (IH _ (dual_coherence scohX cohX szX2)) def_X1. + rewrite (map_comp -%R) orthogonal_oppl. + apply/orthogonalP=> _ eta /mapP[xi Xxi ->]. + by apply: (orthogonalP o_tauXY); rewrite map_f ?ccX. + move: Dpsi1; rewrite -raddfZ_Cnat // defX1. + apply: (bridge_coherent scohS ccsXS cohX ccsYS cohY X'Y). + by rewrite (zchar_on Zpsi1) rpredZ_Cnat ?mem_zchar. +have{caseA_coh12} cohXY: coherent (X ++ Y) L^# tau. + have [/caseA_coh12// | caseB] := boolP caseA. + have defZ: Z = W2 by rewrite /Z (negPf caseB). + have{caseB} [case_c2 _ _] := caseB_P caseB. + move/(_ case_c2) in oRW; pose PtypeL := c2W2 case_c2. + have{prW2} pr_w2 := prW2 case_c2; set w2 := #|W2| in pr_w2. + have /cyclicP[z0 cycZ]: cyclic Z by rewrite defZ prime_cyclic. + have idYZ: {in Y & Z^#, forall (eta : 'CF(L)) x, tau1 eta x = tau1 eta z0}. + move=> eta x Yeta; rewrite !inE andbC cycZ => /andP[/cyclePmin[k]]. + rewrite orderE -cycZ defZ -/w2 => lt_k_w2 -> nt_z0k. + have k_gt0: (0 < k)%N by rewrite lt0n (contraNneq _ nt_z0k) // => ->. + have cokw2: coprime k w2 by rewrite coprime_sym prime_coprime // gtnNdvd. + have sW2G: W2 \subset G by rewrite -defW2 subIset // (subset_trans sHL). + have [u Du _]:= make_pi_cfAut G cokw2. + rewrite -Du ?Ztau1 ?seqInd_zcharW //; last by rewrite orderE -cycZ defZ. + have nAL: L \subset 'N(A) by rewrite normD1 normal_norm. + pose ddA := restr_Dade_hyp PtypeL (subsetUl _ _) nAL. + have cohY_Dade: coherent_with Y L^# (Dade ddA) tau1. + split=> // phi Yphi; rewrite Dtau1 ?Dade_Ind //. + by rewrite (@zchar_on _ _ Y) -?zcharD1_seqInd. + rewrite (cfAut_Dade_coherent cohY_Dade) ?irrY //; last first. + split; last exact: cfAut_seqInd. + exact: seqInd_nontrivial_irr (irrY _ Yeta) (Yeta). + rewrite -[cfAut u _](subrK eta) raddfD cfunE. + apply: canLR (subrK _) _; rewrite subrr. + have [_ ->] := cohY_Dade; last first. + by rewrite -opprB rpredN zcharD1_seqInd // seqInd_sub_aut_zchar. + rewrite Dade_id; last first. + by rewrite !inE -cycle_eq1 -cycle_subG -cycZ ntZ. + rewrite !cfunE cfker1 ?aut_Cnat ?subrr ?(Cnat_seqInd1 Yeta) //. + rewrite -cycle_subG -cycZ (subset_trans sZH') //. + have [j /setDP[kerH'j _] ->] := seqIndP Yeta. + by rewrite inE in kerH'j; rewrite sub_cfker_Ind_irr. + have [_ [Itau _] oSS _ _] := scohS. + have oY: orthonormal Y by apply: sub_orthonormal (irr_orthonormal L). + have oYtau: orthonormal (map tau1 Y) by apply: map_orthonormal. + have oXY: orthogonal X Y. + apply/orthogonalP=> xi eta Xxi Yeta; apply: orthoPr xi Xxi. + exact: (subset_ortho_subcoherent scohS sXS (sYS _ Yeta) (X'Y _ Yeta)). + have [Y1 Dpsi1 defY1]: exists2 Y1, + forall i : Iirr Z, i != 0 -> + exists2 X1 : 'CF(G), orthogonal X1 (map tau1 Y) + & tau ('Ind 'chi_i - #|H : Z|%:R *: eta1) = X1 - #|H : Z|%:R *: Y1 + & Y1 = tau1 eta1 \/ size Y = 2 /\ Y1 = dual_iso tau1 eta1. + - have [i0 nz_i0]: exists i0 : Iirr Z, i0 != 0. + by apply: (ex_intro _ (Sub 1%N _)) => //; rewrite NirrE classes_gt1. + pose psi1 := tau1 eta1; pose b := psi1 z0. + pose a := (psi1 1%g - b) / #|Z|%:R. + have sZL := normal_sub nsZL; have sZG := subset_trans sZL sLG. + have Dpsi1: 'Res psi1 = a *: cfReg Z + b%:A. + apply/cfun_inP=> z Zz. + rewrite cfResE // !cfunE cfun1E Zz mulr1 cfuniE ?normal1 // inE. + have [-> | ntz] := altP eqP; first by rewrite mulr1 divfK ?neq0CG ?subrK. + by rewrite !mulr0 add0r idYZ // !inE ntz. + have /dvdCP[x0 Zx0 Dx0]: (#|H : Z| %| a)%C. + have /dvdCP[x Zx Dx]: (#|H| %| b - psi1 1%g)%C. + have psi1Z z: z \in Z^# -> psi1 z = b. + case/setD1P=> ntz Zz; rewrite -(cfResE _ _ Zz) // Dpsi1 !cfunE cfun1E. + by rewrite cfuniE ?normal1 // Zz inE (negPf ntz) !mulr0 mulr1 add0r. + have /dirrP[e [i /(canLR (signrZK e)) Epsi1]]: psi1 \in dirr G. + have [_ oYt] := orthonormalP oYtau. + by rewrite dirrE oYt ?map_f // !eqxx Ztau1 ?seqInd_zcharW. + have Zz: z0 \in Z^# by rewrite !inE -cycle_eq1 -cycle_subG -cycZ ntZ /=. + have/(Zconst_modH i)[z1 Zz1 z2 Zz2 |_] := Zz. + by rewrite -Epsi1 !cfunE !psi1Z. + by rewrite -Epsi1 !cfunE -mulrBr rpredMsign psi1Z. + apply/dvdCP; exists (- x); first by rewrite rpredN. + rewrite /a -opprB Dx -(Lagrange sZH) mulnC [p in x * p]natrM -!mulNr. + by rewrite !mulrA !mulfK ?neq0CG. + pose x1 := '[eta1, 'Res psi1]; pose x := x0 + 1 - x1. + have Zx: x \in Cint. + rewrite rpredB ?rpredD // Cint_cfdot_vchar // ?(seqInd_vcharW Yeta1) //. + by rewrite cfRes_vchar // Ztau1 ?seqInd_zcharW. + pose Y1 := - \sum_(eta <- Y) (x - (eta == eta1)%:R) *: tau1 eta. + pose alpha i := 'Ind[L, Z] 'chi_i - #|H : Z|%:R *: eta1. + have IZfacts i: i != 0 -> + [/\ 'chi_i 1%g = 1, 'Ind[L, Z] 'chi_i \in 'Z[X] & alpha i \in 'Z[S, L^#]]. + - move=> nzi; have /andP[_ /eqP lin_i]: 'chi_i \is a linear_char. + by rewrite lin_irr_der1 (derG1P _) ?sub1G // cycZ cycle_abelian. + have Xchi: 'Ind 'chi_i \in 'Z[X]. + rewrite -(cfIndInd _ sHL) // ['Ind[H] _]cfun_sum_constt linear_sum. + apply: rpred_sum => k k_i; rewrite linearZ; apply: scale_zchar. + by rewrite Cint_cfdot_vchar_irr // cfInd_vchar ?irr_vchar. + rewrite seqInd_zcharW //; apply/seqIndP; exists k => //. + rewrite !inE sub1G andbT; apply: contra k_i => kerZk. + rewrite -Frobenius_reciprocity. + have ->: 'Res[Z] 'chi_k = ('chi_k 1%g)%:A. + apply: cfun_inP => z Zz; rewrite cfunE cfun1E Zz mulr1 cfResE //. + by rewrite cfker1 ?(subsetP kerZk). + by rewrite cfdotZr -irr0 cfdot_irr (negPf nzi) mulr0. + split=> //; rewrite zcharD1E !cfunE cfInd1 // uniY // lin_i mulr1. + rewrite -divgS // -(sdprod_card defL) -(Lagrange sZH) -mulnA mulKn //. + rewrite -natrM subrr rpredB //=; first by rewrite (zchar_subset sXS). + by rewrite scale_zchar ?rpred_nat // seqInd_zcharW ?sYS. + have Dalpha (i : Iirr Z) (nzi : i != 0) : + exists2 X1 : 'CF(G), orthogonal X1 (map tau1 Y) + & tau (alpha i) = X1 - #|H : Z|%:R *: Y1. + - have [lin_i Xchi Zalpha] := IZfacts i nzi. + have Da: '[tau (alpha i), psi1] = a - #|H : Z|%:R * x1. + rewrite !(=^~ Frobenius_reciprocity, cfdotBl) cfResRes // cfdotZl. + congr (_ - _); rewrite cfdotC Dpsi1 cfdotDl cfdotZl cfReg_sum. + rewrite cfdot_suml (bigD1 i) //= big1 => [|j i'j]; last first. + by rewrite cfdotZl cfdot_irr (negPf i'j) mulr0. + rewrite !cfdotZl cfnorm_irr lin_i addr0 !mulr1. + rewrite -irr0 cfdot_irr eq_sym (negPf nzi) mulr0 addr0. + by rewrite aut_Cint // Dx0 rpredM ?rpred_nat. + have [Y2 dY2 [X1 [dX1 _ oX1Yt]]] := + orthogonal_split (map tau1 Y) (tau (alpha i)). + exists X1 => //; rewrite dX1 addrC scalerN opprK scaler_sumr. + congr (_ + _); have [_ -> ->] := orthonormal_span oYtau dY2. + rewrite big_map; apply: eq_big_seq => eta Yeta. + rewrite scalerA -[Y2](addrK X1) -dX1 cfdotBl (orthoPl oX1Yt) ?map_f //. + congr (_ *: _); rewrite subr0 !mulrBr mulrDr mulrC -Dx0. + rewrite (addrAC a) -Da -addrA -mulrBr addrC; apply: canRL (subrK _) _. + have Zeta: eta - eta1 \in 'Z[Y, L^#]. + by rewrite zcharD1E rpredB ?seqInd_zcharW //= !cfunE !uniY ?subrr. + rewrite -cfdotBr -raddfB Dtau1 // Itau //; last first. + by rewrite (zchar_subset sYS) ?seqInd_free. + rewrite cfdotBl (span_orthogonal oXY) ?(zchar_span Xchi)//; last first. + by rewrite memvB ?memv_span. + have [_ oYY] := orthonormalP oY; rewrite cfdotZl cfdotBr !oYY //. + by rewrite eqxx sub0r -mulrN opprB eq_sym. + exists Y1 => //; have{Dalpha} [X1 oX1Y Dalpha] := Dalpha i0 nz_i0. + have [lin_i Xchi Zalpha] := IZfacts i0 nz_i0. + have norm_alpha: '[tau (alpha i0)] = (#|L : Z| + #|H : Z| ^ 2)%:R. + rewrite natrD Itau // cfnormBd; last first. + rewrite (span_orthogonal oXY) ?(zchar_span Xchi) //. + by rewrite memvZ ?memv_span. + rewrite cfnorm_Ind_irr //; congr (#|_ : _|%:R + _). + apply/setIidPl; apply: subset_trans (cent_sub_inertia _). + rewrite -(sdprodW defL) mulG_subG (centsS sZZ) centsC ?subsetIr //=. + by rewrite defZ -defW2 subsetIr. + have [_ oYY] := orthonormalP oY; rewrite cfnormZ oYY // eqxx mulr1. + by rewrite normCK rmorph_nat -natrM. + have{norm_alpha} ub_norm_alpha: '[tau (alpha i0)] < (#|H : Z| ^ 2).*2%:R. + rewrite norm_alpha -addnn ltr_nat ltn_add2r. + rewrite -divgS // -(sdprod_card defL) -(Lagrange sZH) -mulnA mulKn //. + rewrite ltn_pmul2l //. + have frobL2: [Frobenius L / Z = (H / Z) ><| (W1 / Z)]%g. + apply: (Frobenius_coprime_quotient defL nsZL) => //. + split=> [|y W1y]; first exact: sub_proper_trans ltH'H. + by rewrite defZ; have [/= ? [_ [_ _ _ ->]]] := PtypeL. + have nZW1 := subset_trans sW1L (normal_norm nsZL). + rewrite (card_isog (quotient_isog nZW1 _)); last first. + by rewrite coprime_TIg ?(coprimeSg sZH). + rewrite -(prednK (indexg_gt0 H Z)) ltnS -card_quotient //. + rewrite dvdn_leq ?(Frobenius_dvd_ker1 frobL2) // -subn1 subn_gt0. + by rewrite cardG_gt1; case/Frobenius_context: frobL2. + pose m : algC := (size Y)%:R. + have{ub_norm_alpha} ub_xm: ~~ (2%:R <= (x - 1) ^+ 2 + (m - 1) * x ^+ 2). + have: ~~ (2%:R <= '[Y1]). + rewrite -2!(ler_pmul2l (gt0CiG H Z)) -!natrM mulnA muln2. + rewrite ltr_geF //; apply: ler_lt_trans ub_norm_alpha. + rewrite Dalpha cfnormBd. + by rewrite cfnormZ normCK rmorph_nat mulrA -subr_ge0 addrK cfnorm_ge0. + rewrite scalerN -scaleNr cfdotZr cfdot_sumr big_seq. + rewrite big1 ?mulr0 // => eta Yeta. + by rewrite cfdotZr (orthoPl oX1Y) ?map_f ?mulr0. + rewrite cfnormN cfnorm_sum_orthonormal // (big_rem eta1) //= eqxx. + rewrite big_seq (eq_bigr (fun _ => (x ^+ 2))) => [|eta]; last first. + rewrite mem_rem_uniq // => /andP[/negPf-> _]. + by rewrite subr0 Cint_normK. + rewrite Cint_normK 1?rpredB //= -big_seq; congr (~~ (_ <= _ + _)). + rewrite big_const_seq count_predT // -Monoid.iteropE. + rewrite /m (perm_eq_size (perm_to_rem Yeta1)) /=. + by rewrite mulrSr addrK mulr_natl. + have [x_eq0 | nz_x] := eqVneq x 0. + left; rewrite /Y1 x_eq0 (big_rem eta1) //= eqxx sub0r scaleN1r. + rewrite big_seq big1 => [|eta]; last first. + by rewrite mem_rem_uniq // => /andP[/negPf-> _]; rewrite subrr scale0r. + by rewrite addr0 opprK. + have m1_ge1: 1 <= m - 1. + rewrite -(@ler_add2r _ 1) subrK (ler_nat _ 2). + exact: seqInd_nontrivial (irrY _ Yeta1) (Yeta1). + right; have x_eq1: x = 1. + apply: contraNeq ub_xm; rewrite -subr_eq0 => nz_x1; apply: ler_add. + by rewrite sqr_Cint_ge1 // rpredB. + rewrite (ler_trans m1_ge1) // -{1}[m - 1]mulr1 ler_pmul2l. + exact: sqr_Cint_ge1. + exact: ltr_le_trans ltr01 m1_ge1. + have szY2: size Y = 2. + apply: contraNeq ub_xm => Yneq2; rewrite x_eq1 /m subrr !exprS mul0r. + rewrite add0r !mul1r mulr1 -(ler_add2r 1) subrK -mulrSr ler_nat. + by rewrite ltn_neqAle eq_sym Yneq2 -leC_nat -/m -[m](subrK 1) ler_add2r. + have eta1'2: eta1^*%CF != eta1 by apply: seqInd_conjC_neq Yeta1. + have defY: perm_eq Y (eta1 :: eta1^*%CF). + have uY2: uniq (eta1 :: eta1^*%CF) by rewrite /= inE eq_sym eta1'2. + rewrite perm_eq_sym uniq_perm_eq //. + have sY2Y: {subset (eta1 :: eta1^*%CF) <= Y}. + by apply/allP; rewrite /= cfAut_seqInd ?Yeta1. + by have [|//]:= leq_size_perm uY2 sY2Y; rewrite szY2. + split=> //; congr (- _); rewrite (eq_big_perm _ defY) /= x_eq1. + rewrite big_cons big_seq1 eqxx (negPf eta1'2) subrr scale0r add0r. + by rewrite subr0 scale1r. + have [a Za Dxa]: exists2 a, forall xi, a xi \in Cint + & forall xi, xi \in X -> xi 1%g = a xi * #|W1|%:R + /\ (exists2 X1 : 'CF(G), orthogonal X1 (map tau1 Y) + & tau (xi - a xi *: eta1) = X1 - a xi *: Y1). + - pose aX (xi : 'CF(L)) : algC := (truncC (xi 1%g / #|W1|%:R))%:R. + exists aX => [xi | xi Xxi]; first exact: rpred_nat. + have [k kerZ'k def_xi] := seqIndP Xxi; rewrite !inE sub1G andbT in kerZ'k. + set a := aX xi; have Dxi1: xi 1%g = a * #|W1|%:R. + rewrite /a /aX def_xi cfInd1 // -divgS // -(sdprod_card defL) mulKn //. + by rewrite mulrC mulfK ?neq0CG // irr1_degree natCK. + split=> //; have Da: a = 'chi_k 1%g. + apply: (mulIf (neq0CG W1)); rewrite -Dxi1 def_xi cfInd1 //. + by rewrite mulrC -divgS // -(sdprod_card defL) mulKn. + have [i0 nzi0 Res_k]: exists2 i: Iirr Z, i != 0 & 'Res 'chi_k = a *: 'chi_i. + have [chi /andP[Nchi lin_chi] defRkZ] := cfcenter_Res 'chi_k. + have sZ_Zk: Z \subset 'Z('chi_k)%CF. + by rewrite (subset_trans sZZ) // -cap_cfcenter_irr bigcap_inf. + have{Nchi lin_chi} /irrP[i defRk] : 'Res chi \in irr Z. + by rewrite lin_char_irr // qualifE cfRes_char // cfRes1. + have{chi defRk defRkZ} defRk: 'Res 'chi_k = a *: 'chi_i. + by rewrite -defRk -linearZ -/a Da -defRkZ /= cfResRes ?cfcenter_sub. + exists i => //; apply: contra kerZ'k. + rewrite -subGcfker => /subsetP sZker. + apply/subsetP=> t Zt; rewrite cfkerEirr inE. + by rewrite -!(cfResE _ sZH) // defRk !cfunE cfker1 ?sZker. + set phi := 'chi_i0 in Res_k; pose a_ i := '['Ind[H] phi, 'chi_i]. + pose rp := irr_constt ('Ind[H] phi). + have defIphi: 'Ind phi = \sum_(i in rp) a_ i *: 'chi_i. + exact: cfun_sum_constt. + have a_k: a_ k = a. + by rewrite /a_ -cfdot_Res_r Res_k cfdotZr cfnorm_irr mulr1 rmorph_nat. + have rp_k: k \in rp by rewrite inE ['[_, _]]a_k Da irr1_neq0. + have resZr i: i \in rp -> 'Res[Z] 'chi_i = a_ i *: phi. + move=> r_i; rewrite ['Res _]cfun_sum_cfdot. + rewrite (bigD1 i0) // big1 => /= [|j i0'j]. + rewrite cfdot_Res_l addr0 -/phi cfdotC conj_Cnat //. + by rewrite Cnat_cfdot_char_irr ?cfInd_char ?irr_char. + apply/eqP; rewrite scaler_eq0 cfdot_Res_l. + rewrite -(inj_eq (mulfI r_i)) mulr0 -/(a_ i) -cfdotZl. + have: '['Ind[H] phi, 'Ind[H] 'chi_j] = 0. + apply: not_cfclass_Ind_ortho => //. + have defIj: 'I_H['chi_j] = H. + apply/setIidPl; apply: subset_trans (cent_sub_inertia _). + by rewrite centsC (subset_trans sZZ) ?subsetIr. + rewrite -(congr1 (cfclass _) defIj) cfclass_inertia inE. + by rewrite eq_sym (inj_eq irr_inj). + rewrite defIphi cfdot_suml => /psumr_eq0P-> //; first by rewrite eqxx. + move=> i1 _; rewrite cfdotZl. + by rewrite mulr_ge0 ?Cnat_ge0 ?Cnat_cfdot_char ?cfInd_char ?irr_char. + have lin_phi: phi 1%g = 1. + apply: (mulfI (irr1_neq0 k)); have /resZr/cfunP/(_ 1%g) := rp_k. + by rewrite cfRes1 // cfunE mulr1 a_k Da. + have Da_ i: i \in rp -> 'chi_i 1%g = a_ i. + move/resZr/cfunP/(_ 1%g); rewrite cfRes1 // cfunE => ->. + by rewrite lin_phi mulr1. + pose chi i := 'Ind[L, H] 'chi_i; pose alpha i := chi i - a_ i *: eta1. + have Aalpha i: i \in rp -> alpha i \in 'CF(L, A). + move=> r_i; rewrite cfun_onD1 !cfunE cfInd1 // (uniY _ Yeta1). + rewrite -divgS // -(sdprod_card defL) mulKn // Da_ // mulrC subrr eqxx. + by rewrite memvB ?cfInd_normal ?memvZ // (seqInd_on _ Yeta1). + have [sum_alpha sum_a2]: + 'Ind phi - #|H : Z|%:R *: eta1 = \sum_(i in rp) a_ i *: alpha i + /\ \sum_(i in rp) a_ i ^+ 2 = #|H : Z|%:R. + + set rhs2 := _%:R; set lhs1 := _ - _; set rhs1 := \sum_(i | _) _. + set lhs2 := \sum_(i | _) _. + have eq_diff: lhs1 - rhs1 = (lhs2 - rhs2) *: eta1. + rewrite scalerBl addrAC; congr (_ - _). + rewrite -(cfIndInd _ sHL sZH) defIphi linear_sum -sumrB scaler_suml. + apply: eq_bigr => i rp_i; rewrite linearZ scalerBr opprD addNKr. + by rewrite opprK scalerA. + have: (lhs1 - rhs1) 1%g == 0. + rewrite !cfunE -(cfIndInd _ sHL sZH) !cfInd1 // lin_phi mulr1. + rewrite -divgS // -(sdprod_card defL) mulKn // mulrC uniY // subrr. + rewrite sum_cfunE big1 ?subrr // => i rp_i. + by rewrite cfunE (cfun_on0 (Aalpha i rp_i)) ?mulr0 // !inE eqxx. + rewrite eq_diff cfunE mulf_eq0 subr_eq0 (negPf (seqInd1_neq0 _ Yeta1)) //. + rewrite orbF => /eqP sum_a2; split=> //; apply/eqP; rewrite -subr_eq0. + by rewrite eq_diff sum_a2 subrr scale0r. + have Xchi i: i \in rp -> chi i \in X. + move=> rp_i; apply/seqIndP; exists i => //; rewrite !inE sub1G andbT. + apply: contra rp_i => kerZi; rewrite -cfdot_Res_r. + suffices ->: 'Res[Z] 'chi_i = ('chi_i 1%g)%:A. + by rewrite cfdotZr -irr0 cfdot_irr (negPf nzi0) mulr0. + apply/cfun_inP=> t Zt; rewrite cfResE // cfunE cfun1E Zt mulr1. + by rewrite cfker1 ?(subsetP kerZi). + have oRY i: i \in rp -> orthogonal (R (chi i)) (map tau1 Y). + move/Xchi=> Xchi_i; rewrite orthogonal_sym. + by rewrite (coherent_ortho_supp scohS) // ?sXS // (contraL (X'Y _)). + have n1Y1: '[Y1] = 1. + have [_ oYYt] := orthonormalP oYtau. + have [-> | [_ ->]] := defY1; + by rewrite ?cfnormN oYYt ?eqxx ?map_f // cfAut_seqInd. + have YtauY1: Y1 \in 'Z[map tau1 Y]. + have [-> | [_ ->]] := defY1; + by rewrite ?rpredN mem_zchar ?map_f ?cfAut_seqInd. + have /fin_all_exists[XbZ defXbZ] i: exists XbZ, let: (X1, b, Z1) := XbZ in + [/\ tau (alpha i) = X1 - b *: Y1 + Z1, + i \in rp -> X1 \in 'Z[R (chi i)], i \in rp -> b \is Creal, + '[Z1, Y1] = 0 & i \in rp -> orthogonal Z1 (R (chi i))]. + - have [X1 dX1 [YZ1 [dXYZ _ oYZ1R]]] := + orthogonal_split (R (chi i)) (tau (alpha i)). + have [Y1b dY1b [Z1 [dYZ1 _ oZY1]]] := orthogonal_split Y1 YZ1. + have{dY1b} [|b Db dY1b] := orthogonal_span _ dY1b. + by rewrite /pairwise_orthogonal /= inE eq_sym -cfnorm_eq0 n1Y1 oner_eq0. + exists (X1, - b Y1, Z1); split. + + by rewrite dXYZ dYZ1 dY1b scaleNr big_seq1 opprK addrA. + + have [_ _ _ Rok _] := scohS => /Xchi/sXS/Rok[ZR oRR _]. + have [_ -> ->] := orthonormal_span oRR dX1. + rewrite big_seq rpred_sum // => aa Raa. + rewrite scale_zchar ?mem_zchar //. + rewrite -[X1](addrK YZ1) -dXYZ cfdotBl (orthoPl oYZ1R) // subr0. + rewrite Cint_cfdot_vchar ?(ZR aa) //. + rewrite !(rpredB, cfInd_vchar) ?irr_vchar //. + rewrite scale_zchar ?(seqInd_vcharW Yeta1) // Cint_cfdot_vchar_irr //. + by rewrite cfInd_vchar ?irr_vchar. + + move=> rp_i; rewrite Db -[Y1b](addrK Z1) -dYZ1 cfdotBl (orthoP oZY1). + rewrite subr0 n1Y1 divr1 -[YZ1](addKr X1) -dXYZ cfdotDl cfdotNl. + rewrite (span_orthogonal (oRY i rp_i)) ?(zchar_span YtauY1) //. + rewrite oppr0 add0r Creal_Cint // rpredN Cint_cfdot_vchar //. + rewrite !(cfInd_vchar, rpredB) ?irr_vchar //. + rewrite -Da_ // scale_zchar ?Cint_Cnat ?Cnat_irr1 //. + exact: (seqInd_vcharW Yeta1). + apply: zchar_trans_on YtauY1 => _ /mapP[eta Yeta ->]. + by rewrite Ztau1 ?seqInd_zcharW. + + exact: (orthoP oZY1). + move/oRY=> oRiY; apply/orthoPl=> aa Raa. + rewrite -[Z1](addKr Y1b) -dYZ1 cfdotDl cfdotNl cfdotC (orthoPl oYZ1R) //. + rewrite dY1b addr0 big_seq1 cfdotZr. + by have [-> | [_ ->]] := defY1; + rewrite ?cfdotNr (orthogonalP oRiY) ?map_f ?cfAut_seqInd //; + rewrite ?(oppr0, mulr0, rmorph0). + pose X1 i := (XbZ i).1.1; pose b i := (XbZ i).1.2; pose Z1 i := (XbZ i).2. + have R_X1 i: i \in rp -> X1 i \in 'Z[R (chi i)]. + by rewrite /X1; case: (XbZ i) (defXbZ i) => [[? ?] ?] []. + have Rb i: i \in rp -> b i \is Creal. + by rewrite /b; case: (XbZ i) (defXbZ i) => [[? ?] ?] []. + have oZY1 i: '[Z1 i, Y1] = 0. + by rewrite /Z1; case: (XbZ i) (defXbZ i) => [[? ?] ?] []. + have oZ1R i: i \in rp -> orthogonal (Z1 i) (R (chi i)). + by rewrite /Z1; case: (XbZ i) (defXbZ i) => [[? ?] ?] []. + have{defXbZ} defXbZ i: tau (alpha i) = X1 i - b i *: Y1 + Z1 i. + by rewrite /X1 /b /Z1; case: (XbZ i) (defXbZ i) => [[? ?] ?] []. + have ub_alpha i: i \in rp -> + [/\ '[chi i] <= '[X1 i] + & '[a_ i *: eta1] <= '[b i *: Y1 - Z1 i] -> + [/\ '[X1 i] = '[chi i], '[b i *: Y1 - Z1 i] = '[a_ i *: eta1] + & exists2 E, subseq E (R (chi i)) & X1 i = \sum_(aa <- E) aa]]. + - move=> rp_i; apply: (subcoherent_norm scohS) (erefl _) _. + + rewrite sXS ?Xchi // scale_zchar ?(seqInd_vcharW Yeta1) //; last first. + by rewrite Cint_cfdot_vchar_irr // cfInd_vchar ?irr_vchar. + split=> //; apply/orthoPr=> xi2; rewrite !inE => Dxi2. + rewrite cfdotZr (orthogonalP oXY) ?mulr0 //. + by case/pred2P: Dxi2 => ->; rewrite ?cfAut_seqInd ?Xchi. + + have [_ IZtau _ _ _] := scohS. + apply: sub_iso_to IZtau; [apply: zchar_trans_on | exact: zcharW]. + apply/allP; rewrite /= zchar_split (cfun_onS (setSD _ sHL)) ?Aalpha //. + rewrite rpredB ?scale_zchar ?seqInd_zcharW ?(sYS eta1) ?sXS ?Xchi //. + by rewrite sub_aut_zchar ?zchar_onG ?seqInd_zcharW ?cfAut_seqInd; + rewrite ?sXS ?Xchi //; apply: seqInd_vcharW. + by rewrite -Da_ // irr1_degree rpred_nat. + suffices oYZ_R: orthogonal (b i *: Y1 - Z1 i) (R (chi i)). + rewrite opprD opprK addrA -defXbZ cfdotC. + rewrite (span_orthogonal oYZ_R) ?memv_span1 ?conjC0 //. + exact: (zchar_span (R_X1 i rp_i)). + apply/orthoPl=> aa Raa. + rewrite cfdotBl cfdotZl (orthoPl (oZ1R i _)) //. + by rewrite subr0 cfdotC; have [-> | [_ ->]] := defY1; + rewrite ?cfdotNr (orthogonalP (oRY i _)) ?map_f ?cfAut_seqInd //; + by rewrite ?(mulr0, oppr0, rmorph0). + have leba i: i \in rp -> b i <= a_ i. + move=> rp_i; have ai_gt0: a_ i > 0 by rewrite -Da_ ?irr1_gt0. + have /orP [b_le0|b_ge0] := Rb i rp_i; last first. + by rewrite (ler_trans b_ge0) ?ltrW. + rewrite -(@ler_pexpn2r _ 2) //; last exact: ltrW. + apply: ler_trans (_ : '[b i *: Y1 - Z1 i] <= _). + rewrite cfnormBd; last by rewrite cfdotZl cfdotC oZY1 ?conjC0 ?mulr0. + rewrite cfnormZ (normr_idP _) // n1Y1 mulr1 addrC -subr_ge0 addrK. + exact: cfnorm_ge0. + rewrite -(ler_add2l '[X1 i]) -cfnormBd; last first. + rewrite cfdotBr cfdotZr (span_orthogonal (oRY i _)) //; last first. + - exact: (zchar_span YtauY1). + - exact: (zchar_span (R_X1 i rp_i)). + rewrite mulr0 sub0r cfdotC (span_orthogonal (oZ1R i _)) ?raddf0 //. + exact: memv_span1. + exact: (zchar_span (R_X1 i rp_i)). + have Salpha: alpha i \in 'Z[S, L^#]. + rewrite zchar_split (cfun_onS (setSD _ sHL)) ?Aalpha //. + rewrite rpredB ?scale_zchar ?seqInd_zcharW + ?(sYS _ Yeta1) ?sXS ?Xchi //. + by rewrite -Da_ // irr1_degree rpred_nat. + rewrite opprD opprK addrA -defXbZ // Itau ?Salpha //. + rewrite cfnormBd; last first. + by rewrite cfdotZr (orthogonalP oXY) ?mulr0 ?Xchi. + rewrite cfnormZ (normr_idP _) ?(ltrW ai_gt0) //. + have [_ /(_ eta1)->//] := orthonormalP oY; rewrite eqxx mulr1 ler_add2r. + by have [] := ub_alpha i rp_i. + have{leba} eq_ab: {in rp, a_ =1 b}. + move=> i rp_i; apply/eqP; rewrite -subr_eq0; apply/eqP. + apply: (mulfI (irr1_neq0 i)); rewrite mulr0 Da_ // mulrBr. + move: i rp_i; apply: psumr_eq0P => [i rp_i | ]. + by rewrite subr_ge0 ler_pmul2l ?leba // -Da_ ?irr1_gt0. + have [X2 oX2Y /(congr1 (cfdotr Y1))] := Dpsi1 i0 nzi0. + rewrite sumrB sum_a2 sum_alpha /tau linear_sum /= cfdot_suml cfdotBl. + rewrite (span_orthogonal oX2Y) ?memv_span1 ?(zchar_span YtauY1) // add0r. + rewrite cfdotZl n1Y1 mulr1 => /(canLR (@opprK _)) <-. + rewrite -opprD -big_split big1 ?oppr0 //= => i rp_i. + rewrite linearZ cfdotZl /= -/tau defXbZ addrC cfdotDl oZY1 addr0. + rewrite cfdotBl cfdotZl n1Y1 mulr1. + rewrite (span_orthogonal (oRY i _)) ?(zchar_span YtauY1) //. + by rewrite add0r mulrN subrr. + exact: (zchar_span (R_X1 i rp_i)). + exists (X1 k). + apply/orthoPl=> psi /memv_span Ypsi. + by rewrite (span_orthogonal (oRY k _)) // (zchar_span (R_X1 k rp_k)). + apply/eqP; rewrite -/a def_xi -a_k defXbZ addrC -subr_eq0 eq_ab // addrK. + have n1eta1: '[eta1] = 1 by have [_ -> //] := orthonormalP oY; rewrite eqxx. + rewrite -cfnorm_eq0 -(inj_eq (addrI '[b k *: Y1])). + have [_ [|_]] := ub_alpha k rp_k. + rewrite cfnormBd; last by rewrite cfdotZl cfdotC oZY1 conjC0 mulr0. + by rewrite addrC !cfnormZ eq_ab // n1Y1 n1eta1 -subr_ge0 addrK cfnorm_ge0. + rewrite cfnormBd; last by rewrite cfdotZl cfdotC oZY1 conjC0 mulr0. + by move=> -> _; rewrite addr0 !cfnormZ eq_ab // n1Y1 n1eta1. + have oX: pairwise_orthogonal X by rewrite (sub_pairwise_orthogonal sXS). + have [_ oYY] := orthonormalP oY. + have [[N_S _ _] [_ /(_ _ _)/zcharW/=Ztau] _ _ _] := scohS. + have n1eta: '[eta1] = 1 by rewrite oYY ?eqxx. + have n1Y1: '[Y1] = 1. + have [_ oYYt] := orthonormalP oYtau. + have [-> | [_ ->]] := defY1; + by rewrite ?cfnormN oYYt ?eqxx ?map_f // cfAut_seqInd. + have YtauY1: Y1 \in <<map tau1 Y>>%VS. + by have [-> | [_ ->]] := defY1; + rewrite ?memvN memv_span ?map_f ?cfAut_seqInd. + have Z_Y1: Y1 \in 'Z[irr G]. + by case: defY1 => [|[_]] ->; rewrite ?rpredN Ztau1 ?mem_zchar ?ccY. + have Zalpha xi: xi \in X -> xi - a xi *: eta1 \in 'Z[S, L^#]. + move=> Xxi; rewrite zcharD1E rpredB ?scale_zchar; + rewrite ?seqInd_zcharW ?(sXS xi) ?sYS //. + by rewrite !cfunE (uniY eta1) //= subr_eq0; have [<-] := Dxa xi Xxi. + have Zbeta eta: eta \in Y -> eta - eta1 \in 'Z[S, L^#]. + move=> Yeta; rewrite zcharD1E rpredB ?seqInd_zcharW ?sYS //=. + by rewrite !cfunE !uniY ?subrr. + have nza xi: xi \in X -> a xi != 0. + move=> Xxi; have [/eqP Dxi1 _] := Dxa _ Xxi; apply: contraTneq Dxi1 => ->. + by rewrite mul0r (seqInd1_neq0 _ Xxi). + have alphaY xi: xi \in X -> '[tau (xi - a xi *: eta1), Y1] = - a xi. + case/Dxa=> _ [X1 oX1Y ->]; rewrite cfdotBl cfdotZl n1Y1 mulr1. + by rewrite (span_orthogonal oX1Y) ?memv_span1 ?add0r. + have betaY eta: eta \in Y -> '[tau (eta - eta1), Y1] = (eta == eta1)%:R - 1. + move=> Yeta; rewrite -Dtau1; last first. + by rewrite zchar_split (zchar_on (Zbeta eta _)) ?rpredB ?seqInd_zcharW. + rewrite raddfB cfdotBl. + have [-> | [szY2 ->]] := defY1. + by rewrite !{1}Itau1 ?seqInd_zcharW // !oYY // !eqxx. + rewrite !cfdotNr opprK !{1}Itau1 ?oYY ?seqInd_zcharW ?cfAut_seqInd //. + have defY: (eta1 :: eta1^*)%CF =i Y. + apply: proj1 (leq_size_perm _ _ _); last by rewrite szY2. + by rewrite /= inE eq_sym (seqInd_conjC_neq _ _ _ Yeta1). + by apply/allP; rewrite /= Yeta1 cfAut_seqInd. + rewrite -defY !inE in Yeta; case/pred2P: Yeta => ->. + rewrite eqxx eq_sym (negPf (seqInd_conjC_neq _ _ _ Yeta1)) //. + by rewrite addrC !subrr. + by rewrite eqxx eq_sym (negPf (seqInd_conjC_neq _ _ _ Yeta1)) ?add0r ?addr0. + pose tau2_X xi := tau (xi - a xi *: eta1) + a xi *: Y1. + pose tau3_Y eta := tau (eta - eta1) + Y1. + have Itau2_X: {in X, isometry tau2_X, to 'Z[irr G]}. + split=> [xi1 xi2 Xxi1 Xxi2 | xi Xxi]; last first. + by rewrite rpredD ?rpredZ_Cint ?Za ?Ztau ?Zalpha. + rewrite /= cfdotDl !cfdotDr Itau ?Zalpha // cfdotBl !cfdotBr opprB !cfdotZr. + rewrite !aut_Cint ?Za // !cfdotZl (cfdotC Y1) !alphaY // n1Y1 n1eta rmorphN. + rewrite aut_Cint // (cfdotC eta1) !(orthogonalP oXY _ eta1) // conjC0. + by rewrite !mulr0 !subr0 !mulr1 !mulrN mulrC !addrA subrK addrK. + have{Itau2_X} [tau2 Dtau2 Itau2] := Zisometry_of_iso oX Itau2_X. + have{Itau2} cohX: coherent_with X L^# tau tau2. + split=> // xi; rewrite zcharD1E => /andP[/zchar_expansion[]// z Zz ->{xi}]. + pose sum_za := \sum_(xi <- X) z xi * a xi => /eqP sum_xi_0. + have{sum_xi_0} sum_za_0: sum_za = 0. + apply: (mulIf (neq0CG W1)); rewrite mul0r -{}sum_xi_0 sum_cfunE mulr_suml. + by apply: eq_big_seq => xi /Dxa[xi_1 _]; rewrite !cfunE xi_1 mulrA. + rewrite -[rhs in tau rhs](subrK (sum_za *: eta1)) {1}scaler_suml -sumrB. + rewrite -[tau _](addrK (sum_za *: Y1)) {1 3}sum_za_0 !scale0r addr0 subr0. + rewrite scaler_suml !raddf_sum [tau _]raddf_sum -big_split /= -/tau. + apply: eq_big_seq => xi Xxi; rewrite raddfZ_Cint //= Dtau2 //. + by rewrite -!scalerA -scalerBr [tau _]linearZ -scalerDr. + have Itau3_Y: {in Y, isometry tau3_Y, to 'Z[irr G]}. + split=> [eta3 eta4 Yeta3 Yeta4 | eta Yeta]; last first. + by rewrite rpredD // Ztau ?Zbeta. + rewrite /= cfdotDl !cfdotDr n1Y1 (cfdotC Y1) !betaY // Itau ?Zbeta //. + rewrite cfdotBl !cfdotBr !oYY // eqxx rmorphB rmorph1 rmorph_nat subrK. + rewrite (eq_sym eta1) opprB !addrA 3!(addrAC _ (- _)) addrK. + by rewrite(addrAC _ 1) subrK addrK. + have{oY} oY := orthonormal_orthogonal oY. + have{Itau3_Y} [tau3 Dtau3 Itau3] := Zisometry_of_iso oY Itau3_Y. + have{Itau3 cohY} cohY: coherent_with Y L^# tau tau3. + split=> // eta; rewrite zcharD1E => /andP[/zchar_expansion[]//z Zz ->{eta}]. + pose sum_z := \sum_(eta <- Y) z eta => /eqP sum_eta_0. + have{sum_eta_0} sum_z_0: sum_z = 0. + apply: (mulIf (neq0CG W1)); rewrite mul0r -sum_eta_0 sum_cfunE mulr_suml. + by apply: eq_big_seq => xi /uniY eta_1; rewrite !cfunE eta_1. + rewrite -[rhs in tau rhs](subrK (sum_z *: eta1)) {1}scaler_suml -sumrB. + rewrite -[tau _](addrK (sum_z *: Y1)) {1 3}sum_z_0 !scale0r addr0 subr0. + rewrite scaler_suml !raddf_sum [tau _]raddf_sum -big_split /= -/tau. + apply: eq_big_seq => eta Yeta; rewrite raddfZ_Cint //= Dtau3 //. + by rewrite -scalerBr [tau _]linearZ -scalerDr. + have [-> | ] := altP (@nilP _ X); first by exists tau3. + rewrite -lt0n -has_predT => /hasP[xi1 Xxi1 _]. + have: tau (xi1 - a xi1 *: eta1) = tau2 xi1 - tau3 (a xi1 *: eta1). + rewrite [tau3 _]linearZ Dtau2 //= Dtau3 // /tau3_Y subrr [tau 0]linear0. + by rewrite add0r addrK. + apply: (bridge_coherent scohS ccsXS cohX ccsYS cohY X'Y). + by rewrite (zchar_on (Zalpha _ Xxi1)) // rpredZ_Cint ?mem_zchar. +pose wf S1 := cfConjC_subset S1 S /\ {subset X ++ Y <= S1}. +pose S1 := [::] ++ X ++ Y; set S2 := [::] in S1; rewrite -[X ++ Y]/S1 in cohXY. +have wfS1: wf S1. + do 2!split=> //; rewrite /S1 /= ?cat_uniq ?uX ?uY ?(introT hasPn) //. + by apply/allP; rewrite all_cat !(introT allP). + by move=> phi; rewrite !mem_cat => /orP[/ccX|/ccY]->; rewrite ?orbT. +move: {2}_.+1 (ltnSn (size S - size S1)) => n. +elim: n => // n IHn in (S2) S1 wfS1 cohXY *; rewrite ltnS => leSnS1. +have [ccsS1S sXYS1] := wfS1; have [uS1 sS1S ccS1] := ccsS1S. +have [sSS1 | /allPn[psi /= Spsi notS1psi]] := altP (@allP _ (mem S1) S). + exact: subset_coherent cohXY. +have [_ _ ccS] := uccS. +have [neq_psi_c Spsic] := (hasPn nrS _ Spsi, ccS _ Spsi). +have wfS1': wf [:: psi, psi^* & S1]%CF. + split; last by move=> xi XYxi; rewrite !inE sXYS1 ?orbT. + split=> [|xi|xi]; rewrite /= !inE. + - by rewrite negb_or eq_sym neq_psi_c notS1psi (contra (ccS1 _)) ?cfConjCK. + - by do 2?[case/predU1P=> [-> //|]] => /sS1S. + rewrite (inv_eq (@cfConjCK _ _)) (can_eq (@cfConjCK _ _)) orbCA !orbA. + by case: pred2P => // _ /ccS1. +apply: (IHn [:: psi, psi^* & S2]%CF) => //; last first. + rewrite -subSn ?uniq_leq_size //; try by have [[]] := wfS1'. + by rewrite /= subSS (leq_trans _ leSnS1) // leq_sub2l ?leqW. +have ltZH': Z \proper H^`(1)%g. + rewrite properEneq sZH' andbT; apply: contraNneq notS1psi => eqZH'. + have [i /setDP[_ nt_i] ->] := seqIndP Spsi; rewrite sXYS1 // mem_cat. + rewrite !mem_seqInd ?normal1 //= -eqZH' !inE in nt_i *. + by rewrite sub1G nt_i andbT orNb. +have: [/\ eta1 \in S1, psi \in S & psi \notin S1]. + by rewrite Spsi sXYS1 // mem_cat Yeta1 orbT. +have /seqIndC1P[i nzi Dpsi] := Spsi. +move/(extend_coherent scohS ccsS1S); apply; split=> //. + rewrite (uniY _ Yeta1) Dpsi cfInd1 // (index_sdprod defL) dvdC_mulr //. + by rewrite Cint_Cnat ?Cnat_irr1. +rewrite !big_cat //= (big_rem _ Yeta1) /= addrC -!addrA -big_cat //=. +rewrite sum_seqIndD_square ?normal1 ?sub1G // indexg1 addrC. +rewrite -subr_gt0 -!addrA ltr_spaddl //. + have /irrY/irrP[j ->] := Yeta1. + by rewrite cfnorm_irr divr1 exprn_gt0 ?irr1_gt0. +rewrite big_seq addr_ge0 ?sumr_ge0 // => [phi Sphi|]. + rewrite mulr_ge0 ?invr_ge0 ?cfnorm_ge0 ?exprn_ge0 // ?char1_pos //. + suffices /seqInd_char: phi \in S by apply: char1_ge0. + rewrite sS1S // !mem_cat; rewrite mem_cat in Sphi. + by case/orP: Sphi => [/mem_rem-> | ->]; rewrite ?orbT. +rewrite subr_ge0 -(Lagrange_index sHL sZH) -oW1 natrM mulrC -mulrA. +rewrite uniY ?ler_pmul2l ?gt0CG //. +rewrite -(prednK (cardG_gt0 Z)) [zz in zz - 1]mulrSr addrK -natrM. +rewrite Dpsi cfInd1 // -oW1. +rewrite -(@ler_pexpn2r _ 2) -?topredE /= ?mulr_ge0 ?ler0n //; last first. + by rewrite char1_ge0 ?irr_char. +rewrite !exprMn -!natrX mulrA -natrM. +apply: ler_trans (_ : (4 * #|W1| ^ 2)%:R * #|H : Z|%:R <= _). + rewrite ler_pmul2l; last by rewrite ltr0n muln_gt0 !expn_gt0 cardG_gt0. + rewrite (ler_trans (irr1_bound i)) // ler_nat dvdn_leq // indexgS //. + by rewrite (subset_trans sZZ) // -cap_cfcenter_irr bigcap_inf. +rewrite -natrM ler_nat expnMn mulnC -mulnA leq_pmul2l //. +have [in_caseA | in_caseB] := boolP caseA. + have regW1Z: semiregular Z W1. + have [in_c1 | in_c2] := boolP case_c1. + move=> x /(Frobenius_reg_ker in_c1) regHx; apply/trivgP. + by rewrite -regHx setSI. + have [/= _ [_ [_ _ _ prW1H] _] _ _] := c2W2 in_c2. + move=> x /prW1H prHx; apply/trivgP; rewrite -((_ =P [1]) in_caseA) -prHx. + by rewrite subsetI subIset ?sZZ // setSI. + rewrite -(mul1n (4 * _)%N) leq_mul // -(expnMn 2 _ 2) leq_exp2r //. + rewrite dvdn_leq //; first by rewrite -subn1 subn_gt0 cardG_gt1. + rewrite Gauss_dvd ?(@pnat_coprime 2) -?odd_2'nat ?(oddSg sW1L) //. + rewrite dvdn2 -{1}subn1 odd_sub // (oddSg (normal_sub nsZL)) //=. + by rewrite regular_norm_dvd_pred // (subset_trans sW1L) ?normal_norm. +rewrite -(muln1 (4 * _)%N) leq_mul //; last first. + by rewrite expn_gt0 -subn1 subn_gt0 orbF cardG_gt1. +rewrite -(expnMn 2 _ 2) -(Lagrange_index (der_sub 1 H) sZH') leq_mul //. + rewrite -(prednK (indexg_gt0 _ _)) leqW // dvdn_leq //. + by rewrite -subn1 subn_gt0 indexg_gt1 proper_subn. + rewrite Gauss_dvd ?(@pnat_coprime 2) -?odd_2'nat ?(oddSg sW1L) //. + rewrite dvdn2 -{1}subn1 odd_sub // -card_quotient ?der_norm //. + rewrite quotient_odd ?(oddSg sHL) //=. + rewrite (card_isog (quotient_isog (subset_trans sW1L nH'L) _)); last first. + by rewrite coprime_TIg ?(coprimeSg (der_sub 1 H)). + exact: Frobenius_dvd_ker1 frobL1. +rewrite -(prednK (indexg_gt0 _ _)) leqW // dvdn_leq //. + by rewrite -subn1 subn_gt0 indexg_gt1 proper_subn. +rewrite Gauss_dvd ?(@pnat_coprime 2) -?odd_2'nat ?(oddSg sW1L) //. +rewrite dvdn2 -{1}subn1 odd_sub //. +rewrite -card_quotient ?(subset_trans (der_sub 1 H)) //. +rewrite quotient_odd ?(oddSg (der_sub 1 H)) ?(oddSg sHL) //=. +have /andP[sZL nZL] := nsZL. +rewrite (card_isog (quotient_isog (subset_trans sW1L nZL) _)); last first. + by rewrite coprime_TIg ?(coprimeSg sZH). +suffices: [Frobenius (H^`(1) / Z) <*> (W1 / Z) = (H^`(1) / Z) ><| (W1 / Z)]%g. + exact: Frobenius_dvd_ker1. +suffices: [Frobenius (L / Z) = (H / Z) ><| (W1 / Z)]%g. + apply: Frobenius_subl (quotientS Z (der_sub 1 H)) _. + by rewrite quotient_neq1 // (normalS sZH' (der_sub 1 H)). + by rewrite quotient_norms ?(subset_trans sW1L). +apply: (Frobenius_coprime_quotient defL nsZL) => //; split=> [|x W1x]. + exact: sub_proper_trans sZH' ltH'H. +have /caseB_P[/c2W2[_ [_ [_ _ _ -> //] _] _ _] _ _] := in_caseB. +by rewrite /Z (negPf in_caseB). +Qed. + +End Six. + + |
