diff options
| author | Enrico Tassi | 2015-03-09 11:07:53 +0100 |
|---|---|---|
| committer | Enrico Tassi | 2015-03-09 11:24:38 +0100 |
| commit | fc84c27eac260dffd8f2fb1cb56d599f1e3486d9 (patch) | |
| tree | c16205f1637c80833a4c4598993c29fa0fd8c373 /mathcomp/odd_order/BGappendixC.v | |
Initial commit
Diffstat (limited to 'mathcomp/odd_order/BGappendixC.v')
| -rw-r--r-- | mathcomp/odd_order/BGappendixC.v | 749 |
1 files changed, 749 insertions, 0 deletions
diff --git a/mathcomp/odd_order/BGappendixC.v b/mathcomp/odd_order/BGappendixC.v new file mode 100644 index 0000000..31bccfb --- /dev/null +++ b/mathcomp/odd_order/BGappendixC.v @@ -0,0 +1,749 @@ +(* (c) Copyright Microsoft Corporation and Inria. All rights reserved. *) +Require Import ssreflect ssrbool ssrfun eqtype choice ssrnat seq div fintype. +Require Import tuple finfun bigop ssralg finset prime binomial poly polydiv. +Require Import fingroup morphism quotient automorphism action finalg zmodp. +Require Import gproduct cyclic commutator pgroup abelian frobenius BGsection1. +Require Import matrix mxalgebra mxabelem vector falgebra fieldext galois. +Require Import finfield ssrnum algC classfun character integral_char inertia. + +Set Implicit Arguments. +Unset Strict Implicit. +Unset Printing Implicit Defensive. + +Import GroupScope GRing.Theory FinRing.Theory Num.Theory. +Local Open Scope ring_scope. + +Section AppendixC. + +Variables (gT : finGroupType) (p q : nat) (H P P0 U Q : {group gT}). +Let nU := ((p ^ q).-1 %/ p.-1)%N. + +(* External statement of the finite field assumption. *) +CoInductive finFieldImage : Prop := + FinFieldImage (F : finFieldType) (sigma : {morphism P >-> F}) of + isom P [set: F] sigma & sigma @*^-1 <[1 : F]> = P0 + & exists2 sigmaU : {morphism U >-> {unit F}}, + 'injm sigmaU & {in P & U, morph_act 'J 'U sigma sigmaU}. + +(* These correspond to hypothesis (A) of B & G, Appendix C, Theorem C. *) +Hypotheses (pr_p : prime p) (pr_q : prime q) (coUp1 : coprime nU p.-1). +Hypotheses (defH : P ><| U = H) (fieldH : finFieldImage). +Hypotheses (oP : #|P| = (p ^ q)%N) (oU : #|U| = nU). + +(* These correspond to hypothesis (B) of B & G, Appendix C, Theorem C. *) +Hypotheses (abelQ : q.-abelem Q) (nQP0 : P0 \subset 'N(Q)). +Hypothesis nU_P0Q : exists2 y, y \in Q & P0 :^ y \subset 'N(U). + +Section ExpandHypotheses. + +(* Negation of the goal of B & G, Appendix C, Theorem C. *) +Hypothesis ltqp : (q < p)%N. + +(* From the fieldH assumption. *) +Variables (fT : finFieldType) (charFp : p \in [char fT]). +Local Notation F := (PrimeCharType charFp). +Local Notation galF := [splittingFieldType 'F_p of F]. +Let Fpq : {vspace F} := fullv. +Let Fp : {vspace F} := 1%VS. + +Hypothesis oF : #|F| = (p ^ q)%N. +Let oF_p : #|'F_p| = p. Proof. exact: card_Fp. Qed. +Let oFp : #|Fp| = p. Proof. by rewrite card_vspace1. Qed. +Let oFpq : #|Fpq| = (p ^ q)%N. Proof. by rewrite card_vspacef. Qed. +Let dimFpq : \dim Fpq = q. Proof. by rewrite primeChar_dimf oF pfactorK. Qed. + +Variables (sigma : {morphism P >-> F}) (sigmaU : {morphism U >-> {unit F}}). +Hypotheses (inj_sigma : 'injm sigma) (inj_sigmaU : 'injm sigmaU). +Hypothesis im_sigma : sigma @* P = [set: F]. +Variable s : gT. +Hypotheses (sP0P : P0 \subset P) (sigma_s : sigma s = 1) (defP0 : <[s]> = P0). + +Let psi u : F := val (sigmaU u). +Let inj_psi : {in U &, injective psi}. +Proof. by move=> u v Uu Uv /val_inj/(injmP inj_sigmaU)->. Qed. + +Hypothesis sigmaJ : {in P & U, forall x u, sigma (x ^ u) = sigma x * psi u}. + +Let Ps : s \in P. Proof. by rewrite -cycle_subG defP0. Qed. +Let P0s : s \in P0. Proof. by rewrite -defP0 cycle_id. Qed. + +Let nz_psi u : psi u != 0. Proof. by rewrite -unitfE (valP (sigmaU u)). Qed. + +Let sigma1 : sigma 1%g = 0. Proof. exact: morph1. Qed. +Let sigmaM : {in P &, {morph sigma : x1 x2 / (x1 * x2)%g >-> x1 + x2}}. +Proof. exact: morphM. Qed. +Let sigmaV : {in P, {morph sigma : x / x^-1%g >-> - x}}. +Proof. exact: morphV. Qed. +Let sigmaX n : {in P, {morph sigma : x / (x ^+ n)%g >-> x *+ n}}. +Proof. exact: morphX. Qed. + +Let psi1 : psi 1%g = 1. Proof. by rewrite /psi morph1. Qed. +Let psiM : {in U &, {morph psi : u1 u2 / (u1 * u2)%g >-> u1 * u2}}. +Proof. by move=> u1 u2 Uu1 Uu2; rewrite /psi morphM. Qed. +Let psiV : {in U, {morph psi : u / u^-1%g >-> u^-1}}. +Proof. by move=> u Uu; rewrite /psi morphV. Qed. +Let psiX n : {in U, {morph psi : u / (u ^+ n)%g >-> u ^+ n}}. +Proof. by move=> u Uu; rewrite /psi morphX // val_unitX. Qed. + +Let sigmaE := (sigma1, sigma_s, mulr1, mul1r, + (sigmaJ, sigmaX, sigmaM, sigmaV), (psi1, psiX, psiM, psiV)). + +Let psiE u : u \in U -> psi u = sigma (s ^ u). +Proof. by move=> Uu; rewrite !sigmaE. Qed. + +Let nPU : U \subset 'N(P). Proof. by have [] := sdprodP defH. Qed. +Let memJ_P : {in P & U, forall x u, x ^ u \in P}. +Proof. by move=> x u Px Uu; rewrite /= memJ_norm ?(subsetP nPU). Qed. +Let in_PU := (memJ_P, in_group). + +Let sigmaP0 : sigma @* P0 =i Fp. +Proof. +rewrite -defP0 morphim_cycle // sigma_s => x. +apply/cycleP/vlineP=> [] [n ->]; first by exists n%:R; rewrite scaler_nat. +by exists (val n); rewrite -{1}[n]natr_Zp -in_algE rmorph_nat zmodXgE. +Qed. + +Let nt_s : s != 1%g. +Proof. by rewrite -(morph_injm_eq1 inj_sigma) // sigmaE oner_eq0. Qed. + +Let p_gt0 : (0 < p)%N. Proof. exact: prime_gt0. Qed. +Let q_gt0 : (0 < q)%N. Proof. exact: prime_gt0. Qed. +Let p1_gt0 : (0 < p.-1)%N. Proof. by rewrite -subn1 subn_gt0 prime_gt1. Qed. + +(* This is B & G, Appendix C, Remark I. *) +Let not_dvd_q_p1 : ~~ (q %| p.-1)%N. +Proof. +rewrite -prime_coprime // -[q]card_ord -sum1_card -coprime_modl -modn_summ. +have:= coUp1; rewrite /nU predn_exp mulKn //= -coprime_modl -modn_summ. +congr (coprime (_ %% _) _); apply: eq_bigr => i _. +by rewrite -{1}[p](subnK p_gt0) subn1 -modnXm modnDl modnXm exp1n. +Qed. + +(* This is the first assertion of B & G, Appendix C, Remark V. *) +Let odd_p : odd p. +Proof. +by apply: contraLR ltqp => /prime_oddPn-> //; rewrite -leqNgt prime_gt1. +Qed. + +(* This is the second assertion of B & G, Appendix C, Remark V. *) +Let odd_q : odd q. +Proof. +apply: contraR not_dvd_q_p1 => /prime_oddPn-> //. +by rewrite -subn1 dvdn2 odd_sub ?odd_p. +Qed. + +Let qgt2 : (2 < q)%N. Proof. by rewrite odd_prime_gt2. Qed. +Let pgt4 : (4 < p)%N. Proof. by rewrite odd_geq ?(leq_ltn_trans qgt2). Qed. +Let qgt1 : (1 < q)%N. Proof. exact: ltnW. Qed. + +Local Notation Nm := (galNorm Fp Fpq). +Local Notation uval := (@FinRing.uval _). + +Let cycFU (FU : {group {unit F}}) : cyclic FU. +Proof. exact: field_unit_group_cyclic. Qed. +Let cUU : abelian U. +Proof. by rewrite cyclic_abelian // -(injm_cyclic inj_sigmaU) ?cycFU. Qed. + +(* This is B & G, Appendix C, Remark VII. *) +Let im_psi (x : F) : (x \in psi @: U) = (Nm x == 1). +Proof. +have /cyclicP[u0 defFU]: cyclic [set: {unit F}] by exact: cycFU. +have o_u0: #[u0] = (p ^ q).-1 by rewrite orderE -defFU card_finField_unit oF. +have ->: psi @: U = uval @: (sigmaU @* U) by rewrite morphimEdom -imset_comp. +have /set1P[->]: (sigmaU @* U)%G \in [set <[u0 ^+ (#[u0] %/ nU)]>%G]. + rewrite -cycle_sub_group ?inE; last first. + by rewrite o_u0 -(divnK (dvdn_pred_predX p q)) dvdn_mulr. + by rewrite -defFU subsetT card_injm //= oU. +rewrite divnA ?dvdn_pred_predX // -o_u0 mulKn //. +have [/= alpha alpha_gen Dalpha] := finField_galois_generator (subvf Fp). +have{Dalpha} Dalpha x1: x1 != 0 -> x1 / alpha x1 = x1^-1 ^+ p.-1. + move=> nz_x1; rewrite -[_ ^+ _](mulVKf nz_x1) -exprS Dalpha ?memvf // exprVn. + by rewrite dimv1 oF_p prednK ?prime_gt0. +apply/idP/(Hilbert's_theorem_90 alpha_gen (memvf _)) => [|[u [_ nz_u] ->]]. + case/imsetP=> /= _ /cycleP[n ->] ->; rewrite expgAC; set u := (u0 ^+ n)%g. + have nz_u: (val u)^-1 != 0 by rewrite -unitfE unitrV (valP u). + by exists (val u)^-1; rewrite ?memvf ?Dalpha //= invrK val_unitX. +have /cycleP[n Du]: (insubd u0 u)^-1%g \in <[u0]> by rewrite -defFU inE. +have{Du} Du: u^-1 = val (u0 ^+ n)%g by rewrite -Du /= insubdK ?unitfE. +by rewrite Dalpha // Du -val_unitX mem_imset // expgAC mem_cycle. +Qed. + +(* This is B & G, Appendix C, Remark VIII. *) +Let defFU : sigmaU @* U \x [set u | uval u \in Fp] = [set: {unit F}]. +Proof. +have fP v: in_alg F (uval v) \is a GRing.unit by rewrite rmorph_unit ?(valP v). +pose f (v : {unit 'F_p}) := FinRing.unit F (fP v). +have fM: {in setT &, {morph f: v1 v2 / (v1 * v2)%g}}. + by move=> v1 v2 _ _; apply: val_inj; rewrite /= -in_algE rmorphM. +pose galFpU := Morphism fM @* [set: {unit 'F_p}]. +have ->: [set u | uval u \in Fp] = galFpU. + apply/setP=> u; rewrite inE /galFpU morphimEdom. + apply/idP/imsetP=> [|[v _ ->]]; last by rewrite /= rpredZ // memv_line. + case/vlineP=> v Du; have nz_v: v != 0. + by apply: contraTneq (valP u) => v0; rewrite unitfE /= Du v0 scale0r eqxx. + exists (insubd (1%g : {unit 'F_p}) v); rewrite ?inE //. + by apply: val_inj; rewrite /= insubdK ?unitfE. +have oFpU: #|galFpU| = p.-1. + rewrite card_injm ?card_finField_unit ?oF_p //. + by apply/injmP=> v1 v2 _ _ []/(fmorph_inj [rmorphism of in_alg F])/val_inj. +have oUU: #|sigmaU @* U| = nU by rewrite card_injm. +rewrite dprodE ?coprime_TIg ?oUU ?oFpU //; last first. + by rewrite (sub_abelian_cent2 (cyclic_abelian (cycFU [set: _]))) ?subsetT. +apply/eqP; rewrite eqEcard subsetT coprime_cardMg oUU oFpU //=. +by rewrite card_finField_unit oF divnK ?dvdn_pred_predX. +Qed. + +(* This is B & G, Appendix C, Remark IX. *) +Let frobH : [Frobenius H = P ><| U]. +Proof. +apply/Frobenius_semiregularP=> // [||u /setD1P[ntu Uu]]. +- by rewrite -(morphim_injm_eq1 inj_sigma) // im_sigma finRing_nontrivial. +- rewrite -cardG_gt1 oU ltn_divRL ?dvdn_pred_predX // mul1n -!subn1. + by rewrite ltn_sub2r ?(ltn_exp2l 0) ?(ltn_exp2l 1) ?prime_gt1. +apply/trivgP/subsetP=> x /setIP[Px /cent1P/commgP]. +rewrite inE -!(morph_injm_eq1 inj_sigma) ?(sigmaE, in_PU) //. +rewrite -mulrN1 addrC -mulrDr mulf_eq0 subr_eq0 => /orP[] // /idPn[]. +by rewrite (inj_eq val_inj (sigmaU u) 1%g) morph_injm_eq1. +Qed. + +(* From the abelQ assumption of Peterfalvi, Theorem (14.2) to the assumptions *) +(* of part (B) of the assumptions of Theorem C. *) +Let p'q : q != p. Proof. by rewrite ltn_eqF. Qed. +Let cQQ : abelian Q. Proof. exact: abelem_abelian abelQ. Qed. +Let p'Q : p^'.-group Q. Proof. exact: pi_pgroup (abelem_pgroup abelQ) _. Qed. + +Let pP : p.-group P. Proof. by rewrite /pgroup oP pnat_exp ?pnat_id. Qed. +Let coQP : coprime #|Q| #|P|. Proof. exact: p'nat_coprime p'Q pP. Qed. +Let sQP0Q : [~: Q, P0] \subset Q. Proof. by rewrite commg_subl. Qed. + +(* This is B & G, Appendix C, Remark X. *) +Let defQ : 'C_Q(P0) \x [~: Q, P0] = Q. +Proof. by rewrite dprodC coprime_abelian_cent_dprod // (coprimegS sP0P). Qed. + +(* This is B & G, Appendix C, Remark XI. *) +Let nU_P0QP0 : exists2 y, y \in [~: Q, P0] & P0 :^ y \subset 'N(U). +Proof. +have [_ /(mem_dprod defQ)[z [y [/setIP[_ cP0z] QP0y -> _]]]] := nU_P0Q. +by rewrite conjsgM (normsP (cent_sub P0)) //; exists y. +Qed. + +Let E := [set x : galF | Nm x == 1 & Nm (2%:R - x) == 1]. + +Let E_1 : 1 \in E. +Proof. by rewrite !inE -addrA subrr addr0 galNorm1 eqxx. Qed. + +(* This is B & G, Appendix C, Lemma C.1. *) +Let Einv_gt1_le_pq : E = [set x^-1 | x in E] -> (1 < #|E|)%N -> (p <= q)%N. +Proof. +rewrite (cardsD1 1) E_1 ltnS card_gt0 => Einv /set0Pn[/= a /setD1P[not_a1 Ea]]. +pose tau (x : F) := (2%:R - x)^-1. +have Etau x: x \in E -> tau x \in E. + rewrite inE => Ex; rewrite Einv (mem_imset (fun y => y^-1)) //. + by rewrite inE andbC opprD addNKr opprK. +pose Pa := \prod_(beta in 'Gal(Fpq / Fp)) (beta (1 - a) *: 'X + 1). +have galPoly_roots: all (root (Pa - 1)) (enum Fp). + apply/allP=> x; rewrite mem_enum => /vlineP[b ->]. + rewrite rootE !hornerE horner_prod subr_eq0 /=; apply/eqP. + pose h k := (1 - a) *+ k + 1; transitivity (Nm (h b)). + apply: eq_bigr => beta _; rewrite !(rmorphB, rmorphD, rmorphMn) rmorph1 /=. + by rewrite -mulr_natr -scaler_nat natr_Zp hornerD hornerZ hornerX hornerC. + elim: (b : nat) => [|k IHk]; first by rewrite /h add0r galNorm1. + suffices{IHk}: h k / h k.+1 \in E. + rewrite inE -invr_eq1 => /andP[/eqP <- _]. + by rewrite galNormM galNormV /= [galNorm _ _ (h k)]IHk mul1r invrK. + elim: k => [|k IHk]; first by rewrite /h add0r mul1r addrAC Etau. + have nz_hk1: h k.+1 != 0. + apply: contraTneq IHk => ->; rewrite invr0 mulr0. + by rewrite inE galNorm0 eq_sym oner_eq0. + congr (_ \in E): (Etau _ IHk); apply: canLR (@invrK _) _; rewrite invfM invrK. + apply: canRL (mulKf nz_hk1) _; rewrite mulrC mulrBl divfK // mulrDl mul1r. + by rewrite {2}/h mulrS -2!addrA addrK addrAC -mulrSr. +have sizePa: size Pa = q.+1. + have sizePaX (beta : {rmorphism F -> F}) : size (beta (1 - a) *: 'X + 1) = 2. + rewrite -mul_polyC size_MXaddC oner_eq0 andbF size_polyC fmorph_eq0. + by rewrite subr_eq0 eq_sym (negbTE not_a1). + rewrite size_prod => [|i _]; last by rewrite -size_poly_eq0 sizePaX. + rewrite (eq_bigr (fun _ => 2)) => [|beta _]; last by rewrite sizePaX. + rewrite sum_nat_const muln2 -addnn -addSn addnK. + by rewrite -galois_dim ?finField_galois ?subvf // dimv1 divn1 dimFpq. +have sizePa1: size (Pa - 1) = q.+1. + by rewrite size_addl // size_opp size_poly1 sizePa. +have nz_Pa1 : Pa - 1 != 0 by rewrite -size_poly_eq0 sizePa1. +by rewrite -ltnS -oFp -sizePa1 cardE max_poly_roots ?enum_uniq. +Qed. + +(* This is B & G, Appendix C, Lemma C.2. *) +Let E_gt1 : (1 < #|E|)%N. +Proof. +have [q_gt4 | q_le4] := ltnP 4 q. + pose inK x := enum_rank_in (classes1 H) (x ^: H). + have inK_E x: x \in H -> enum_val (inK x) = x ^: H. + by move=> Hx; rewrite enum_rankK_in ?mem_classes. + pose j := inK s; pose k := inK (s ^+ 2)%g; pose e := gring_classM_coef j j k. + have cPP: abelian P by rewrite -(injm_abelian inj_sigma) ?zmod_abelian. + have Hs: s \in H by rewrite -(sdprodW defH) -[s]mulg1 mem_mulg. + have DsH n: (s ^+ n) ^: H = (s ^+ n) ^: U. + rewrite -(sdprodW defH) classM (abelian_classP _ cPP) ?groupX //. + by rewrite class_support_set1l. + have injJU: {in U &, injective (conjg s)}. + by move=> u v Uu Uv eq_s_uv; apply/inj_psi; rewrite ?psiE ?eq_s_uv. + have ->: #|E| = e. + rewrite /e /gring_classM_coef !inK_E ?groupX //. + transitivity #|[set u in U | s^-1 ^ u * s ^+ 2 \in s ^: U]%g|. + rewrite -(card_in_imset (sub_in2 _ inj_psi)) => [|u /setIdP[] //]. + apply: eq_card => x; rewrite inE -!im_psi. + apply/andP/imsetP=> [[/imsetP[u Uu ->] /imsetP[v Uv Dv]]{x} | ]. + exists u; rewrite // inE Uu /=; apply/imsetP; exists v => //. + by apply: (injmP inj_sigma); rewrite ?(sigmaE, in_PU) // mulN1r addrC. + case=> u /setIdP[Uu /imsetP[v Uv /(congr1 sigma)]]. + rewrite ?(sigmaE, in_PU) // mulN1r addrC => Dv ->. + by rewrite Dv !mem_imset. + rewrite DsH (DsH 1%N) expg1; have [w Uw ->] := repr_class U (s ^+ 2). + pose f u := (s ^ (u * w), (s^-1 ^ u * s ^+ 2) ^ w). + rewrite -(@card_in_imset _ _ f) => [|u v]; last first. + by move=> /setIdP[Uu _] /setIdP[Uv _] [/injJU/mulIg-> //]; apply: groupM. + apply: eq_card => [[x1 x2]]; rewrite inE -andbA. + apply/imsetP/and3P=> [[u /setIdP[Uu sUs2u'] [-> ->]{x1 x2}] | []]. + rewrite /= conjgM -(rcoset_id Uw) class_rcoset !memJ_conjg mem_orbit //. + by rewrite sUs2u' -conjMg conjVg mulKVg. + case/imsetP=> u Uu /= -> sUx2 /eqP/(canRL (mulKg _)) Dx2. + exists (u * w^-1)%g; last first. + by rewrite /f /= conjMg -conjgM mulgKV conjVg -Dx2. + rewrite inE !in_PU // Uw -(memJ_conjg _ w) -class_rcoset rcoset_id //. + by rewrite conjMg -conjgM mulgKV conjVg -Dx2. + pose chi_s2 i := 'chi[H]_i s ^+ 2 * ('chi_i (s ^+ 2)%g)^* / 'chi_i 1%g. + have De: e%:R = #|U|%:R / #|P|%:R * (\sum_i chi_s2 i). + have Ks: s \in enum_val j by rewrite inK_E ?class_refl. + have Ks2: (s ^+ 2)%g \in enum_val k by rewrite inK_E ?groupX ?class_refl. + rewrite (gring_classM_coef_sum_eq Ks Ks Ks2) inK_E //; congr (_ * _). + have ->: #|s ^: H| = #|U| by rewrite (DsH 1%N) (card_in_imset injJU). + by rewrite -(sdprod_card defH) mulnC !natrM invfM mulrA mulfK ?neq0CG. + pose linH := [pred i | P \subset cfker 'chi[H]_i]. + have nsPH: P <| H by have [] := sdprod_context defH. + have sum_linH: \sum_(i in linH) chi_s2 i = #|U|%:R. + have isoU: U \isog H / P := sdprod_isog defH. + have abHbar: abelian (H / P) by rewrite -(isog_abelian isoU). + rewrite (card_isog isoU) -(card_Iirr_abelian abHbar) -sumr_const. + rewrite (reindex _ (mod_Iirr_bij nsPH)) /chi_s2 /=. + apply: eq_big => [i | i _]; rewrite ?mod_IirrE ?cfker_mod //. + have lin_i: ('chi_i %% P)%CF \is a linear_char. + exact/cfMod_lin_char/char_abelianP. + rewrite lin_char1 // divr1 -lin_charX // -normCK. + by rewrite normC_lin_char ?groupX ?expr1n. + have degU i: i \notin linH -> 'chi_i 1%g = #|U|%:R. + case/(Frobenius_Ind_irrP (FrobeniusWker frobH)) => {i}i _ ->. + rewrite cfInd1 ?normal_sub // -(index_sdprod defH) lin_char1 ?mulr1 //. + exact/char_abelianP. + have ub_linH' m (s_m := (s ^+ m)%g): + (0 < m < 5)%N -> \sum_(i in predC linH) `|'chi_i s_m| ^+ 2 <= #|P|%:R. + - case/andP=> m_gt0 m_lt5; have{m_gt0 m_lt5} P1sm: s_m \in P^#. + rewrite !inE groupX // -order_dvdn -(order_injm inj_sigma) // sigmaE. + by rewrite andbT order_primeChar ?oner_neq0 ?gtnNdvd ?(leq_trans m_lt5). + have ->: #|P| = (#|P| * (s_m \in s_m ^: H))%N by rewrite class_refl ?muln1. + have{P1sm} /eqP <-: 'C_H[s ^+ m] == P. + rewrite eqEsubset (Frobenius_cent1_ker frobH) // subsetI normal_sub //=. + by rewrite sub_cent1 groupX // (subsetP cPP). + rewrite mulrnA -second_orthogonality_relation ?groupX // big_mkcond. + by apply: ler_sum => i _; rewrite normCK; case: ifP; rewrite ?mul_conjC_ge0. + have sqrtP_gt0: 0 < sqrtC #|P|%:R by rewrite sqrtC_gt0 ?gt0CG. + have{De ub_linH'}: `|(#|P| * e)%:R - #|U|%:R ^+ 2| <= #|P|%:R * sqrtC #|P|%:R. + rewrite natrM De mulrCA mulrA divfK ?neq0CG // (bigID linH) /= sum_linH. + rewrite mulrDr addrC addKr mulrC mulr_suml /chi_s2. + rewrite (ler_trans (ler_norm_sum _ _ _)) // -ler_pdivr_mulr // mulr_suml. + apply: ler_trans (ub_linH' 1%N isT); apply: ler_sum => i linH'i. + rewrite ler_pdivr_mulr // degU ?divfK ?neq0CG //. + rewrite normrM -normrX norm_conjC ler_wpmul2l ?normr_ge0 //. + rewrite -ler_sqr ?qualifE ?normr_ge0 ?(@ltrW _ 0) // sqrtCK. + apply: ler_trans (ub_linH' 2 isT); rewrite (bigD1 i) ?ler_paddr //=. + by apply: sumr_ge0 => i1 _; rewrite exprn_ge0 ?normr_ge0. + rewrite natrM real_ler_distl ?rpredB ?rpredM ?rpred_nat // => /andP[lb_Pe _]. + rewrite -ltC_nat -(ltr_pmul2l (gt0CG P)) {lb_Pe}(ltr_le_trans _ lb_Pe) //. + rewrite ltr_subr_addl (@ler_lt_trans _ ((p ^ q.-1)%:R ^+ 2)) //; last first. + rewrite -!natrX ltC_nat ltn_sqr oU ltn_divRL ?dvdn_pred_predX //. + rewrite -(subnKC qgt1) /= -!subn1 mulnBr muln1 -expnSr. + by rewrite ltn_sub2l ?(ltn_exp2l 0) // prime_gt1. + rewrite -mulrDr -natrX -expnM muln2 -subn1 doubleB -addnn -addnBA // subn2. + rewrite expnD natrM -oP ler_wpmul2l ?ler0n //. + apply: ler_trans (_ : 2%:R * sqrtC #|P|%:R <= _). + rewrite mulrDl mul1r ler_add2l -(@expr_ge1 _ 2) ?(ltrW sqrtP_gt0) // sqrtCK. + by rewrite oP natrX expr_ge1 ?ler0n ?ler1n. + rewrite -ler_sqr ?rpredM ?rpred_nat ?qualifE ?(ltrW sqrtP_gt0) //. + rewrite exprMn sqrtCK -!natrX -natrM leC_nat -expnM muln2 oP. + rewrite -(subnKC q_gt4) doubleS (expnS p _.*2.+1) -(subnKC pgt4) leq_mul //. + by rewrite ?leq_exp2l // !doubleS !ltnS -addnn leq_addl. +have q3: q = 3 by apply/eqP; rewrite eqn_leq qgt2 andbT -ltnS -(odd_ltn 5). +rewrite (cardsD1 1) E_1 ltnS card_gt0; apply/set0Pn => /=. +pose f (c : 'F_p) : {poly 'F_p} := 'X * ('X - 2%:R%:P) * ('X - c%:P) + ('X - 1). +have fc0 c: (f c).[0] = -1 by rewrite !hornerE. +have fc2 c: (f c).[2%:R] = 1 by rewrite !(subrr, hornerE) /= addrK. +have /existsP[c nz_fc]: [exists c, ~~ [exists d, root (f c) d]]. + have nz_f_0 c: ~~ root (f c) 0 by rewrite /root fc0 oppr_eq0. + rewrite -negb_forall; apply/negP=> /'forall_existsP/fin_all_exists[/= rf rfP]. + suffices inj_rf: injective rf. + by have /negP[] := nz_f_0 (invF inj_rf 0); rewrite -{2}[0](f_invF inj_rf). + move=> a b eq_rf_ab; apply/oppr_inj/(addrI (rf a)). + have: (f a).[rf a] = (f b).[rf a] by rewrite {2}eq_rf_ab !(rootP _). + rewrite !(hornerXsubC, hornerD, hornerM) hornerX => /addIr/mulfI-> //. + rewrite mulf_neq0 ?subr_eq0 1?(contraTneq _ (rfP a)) // => -> //. + by rewrite /root fc2. +have{nz_fc} /= nz_fc: ~~ root (f c) _ by apply/forallP; rewrite -negb_exists. +have sz_fc_lhs: size ('X * ('X - 2%:R%:P) * ('X - c%:P)) = 4. + by rewrite !(size_mul, =^~ size_poly_eq0) ?size_polyX ?size_XsubC. +have sz_fc: size (f c) = 4 by rewrite size_addl ?size_XsubC sz_fc_lhs. +have irr_fc: irreducible_poly (f c) by apply: cubic_irreducible; rewrite ?sz_fc. +have fc_monic : f c \is monic. + rewrite monicE lead_coefDl ?size_XsubC ?sz_fc_lhs // -monicE. + by rewrite !monicMl ?monicXsubC ?monicX. +pose inF := [rmorphism of in_alg F]; pose fcF := map_poly inF (f c). +have /existsP[a fcFa_0]: [exists a : F, root fcF a]. + suffices: ~~ coprimep (f c) ('X ^+ #|F| - 'X). + apply: contraR; rewrite -(coprimep_map inF) negb_exists => /forallP-nz_fcF. + rewrite -/fcF rmorphB rmorphX /= map_polyX finField_genPoly. + elim/big_rec: _ => [|x gF _ co_fcFg]; first exact: coprimep1. + by rewrite coprimep_mulr coprimep_XsubC nz_fcF. + have /irredp_FAdjoin[L dimL [z /coprimep_root fcz0 _]] := irr_fc. + pose finL := [vectType 'F_p of FinFieldExtType L]. + set fcL := map_poly _ _ in fcz0; pose inL := [rmorphism of in_alg L]. + rewrite -(coprimep_map inL) -/fcL rmorphB rmorphX /= map_polyX. + apply: contraL (fcz0 _) _; rewrite hornerD hornerN hornerXn hornerX subr_eq0. + have ->: #|F| = #|{: finL}%VS| by rewrite oF card_vspace dimL sz_fc oF_p q3. + by rewrite card_vspacef (expf_card (z : finL)). +have Fp_fcF: fcF \is a polyOver Fp. + by apply/polyOverP => i; rewrite coef_map /= memvZ ?memv_line. +pose G := 'Gal(Fpq / Fp). +have galG: galois Fp Fpq by rewrite finField_galois ?subvf. +have oG: #|G| = 3 by rewrite -galois_dim // dimv1 dimFpq q3. +have Fp'a: a \notin Fp. + by apply: contraL fcFa_0 => /vlineP[d ->]; rewrite fmorph_root. +have DfcF: fcF = \prod_(beta in G) ('X - (beta a)%:P). + pose Pa : {poly F} := minPoly Fp a. + have /eqP szPa: size Pa == 4. + rewrite size_minPoly eqSS. + rewrite (sameP eqP (prime_nt_dvdP _ _)) ?adjoin_deg_eq1 //. + by rewrite adjoin_degreeE dimv1 divn1 -q3 -dimFpq field_dimS ?subvf. + have dvd_Pa_fcF: Pa %| fcF by apply: minPoly_dvdp fcFa_0. + have{dvd_Pa_fcF} /eqP <-: Pa == fcF. + rewrite -eqp_monic ?monic_minPoly ?monic_map // -dvdp_size_eqp //. + by rewrite szPa size_map_poly sz_fc. + have [r [srG /map_uniq Ur defPa]]:= galois_factors (subvf _) galG a (memvf a). + rewrite -/Pa big_map in defPa; rewrite defPa big_uniq //=. + apply/eq_bigl/subset_cardP=> //; apply/eqP. + by rewrite -eqSS (card_uniqP Ur) oG -szPa defPa size_prod_XsubC. +exists a; rewrite !inE; apply/and3P; split. +- by apply: contraNneq Fp'a => ->; apply: mem1v. +- apply/eqP; transitivity ((- 1) ^+ #|G| * fcF.[inF 0]). + rewrite DfcF horner_prod -prodrN; apply: eq_bigr => beta _. + by rewrite rmorph0 hornerXsubC add0r opprK. + by rewrite -signr_odd mulr_sign oG horner_map fc0 rmorphN1 opprK. +apply/eqP; transitivity (fcF.[inF 2%:R]); last by rewrite horner_map fc2 rmorph1. +rewrite DfcF horner_prod; apply: eq_bigr => beta _. +by rewrite hornerXsubC rmorphB !rmorph_nat. +Qed. + +Section AppendixC3. + +Import GroupScope. + +Variables y : gT. +Hypotheses (QP0y : y \in [~: Q, P0]) (nUP0y : P0 :^ y \subset 'N(U)). +Let Qy : y \in Q. Proof. by rewrite (subsetP sQP0Q). Qed. + +Let t := s ^ y. +Let P1 := P0 :^ y. + +(* This is B & G, Appendix C, Lemma C.3, Step 1. *) +Let splitH x : + x \in H -> + exists2 u, u \in U & exists2 v, v \in U & exists2 s1, s1 \in P0 + & x = u * s1 * v. +Proof. +case/(mem_sdprod defH) => z [v [Pz Uv -> _]]. +have [-> | nt_z] := eqVneq z 1. + by exists 1 => //; exists v => //; exists 1; rewrite ?mulg1. +have nz_z: sigma z != 0 by rewrite (morph_injm_eq1 inj_sigma). +have /(mem_dprod defFU)[]: finField_unit nz_z \in setT := in_setT _. +move=> _ [w [/morphimP[u Uu _ ->] Fp_w /(congr1 val)/= Dz _]]. +have{Fp_w Dz} [n Dz]: exists n, sigma z = sigma ((s ^+ n) ^ u). + move: Fp_w; rewrite {}Dz inE => /vlineP[n ->]; exists n. + by rewrite -{1}(natr_Zp n) scaler_nat mulr_natr conjXg !sigmaE ?in_PU. +exists u^-1; last exists (u * v); rewrite ?groupV ?groupM //. +exists (s ^+ n); rewrite ?groupX // mulgA; congr (_ * _). +by apply: (injmP inj_sigma); rewrite -?mulgA ?in_PU. +Qed. + +(* This is B & G, Appendix C, Lemma C.3, Step 2. *) +Let not_splitU s1 s2 u : + s1 \in P0 -> s2 \in P0 -> u \in U -> s1 * u * s2 \in U -> + (s1 == 1) && (s2 == 1) || (u == 1) && (s1 * s2 == 1). +Proof. +move=> P0s1 P0s2 Uu; have [_ _ _ tiPU] := sdprodP defH. +have [Ps1 Ps2]: s1 \in P /\ s2 \in P by rewrite !(subsetP sP0P). +have [-> | nt_s1 /=] := altP (s1 =P 1). + by rewrite mul1g groupMl // -in_set1 -set1gE -tiPU inE Ps2 => ->. +have [-> | nt_u /=] := altP (u =P 1). + by rewrite mulg1 -in_set1 -set1gE -tiPU inE (groupM Ps1). +rewrite (conjgC _ u) -mulgA groupMl // => Us12; case/negP: nt_u. +rewrite -(morph_injm_eq1 inj_sigmaU) // -in_set1 -set1gE. +have [_ _ _ <-] := dprodP defFU; rewrite !inE mem_morphim //= -/(psi u). +have{Us12}: s1 ^ u * s2 == 1. + by rewrite -in_set1 -set1gE -tiPU inE Us12 andbT !in_PU. +rewrite -(morph_injm_eq1 inj_sigma) ?(in_PU, sigmaE) // addr_eq0. +move/eqP/(canRL (mulKf _))->; rewrite ?morph_injm_eq1 //. +by rewrite mulrC rpred_div ?rpredN //= -sigmaP0 mem_morphim. +Qed. + +(* This is B & G, Appendix C, Lemma C.3, Step 3. *) +Let tiH_P1 t1 : t1 \in P1^# -> H :&: H :^ t1 = U. +Proof. +case/setD1P=>[nt_t1 P1t1]; set X := H :&: _. +have [nsPH sUH _ _ tiPU] := sdprod_context defH. +have sUX: U \subset X. + by rewrite subsetI sUH -(normsP nUP0y t1 P1t1) conjSg. +have defX: (P :&: X) * U = X. + by rewrite setIC group_modr // (sdprodW defH) setIAC setIid. +have [tiPX | ntPX] := eqVneq (P :&: X) 1; first by rewrite -defX tiPX mul1g. +have irrPU: acts_irreducibly U P 'J. + apply/mingroupP; (split=> [|V /andP[ntV]]; rewrite astabsJ) => [|nVU sVP]. + by have [_ ->] := Frobenius_context frobH. + apply/eqP; rewrite eqEsubset sVP; apply/subsetP=> x Px. + have [-> // | ntx] := eqVneq x 1. + have [z Vz ntz] := trivgPn _ ntV; have Pz := subsetP sVP z Vz. + have nz_z: sigma z != 0%R by rewrite morph_injm_eq1. + have uP: (sigma x / sigma z)%R \is a GRing.unit. + by rewrite unitfE mulf_neq0 ?invr_eq0 ?morph_injm_eq1. + have: FinRing.unit F uP \in setT := in_setT _. + case/(mem_dprod defFU)=> _ [s1 [/morphimP[u Uu _ ->]]]. + rewrite inE => /vlineP[n Ds1] /(congr1 val)/= Dx _. + suffices ->: x = (z ^ u) ^+ n by rewrite groupX ?memJ_norm ?(subsetP nVU). + apply: (injmP inj_sigma); rewrite ?(in_PU, sigmaE) //. + by rewrite -mulr_natr -scaler_nat natr_Zp -Ds1 -mulrA -Dx mulrC divfK. +have{ntPX defX irrPU} defX: X :=: H. + rewrite -(sdprodW defH) -defX; congr (_ * _). + have [_ -> //] := mingroupP irrPU; rewrite ?subsetIl //= -/X astabsJ ntPX. + by rewrite normsI // normsG. +have nHt1: t1 \in 'N(H) by rewrite -groupV inE sub_conjgV; apply/setIidPl. +have oP0: #|P0| = p by rewrite -(card_injm inj_sigma) // (eq_card sigmaP0) oFp. +have{nHt1} nHP1: P1 \subset 'N(H). + apply: prime_meetG; first by rewrite cardJg oP0. + by apply/trivgPn; exists t1; rewrite // inE P1t1. +have{nHP1} nPP1: P1 \subset 'N(P). + have /Hall_pi hallP: Hall H P by apply: Frobenius_ker_Hall frobH. + by rewrite -(normal_Hall_pcore hallP nsPH) (char_norm_trans (pcore_char _ _)). +have sylP0: p.-Sylow(Q <*> P0) P0. + rewrite /pHall -divgS joing_subr ?(pgroupS sP0P) //=. + by rewrite norm_joinEr // coprime_cardMg ?(coprimegS sP0P) ?mulnK. +have sP1QP0: P1 \subset Q <*> P0. + by rewrite conj_subG ?joing_subr ?mem_gen // inE Qy. +have nP10: P1 \subset 'N(P0). + have: P1 \subset 'N(P :&: (Q <*> P0)) by rewrite normsI // normsG. + by rewrite norm_joinEr // -group_modr // setIC coprime_TIg // mul1g. +have eqP10: P1 :=: P0. + apply/eqP; rewrite eqEcard cardJg leqnn andbT. + rewrite (comm_sub_max_pgroup (Hall_max sylP0)) //; last exact: normC. + by rewrite pgroupJ (pHall_pgroup sylP0). +have /idPn[] := prime_gt1 pr_p. +rewrite -oP0 cardG_gt1 negbK -subG1 -(Frobenius_trivg_cent frobH) subsetI sP0P. +apply/commG1P/trivgP; rewrite -tiPU commg_subI // subsetI ?subxx //. +by rewrite sP0P -eqP10. +Qed. + +(* This is B & G, Appendix C, Lemma C.3, Step 4. *) +Fact BGappendixC3_Ediv : E = [set x^-1 | x in E]%R. +Proof. +suffices sEV_E: [set x^-1 | x in E]%R \subset E. + by apply/esym/eqP; rewrite eqEcard sEV_E card_imset //=; apply: invr_inj. +have /mulG_sub[/(subset_trans sP0P)/subsetP sP0H /subsetP sUH] := sdprodW defH. +have Hs := sP0H s P0s; have P1t: t \in P1 by rewrite memJ_conjg. +have nUP1 t1: t1 \in P1 -> U :^ t1 = U by move/(subsetP nUP0y)/normP. +have nUtn n u: u \in U -> u ^ (t ^+ n) \in U. + by rewrite -mem_conjgV nUP1 ?groupV ?groupX. +have nUtVn n u: u \in U -> u ^ (t ^- n) \in U. + by rewrite -mem_conjg nUP1 ?groupX. +have Qsti i: s ^- i * t ^+ i \in Q. + by rewrite -conjXg -commgEl (subsetP sQP0Q) // commGC mem_commg ?groupX. +pose is_sUs m a j n u s1 v := + [/\ a \in U, u \in U, v \in U, s1 \in P0 + & s ^+ m * a ^ t ^+ j * s ^- n = u * s1 * v]. +have split_sUs m a j n: + a \in U -> exists u, exists s1, exists v, is_sUs m a j n u s1 v. +- move=> Ua; suffices: s ^+ m * a ^ t ^+ j * s ^- n \in H. + by case/splitH=> u Uu [v Uv [s1 P0s1 Dusv1]]; exists u, s1, v. + by rewrite 2?groupM ?groupV ?groupX // sUH ?nUtn. +have nt_sUs m j n a u s1 v: + (m == n.+1) || (n == m.+1) -> is_sUs m a j n u s1 v -> s1 != 1. +- move/pred2P=> Dmn [Ua Uu Uv _ Dusv]; have{Dmn}: s ^+ m != s ^+ n. + by case: Dmn => ->; last rewrite eq_sym; rewrite expgS eq_mulgV1 ?mulgK. + apply: contraNneq => s1_1; rewrite {s1}s1_1 mulg1 in Dusv. + have:= groupM Uu Uv; rewrite -Dusv => /(not_splitU _ _ (nUtn j a Ua))/orP. + by rewrite !in_group // eq_invg1 -eq_mulgV1 => -[]// /andP[? /eqP->]. +have sUs_modP m a j n u s1 v: is_sUs m a j n u s1 v -> a ^ t ^+ j = u * v. + have [nUP /isom_inj/injmP/=quoUP_inj] := sdprod_isom defH. + case=> Ua Uu Uv P0s1 /(congr1 (coset P)); rewrite (conjgCV u) -(mulgA _ u). + rewrite coset_kerr ?groupV 2?coset_kerl ?groupX //; last first. + by rewrite -mem_conjg (normsP nUP) // (subsetP sP0P). + by move/quoUP_inj->; rewrite ?nUtn ?groupM. +have expUMp u v Uu Uv := expgMn p (centsP cUU u v Uu Uv). +have sUsXp m a j n u s1 v: + is_sUs m a j n u s1 v -> is_sUs m (a ^+ p) j n (u ^+ p) s1 (v ^+ p). +- move=> Dusv; have{Dusv} [/sUs_modP Duv [Ua Uu Vv P0s1 Dusv]] := (Dusv, Dusv). + split; rewrite ?groupX //; move: P0s1 Dusv; rewrite -defP0 => /cycleP[k ->]. + rewrite conjXg -!(mulgA _ (s ^+ k)) ![s ^+ k * _]conjgC 2!mulgA -expUMp //. + rewrite {}Duv ![s ^+ m * _]conjgC !conjXg -![_ * _ * s ^- n]mulgA. + move/mulgI/(congr1 (Frobenius_aut charFp \o sigma))=> /= Duv_p. + congr (_ * _); apply/(injmP inj_sigma); rewrite ?in_PU //. + by rewrite !{1}sigmaE ?in_PU // rmorphB !rmorphMn rmorph1 in Duv_p *. +have odd_P: odd #|P| by rewrite oP odd_exp odd_p orbT. +suffices EpsiV a: a \in U -> psi a \in E -> psi (a^-1 ^ t ^+ 3) \in E. + apply/subsetP => _ /imsetP[x Ex ->]. + have /imsetP[a Ua Dx]: x \in psi @: U by rewrite im_psi; case/setIdP: Ex. + suffices: psi (a^-1 ^ t ^+ (3 * #|P|)) \in E. + rewrite Dx -psiV // -{2}(conjg1 a^-1); congr (psi (_ ^ _) \in E). + by apply/eqP; rewrite -order_dvdn orderJ dvdn_mull ?order_dvdG. + rewrite -(odd_double_half #|P|) odd_P addnC. + elim: _./2 => [|n /EpsiV/EpsiV/=]; first by rewrite EpsiV -?Dx. + by rewrite conjVg invgK -!conjgM -!expgD -!mulnSr !(groupV, nUtn) //; apply. +move=> Ua Ea; have{Ea} [b Ub Dab]: exists2 b, b \in U & psi a + psi b = 2%:R. + case/setIdP: Ea => _; rewrite -im_psi => /imsetP[b Ub Db]; exists b => //. + by rewrite -Db addrC subrK. +(* In the book k is arbitrary in Fp; however only k := 3 is used. *) +have [u2 [s2 [v2 usv2P]]] := split_sUs 3 (a * _) 2 1%N (groupM Ua (groupVr Ub)). +have{Ua} [u1 [s1 [v1 usv1P]]] := split_sUs 1%N a^-1 3 2 (groupVr Ua). +have{Ub} [u3 [s3 [v3 usv3P]]] := split_sUs 2 b 1%N 3 Ub. +pose s2def w1 w2 w3 := t * s2^-1 * t = w1 * s3 * w2 * t ^+ 2 * s1 * w3. +pose w1 := v2 ^ t^-1 * u3; pose w2 := v3 * u1 ^ t ^- 2; pose w3 := v1 * u2 ^ t. +have stXC m n: (m <= n)%N -> s ^- n ^ t ^+ m = s ^- m ^ t ^+ n * s ^- (n - m). + move/subnK=> Dn; apply/(mulgI (s ^- (n - m) * t ^+ n))/(mulIg (t ^+ (n - m))). + rewrite -{1}[in t ^+ n]Dn expgD !mulgA !mulgK -invMg -2!mulgA -!expgD. + by rewrite addnC Dn (centsP (abelem_abelian abelQ)) ?mulgA. +wlog suffices Ds2: a b u1 v1 u2 v2 u3 v3 @w1 @w2 @w3 Dab usv1P usv2P usv3P / + s2def w1 w2 w3; last first. +- apply/esym; rewrite -[_ * t]mulgA [_ * t]conjgC mulgA -(expgS _ 1) conjVg. + rewrite /w2 mulgA; apply: (canRL (mulKVg _)); rewrite 2!mulgA -conjgE. + rewrite conjMg conjgKV /w3 mulgA; apply: (canLR (mulgKV _)). + rewrite /w1 -4!mulgA (mulgA u1) (mulgA u3) conjMg -conjgM mulKg -mulgA. + have [[[Ua _ _ _ <-] [_ _ _ _ Ds2]] [Ub _ _ _ <-]] := (usv1P, usv2P, usv3P). + apply: (canLR (mulKVg _)); rewrite -!invMg -!conjMg -{}Ds2 groupV in Ua *. + rewrite -[t]expg1 2!conjMg -conjgM -expgS 2!conjMg -conjgM -expgSr mulgA. + apply: (canLR (mulgK _)); rewrite 2!invMg -!conjVg invgK invMg invgK -4!mulgA. + rewrite (mulgA _ s) stXC // mulgKV -!conjMg stXC // mulgKV -conjMg conjgM. + apply: (canLR (mulKVg _)); rewrite -2!conjVg 2!mulgA -conjMg (stXC 1%N) //. + rewrite mulgKV -conjgM -expgSr -mulgA -!conjMg; congr (_ ^ t ^+ 3). + apply/(canLR (mulKVg _))/(canLR (mulgK _))/(canLR invgK). + rewrite -!mulgA (mulgA _ b) mulgA invMg -!conjVg !invgK. + by apply/(injmP inj_sigma); rewrite 1?groupM ?sigmaE ?memJ_P. +have [[Ua Uu1 Uv1 P0s1 Dusv1] /sUs_modP-Duv1] := (usv1P, usv1P). +have [[_ Uu2 Uv2 P0s2 _] [Ub Uu3 Uv3 P0s3 _]] := (usv2P, usv3P). +suffices /(congr1 sigma): s ^+ 2 = s ^ v1 * s ^ a^-1 ^ t ^+ 3. + rewrite inE sigmaX // sigma_s sigmaM ?memJ_P -?psiE ?nUtn // => ->. + by rewrite addrK -!im_psi !mem_imset ?nUtn. +rewrite groupV in Ua; have [Hs1 Hs3]: s1 \in H /\ s3 \in H by rewrite !sP0H. +have nt_s1: s1 != 1 by apply: nt_sUs usv1P. +have nt_s3: s3 != 1 by apply: nt_sUs usv3P. +have{sUsXp} Ds2p: s2def (w1 ^+ p) (w2 ^+ p) (w3 ^+ p). + have [/sUsXp-usv1pP /sUsXp-usv2pP /sUsXp-usv3pP] := And3 usv1P usv2P usv3P. + rewrite expUMp ?groupV // !expgVn in usv1pP usv2pP. + rewrite !(=^~ conjXg _ _ p, expUMp) ?groupV -1?[t]expg1 ?nUtn ?nUtVn //. + apply: Ds2 usv1pP usv2pP usv3pP => //. + by rewrite !psiX // -!Frobenius_autE -rmorphD Dab rmorph_nat. +have{Ds2} Ds2: s2def w1 w2 w3 by apply: Ds2 usv1P usv2P usv3P. +wlog [Uw1 Uw2 Uw3]: w1 w2 w3 Ds2p Ds2 / [/\ w1 \in U, w2 \in U & w3 \in U]. + by move/(_ w1 w2 w3)->; rewrite ?(nUtVn, nUtVn 1%N, nUtn 1%N, in_group). +have{Ds2p} Dw3p: (w2 ^- p * w1 ^- p.-1 ^ s3 * w2) ^ t ^+ 2 = w3 ^+ p.-1 ^ s1^-1. + rewrite -[w1 ^+ _](mulKg w1) -[w3 ^+ _](mulgK w3) -expgS -expgSr !prednK //. + rewrite -(canLR (mulKg _) Ds2p) -(canLR (mulKg _) Ds2) 6!invMg !invgK. + by rewrite mulgA mulgK [2]lock /conjg !mulgA mulVg mul1g mulgK. +have w_id w: w \in U -> w ^+ p.-1 == 1 -> w = 1. + by move=> Uw /eqP/(canRL_in (expgK _) Uw)->; rewrite ?expg1n ?oU. +have{Uw3} Dw3: w3 = 1. + apply: w_id => //; have:= @not_splitU s1^-1^-1 s1^-1 (w3 ^+ p.-1). + rewrite !groupV mulVg eqxx andbT {2}invgK (negPf nt_s1) groupX //= => -> //. + have /tiH_P1 <-: t ^+ 2 \in P1^#. + rewrite 2!inE groupX // andbT -order_dvdn gtnNdvd // orderJ. + by rewrite odd_gt2 ?order_gt1 // orderE defP0 (oddSg sP0P). + by rewrite -mulgA -conjgE inE -{2}Dw3p memJ_conjg !in_group ?Hs1 // sUH. +have{Dw3p} Dw2p: w2 ^+ p.-1 = w1 ^- p.-1 ^ s3. + apply/(mulIg w2)/eqP; rewrite -expgSr prednK // eq_mulVg1 mulgA. + by rewrite (canRL (conjgK _) Dw3p) Dw3 expg1n !conj1g. +have{Uw1} Dw1: w1 = 1. + apply: w_id => //; have:= @not_splitU s3^-1 s3 (w1 ^- p.-1). + rewrite mulVg (negPf nt_s3) andbF -mulgA -conjgE -Dw2p !in_group //=. + by rewrite eqxx andbT eq_invg1 /= => ->. +have{w1 w2 w3 Dw1 Dw3 w_id Uw2 Dw2p Ds2} Ds2: t * s2^-1 * t = s3 * t ^+ 2 * s1. + by rewrite Ds2 Dw3 [w2]w_id ?mulg1 ?Dw2p ?Dw1 ?mul1g // expg1n invg1 conj1g. +have /centsP abP0: abelian P0 by rewrite -defP0 cycle_abelian. +have QP0ys := memJ_norm y (subsetP (commg_normr P0 Q) _ _). +have{QP0ys} memQP0 := (QP0ys, groupV, groupM); have nQ_P0 := subsetP nQP0. +have sQP0_Q: [~: Q, P0] \subset Q by rewrite commg_subl. +have /centsP abQP0 := abelianS sQP0_Q (abelem_abelian abelQ). +have{s2def} Ds312: s3 * s1 * s2 = 1. + apply/set1P; rewrite -set1gE -(coprime_TIg coQP) inE. + rewrite coset_idr ?(subsetP sP0P) ?nQ_P0 ?groupM //. + rewrite -mulgA -[s2](mulgK s) [_ * s]abP0 // -[s2](mulKVg s). + rewrite -!mulgA [s * _]mulgA [s1 * _]mulgA [s1 * _]abP0 ?groupM //. + rewrite 2!(mulgA s3) [s^-1 * _]mulgA !(morphM, morphV) ?nQ_P0 ?in_group //=. + have ->: coset Q s = coset Q t by rewrite coset_kerl ?groupV ?coset_kerr. + have nQt: t \in 'N(Q) by rewrite -(conjGid Qy) normJ memJ_conjg nQ_P0. + rewrite -morphV // -!morphM ?(nQt, groupM) ?groupV // ?nQ_P0 //= -Ds2. + by rewrite 2!mulgA mulgK mulgKV mulgV morph1. +pose x := (y ^ s3)^-1 * y ^ s^-1 * (y ^ (s * s1)^-1)^-1 * y. +have{abP0} Dx: x ^ s^-1 = x. + rewrite 3!conjMg !conjVg -!conjgM -!invMg (mulgA s) -(expgS _ 1). + rewrite [x]abQP0 ?memQP0 // [rhs in y * rhs]abQP0 ?memQP0 //. + apply/(canRL (mulKVg _)); rewrite 4!mulgA; congr (_ * _). + rewrite [RHS]abQP0 ?memQP0 //; apply/(canRL (mulgK _))/eqP. + rewrite -3!mulgA [rhs in y^-1 * rhs]abQP0 ?memQP0 // -eq_invg_sym eq_invg_mul. + apply/eqP; transitivity (t ^+ 2 * s1 * (t^-1 * s2 * t^-1) * s3); last first. + by rewrite -[s2]invgK -!invMg mulgA Ds2 -(mulgA s3) invMg mulKVg mulVg. + rewrite (canRL (mulKg _) Ds312) -2![_ * t^-1]mulgA. + have Dt1 si: si \in P0 -> t^-1 = (s^-1 ^ si) ^ y. + by move=> P0si; rewrite {2}/conjg -conjVg -(abP0 si) ?groupV ?mulKg. + by rewrite {1}(Dt1 s1) // (Dt1 s3^-1) ?groupV // -conjXg /conjg !{1}gnorm. +have{Dx memQP0} Dx1: x = 1. + apply/set1P; rewrite -set1gE; have [_ _ _ <-] := dprodP defQ. + rewrite setIAC (setIidPr sQP0_Q) inE -{2}defP0 -cycleV cent_cycle. + by rewrite (sameP cent1P commgP) commgEl Dx mulVg eqxx !memQP0. +pose t1 := s1 ^ y; pose t3 := s3 ^ y. +have{x Dx1} Ds13: s1 * (t * t1)^-1 = (t3 * t)^-1 * s3. + by apply/eqP; rewrite eq_sym eq_mulVg1 invMg invgK -Dx1 /x /conjg !gnorm. +suffices Ds1: s1 = s^-1. + rewrite -(canLR (mulKg _) (canRL (mulgKV _) Dusv1)) Ds1 Duv1. + by rewrite !invMg invgK /conjg !gnorm. +have [_ _ /trivgPn[u Uu nt_u] _ _] := Frobenius_context frobH. +apply: (conjg_inj y); apply: contraNeq nt_u. +rewrite -/t1 conjVg -/t eq_mulVg1 -invMg => nt_tt1. +have Hu := sUH u Uu; have P1tt1: t * t1 \in P1 by rewrite groupM ?memJ_conjg. +have /tiH_P1 defU: (t * t1)^-1 \in P1^# by rewrite 2!inE nt_tt1 groupV. +suffices: (u ^ s1) ^ (t * t1)^-1 \in U. + rewrite -mem_conjg nUP1 // conjgE mulgA => /(not_splitU _ _ Uu). + by rewrite groupV (negPf nt_s1) andbF mulVg eqxx andbT /= => /(_ _ _)/eqP->. +rewrite -defU inE memJ_conjg -conjgM Ds13 conjgM groupJ ?(groupJ _ Hs1) //. +by rewrite sUH // -mem_conjg nUP1 // groupM ?memJ_conjg. +Qed. + +End AppendixC3. + +Fact BGappendixC_inner_subproof : (p <= q)%N. +Proof. +have [y QP0y nUP0y] := nU_P0QP0. +by apply: Einv_gt1_le_pq E_gt1; apply: BGappendixC3_Ediv nUP0y. +Qed. + +End ExpandHypotheses. + +(* This is B & G, Appendix C, Theorem C. *) +Theorem prime_dim_normed_finField : (p <= q)%N. +Proof. +apply: wlog_neg; rewrite -ltnNge => ltqp. +have [F sigma /isomP[inj_sigma im_sigma] defP0] := fieldH. +case=> sigmaU inj_sigmaU sigmaJ. +have oF: #|F| = (p ^ q)%N by rewrite -cardsT -im_sigma card_injm. +have charFp: p \in [char F] := card_finCharP oF pr_p. +have sP0P: P0 \subset P by rewrite -defP0 subsetIl. +pose s := invm inj_sigma 1%R. +have sigma_s: sigma s = 1%R by rewrite invmK ?im_sigma ?inE. +have{defP0} defP0: <[s]> = P0. + by rewrite -morphim_cycle /= ?im_sigma ?inE // morphim_invmE. +exact: BGappendixC_inner_subproof defP0 sigmaJ. +Qed. + +End AppendixC. |
