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/PFsection1.v | |
Initial commit
Diffstat (limited to 'mathcomp/odd_order/PFsection1.v')
| -rw-r--r-- | mathcomp/odd_order/PFsection1.v | 809 |
1 files changed, 809 insertions, 0 deletions
diff --git a/mathcomp/odd_order/PFsection1.v b/mathcomp/odd_order/PFsection1.v new file mode 100644 index 0000000..dc5ce95 --- /dev/null +++ b/mathcomp/odd_order/PFsection1.v @@ -0,0 +1,809 @@ +(* (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 finset fingroup morphism. +Require Import perm automorphism quotient action zmodp center commutator. +Require Import poly cyclic pgroup nilpotent matrix mxalgebra mxrepresentation. +Require Import vector falgebra fieldext ssrnum algC rat algnum galois. +Require Import classfun character inertia integral_char vcharacter. +Require ssrint. + +(******************************************************************************) +(* This file covers Peterfalvi, Section 1: Preliminary results. *) +(******************************************************************************) + +Set Implicit Arguments. +Unset Strict Implicit. +Unset Printing Implicit Defensive. + +Import GroupScope GRing.Theory Num.Theory. +Local Open Scope ring_scope. + +Local Notation algCF := [fieldType of algC]. + +Section Main. + +Variable gT : finGroupType. + +(* This is Peterfalvi (1.1). *) +Lemma odd_eq_conj_irr1 (G : {group gT}) t : + odd #|G| -> (('chi[G]_t)^*%CF == 'chi_t) = ('chi_t == 1). +Proof. +move=> OG; apply/eqP/eqP=> [Ht | ->]; last exact: cfConjC_cfun1. +pose a := (@Zp1 1). +have Aito: + is_action <[a]> (fun (t : Iirr G) v => if v == a then conjC_Iirr t else t). + split=> [[[|[]]] //= _ t1 t2 Hj |j [[|[]]] // HH1 [[|[]]] // HH2 ] //=. + by apply: (inv_inj (@conjC_IirrK _ _)). + by rewrite conjC_IirrK. +pose ito := Action Aito. +have Acto: + is_action <[a]> (fun (c : {set gT}) v => if v == a then c^-1%g else c). + split=> [[[|[]]] //= _ t1 t2 Hj |j [[|[]]] // HH1 [[|[]]] // HH2 ] //=. + by rewrite -[t1]invgK Hj invgK. + by rewrite invgK. +pose cto := Action Acto. +have F1: [acts <[a]>, on (classes G) | cto]. + apply/subsetP=> j Hj. + rewrite !inE Hj; apply/subsetP=> u. + case/imsetP=> g GiG ->. + by rewrite inE /=; case: (_ == _) => //; + rewrite -?classVg mem_classes // ?groupV. +have F2 u x y: x \in G -> y \in cto (x ^: G) a -> 'chi_u x = 'chi_(ito u a) y. + rewrite mem_invg -{2}[y]invgK => Gx {y}/imsetP[y Gy ->]. + by rewrite -conjVg cfunJ {y Gy}//= conjC_IirrE cfunE -irr_inv invgK. +have F3: forall c, c \in classes G -> c^-1%g = c -> c = 1%g. + move=> c; case/imsetP => g GiG ->; rewrite -classVg => Hg. + move: (class_refl G g^-1); rewrite Hg; case/imsetP=> x XiG Hx. + have F4: (x ^+ 2)%g \in 'C_G[g]. + apply/subcent1P; split; rewrite ?groupM //. + apply: (mulgI (x * x * g)^-1)%g. + rewrite mulVg !invMg Hx conjgE !mulgA mulgK. + rewrite -[(_ * g * x)%g]mulgA -[(_ * (g * _))%g]mulgA -conjgE. + by rewrite -Hx mulgK mulVg. + have F5 : x \in 'C_G[g]. + suff->: (x = (x ^+ 2) ^+ (#|G| %/2).+1)%g by apply: groupX. + rewrite -expgM -[(_%/_).+1]addn1 mulnDr muln1 -{3}addn1 addnA. + move: (modn2 #|G|); rewrite {1}OG /= => HH; rewrite -{3}HH. + rewrite [(2 * _)%N]mulnC -divn_eq expgD expg1. + by move: (order_dvdG XiG); rewrite order_dvdn; move/eqP->; rewrite mul1g. + move: Hx; rewrite conjgE; case/subcent1P: F5=> _ ->. + rewrite mulgA mulVg mul1g => HH. + have F6: (g ^+ 2 == 1)%g by rewrite expgS -{1}HH expg1 mulVg. + suff: #[g] == 1%N by rewrite order_eq1; move/eqP->; apply: class1G. + move: F6 (order_gt0 g) (order_dvdG GiG); rewrite -order_dvdn. + move/(dvdn_leq (isT : (0 < 2)%N)); case: #[_]=> // [[|[]]] //. + by rewrite dvdn2 OG. +apply/eqP; case: (boolP (t == 0))=> // Hd. + by move/eqP: Hd->; rewrite irr0. +have:= card_afix_irr_classes (cycle_id a) F1 F2. +have->: #|'Fix_(classes G | cto)[a]| = 1%N. + apply: (@eq_card1 _ 1%g)=> c; apply/idP/idP; rewrite !inE. + case/andP=> GiG HH; apply/eqP; apply: F3=> //; apply/eqP. + by move/subsetP: HH; move/(_ a); rewrite !inE eqxx; apply. + move/eqP->; rewrite classes1. + apply/subsetP=> b; rewrite !inE; move/eqP=> -> /=. + by rewrite invg1. +rewrite (cardD1 (0 : Iirr _)). +have->: 0 \in 'Fix_ito[a]. + apply/afixP=> b; rewrite !inE; move/eqP->; rewrite /=. + apply: irr_inj; apply/cfunP=> g. + by rewrite conjC_IirrE cfConjCE irr0 cfun1E conjC_nat. +rewrite (cardD1 t) //. +suff->: t \in [predD1 'Fix_ito[a] & 0] by []. +rewrite inE /= Hd. +apply/afixP=> b; rewrite !inE; move/eqP->; rewrite /=. +apply: irr_inj; apply/cfunP=> g. +by rewrite conjC_IirrE Ht. +Qed. + +Variables G H : {group gT}. + +(* This is Peterfalvi (1.2). *) +Lemma not_in_ker_char0 t g : g \in G -> + H <| G -> ~~ (H \subset cfker 'chi[G]_t) -> 'C_H[g] = 1%g -> 'chi_t g = 0. +Proof. +move=> GiG HnG nHsC CH1. +have: (#|'C_G[g]| <= #|'C_(G/H)[coset H g]|)%N. + suff->: #|'C_G[g]| = #|'C_G[g] / H|%G. + by apply: (subset_leq_card (quotient_subcent1 H G g)). + apply: card_isog. + apply: isog_trans (second_isog _); last first. + apply: subset_trans (normal_norm HnG). + by apply: subcent1_sub. + suff->: H :&: 'C_G[g] = 1%g by exact: quotient1_isog. + rewrite -CH1. + apply/setP=> h; rewrite inE. + apply/andP/subcent1P; case=> H1 H2; split=> //. + by move/subcent1P: H2; case. + apply/subcent1P; split=> //. + by apply: (subsetP (normal_sub HnG)). +have F1: coset H g \in (G / H)%g by exact: mem_quotient. +rewrite -leC_nat. +have:= second_orthogonality_relation g GiG. +rewrite mulrb class_refl => <-. +have:= second_orthogonality_relation (coset H g) F1. +rewrite mulrb class_refl => <-; rewrite -!(eq_bigr _ (fun _ _ => normCK _)). +rewrite sum_norm_irr_quo // (bigID (fun i => H \subset cfker 'chi_i)) //=. +set S := \sum_(i | ~~ _) _; set S' := \sum_(i | _) _ => HH. +have /eqP F2: S == 0. + rewrite eqr_le -(ler_add2l S') addr0 HH /=. + by apply: sumr_ge0 => j _; rewrite mulr_ge0 ?normr_ge0. +apply/eqP; have: `|'chi_t g| ^+ 2 == 0. + apply/eqP; apply: (psumr_eq0P _ F2) nHsC => j _. + by rewrite mulr_ge0 ?normr_ge0. +by rewrite mulf_eq0 orbb normr_eq0. +Qed. + +(* This is Peterfalvi (1.3)(a). *) +Lemma equiv_restrict_compl A m (Phi : m.-tuple 'CF(H)) (mu : 'CF(G)) d : + H \subset G -> A <| H -> basis_of 'CF(H, A) Phi -> + ({in A, mu =1 \sum_i d i *: 'chi_i} <-> + (forall j : 'I_m, + \sum_i '[Phi`_j, 'chi_i] * (d i)^* = '['Ind[G] Phi`_j, mu])). +Proof. +move=> sHG nsAH BPhi; have [sAH nAH] := andP nsAH. +have APhi (i : 'I_m) : Phi`_i \in 'CF(H, A). + by apply: (basis_mem BPhi _); apply: mem_nth; rewrite size_tuple. +pose D := 'Res[H] mu - \sum_i d i *: 'chi_i. +transitivity (D \in 'CF(H, H :\: A)). + split=> [A'D | /cfun_onP A'D x Ax]. + apply/cfun_onP=> x; rewrite inE negb_and negbK. + case/orP=> [Ax | /cfun0-> //]; rewrite !cfunE -A'D //. + by rewrite cfResE ?subrr ?(subsetP sAH). + have:= A'D x; rewrite !cfunE !inE Ax => /(_ isT)/(canRL (subrK _)). + by rewrite add0r cfResE // ?(subsetP sAH). +have F0 (j : 'I_m) : + (\sum_i '[Phi`_j, 'chi_i] * (d i)^* == '['Ind Phi`_j, mu]) + = ('[Phi`_j, D] == 0). + rewrite raddfB raddf_sum /= Frobenius_reciprocity subr_eq0 eq_sym. + by congr (_ == _); apply: eq_bigr=> i _; rewrite cfdotZr mulrC. +split=> [HH j | HH]. + by apply/eqP; rewrite F0; apply/eqP; apply: cfdot_complement. +have{F0} F1 (j : 'I_m) : '[Phi`_j, D]_H = 0. + by have/eqP := HH j; rewrite F0 => /eqP. +have: (D \in 'CF(H))%VS by rewrite memvf. +rewrite -(cfun_complement nsAH) => /memv_addP[f Cf [g Cg defD]]. +have: '[f, f + g] = 0. + rewrite -defD (coord_basis BPhi Cf) cfdot_suml. + by rewrite big1 // => i _; rewrite cfdotZl F1 mulr0. +rewrite raddfD /= {1}(cfdot_complement Cf Cg) addr0 => /eqP. +by rewrite cfnorm_eq0 defD => /eqP->; rewrite add0r. +Qed. + +(* This is Peterfalvi (1.3)(b). *) +Lemma equiv_restrict_compl_ortho A m (Phi : m.-tuple 'CF(H)) mu_ : + H \subset G -> A <| H -> basis_of 'CF(H, A) Phi -> + (forall i j, '[mu_ i, mu_ j] = (i == j)%:R) -> + (forall j : 'I_m, 'Ind[G] Phi`_j = \sum_i '[Phi`_j, 'chi_i] *: mu_ i) -> + [/\ forall i, {in A, mu_ i =1 'chi_i} + & forall mu, (forall i, '[mu, mu_ i] = 0) -> {in A, forall x, mu x = 0}]. +Proof. +move=> HsG nsAH /equiv_restrict_compl Phi_A Mo IP; split=> [/= i | mu Cmu x Ax]. + have->: 'chi[H]_i = \sum_j (j == i)%:R *: 'chi_j. + rewrite (bigD1 i) //= eqxx scale1r big1 ?addr0 // => j /negPf->. + by rewrite scale0r. + apply/Phi_A=> // j; rewrite IP cfdot_suml. + by apply: eq_bigr=> k _; rewrite cfdotZl rmorph_nat Mo. +transitivity ((\sum_j 0 *: 'chi[H]_j) x); last first. + by rewrite sum_cfunE big1 // => j _; rewrite cfunE mul0r. +move: x Ax; apply/Phi_A=> // j. +rewrite -mulr_suml rmorph0 mulr0 IP cfdot_suml big1 // => k _. +by rewrite cfdotZl [d in _ * d]cfdotC Cmu rmorph0 mulr0. +Qed. + +Let vchar_isometry_base3 f f' : + f \in 'Z[irr G, G^#] -> '[f]_G = 2%:R -> + f' \in 'Z[irr G, G^#] -> '[f']_G = 2%:R -> + '[f, f'] = 1 -> + exists es : _ * bool, let: (i, j, k, epsilon) := es in + [/\ f = (-1) ^+ epsilon *: ('chi_j - 'chi_i), + f' = (-1) ^+ epsilon *: ('chi_j - 'chi_k) + & uniq [:: i; j; k]]. +Proof. +move=> Hf H2f Hf1 H2f1. +have [j [i neq_ij ->]] := vchar_norm2 Hf H2f. +have [j' [k neq_kj' ->]] := vchar_norm2 Hf1 H2f1. +rewrite cfdotBl !cfdotBr !cfdot_irr opprB addrAC !addrA. +do 2!move/(canRL (subrK _)); rewrite -(natrD _ 1) -!natrD => /eqP. +rewrite eqr_nat; have [eq_jj' | neq_jj'] := altP (j =P j'). + rewrite (eq_sym j) -eq_jj' {1}eq_jj' (negbTE neq_ij) (negbTE neq_kj'). + rewrite eqSS (can_eq oddb) => /eqP neq_ik; exists (i, j, k, false). + by rewrite !scaler_sign /= !inE neq_ik orbF neq_ij eq_sym eq_jj' neq_kj'. +case: (i =P k) => // eq_ik; exists (j, i, j', true). +rewrite !scaler_sign !opprB /= !inE eq_sym negb_or neq_ij neq_jj'. +by rewrite eq_ik neq_kj'. +Qed. + +Let vchar_isometry_base4 (eps : bool) i j k n m : + let f1 := 'chi_j - 'chi_i in + let f2 := 'chi_k - 'chi_i in + let f3 := 'chi_n - 'chi_m in + j != k -> '[f3, f1]_G = (-1) ^+ eps -> '[f3, f2] = (-1) ^+ eps -> + if eps then n == i else m == i. +Proof. +move=> /= Hjk; wlog ->: eps n m / eps = false. + case: eps; last exact; move/(_ false m n)=> IH nm_ji nm_ki. + by apply: IH; rewrite // -opprB cfdotNl (nm_ji, nm_ki) opprK. +rewrite !cfdotBl !cfdotBr !cfdot_irr !opprB addrAC addrA. +do 2!move/(canRL (subrK _)); rewrite -(natrD _ 1) -!natrD. +move/(can_inj natCK); case: (m == i) => //. +case: eqP => // ->; case: (j == i) => // _. +rewrite subr0 add0r => /(canRL (subrK _)); rewrite -(natrD _ 1). +by move/(can_inj natCK); rewrite (negbTE Hjk). +Qed. + +(* This is Peterfalvi (1.4). *) +Lemma vchar_isometry_base m L (Chi : m.-tuple 'CF(H)) + (tau : {linear 'CF(H) -> 'CF(G)}) : + (1 < m)%N -> {subset Chi <= irr H} -> free Chi -> + (forall chi, chi \in Chi -> chi 1%g = Chi`_0 1%g) -> + (forall i : 'I_m, (Chi`_i - Chi`_0) \in 'CF(H, L)) -> + {in 'Z[Chi, L], isometry tau, to 'Z[irr G, G^#]} -> + exists2 mu : m.-tuple (Iirr G), + uniq mu + & exists epsilon : bool, forall i : 'I_m, + tau (Chi`_i - Chi`_0) = (-1) ^+ epsilon *: ('chi_(mu`_i) - 'chi_(mu`_0)). +Proof. +case: m Chi => [|[|m]] // Chi _ irrChi Chifree Chi1 ChiCF [iso_tau Ztau]. +rewrite -(tnth_nth 0 _ 0); set chi := tnth Chi. +have chiE i: chi i = Chi`_i by rewrite -tnth_nth. +have inChi i: chi i \in Chi by exact: mem_tnth. +have{irrChi} irrChi i: chi i \in irr H by exact: irrChi. +have eq_chi i j: (chi i == chi j) = (i == j). + by rewrite /chi !(tnth_nth 0) nth_uniq ?size_tuple ?free_uniq. +have dot_chi i j: '[chi i, chi j] = (i == j)%:R. + rewrite -eq_chi; have [/irrP[{i}i ->] /irrP[{j}j ->]] := (irrChi i,irrChi j). + by rewrite cfdot_irr inj_eq //; exact: irr_inj. +pose F i j := chi i - chi j. +have DF i j : F i j = F i 0 - F j 0 by rewrite /F opprB addrA subrK. +have ZF i j: F i j \in 'Z[Chi, L]. + by rewrite zchar_split rpredB ?mem_zchar // DF memvB // /F !chiE. +have htau2 i j: i != j -> '[tau (F i j)] = 2%:R. + rewrite iso_tau // cfnormB -cfdotC !dot_chi !eqxx eq_sym => /negbTE->. + by rewrite -!natrD subr0. +have htau1 i j: j != 0 -> j != i -> i != 0 -> '[tau (F i 0), tau (F j 0)] = 1. + rewrite iso_tau // cfdotBl !cfdotBr opprB !dot_chi !(eq_sym j). + by do 3!move/negbTE->; rewrite !subr0 add0r. +have [m0 | nz_m] := boolP (m == 0%N). + rewrite -2!eqSS eq_sym in m0; move: (htau2 1 0 isT). + case/(vchar_norm2 (Ztau _ (ZF 1 0))) => [k1 [k0 neq_k01 eq_mu]]. + pose mu := @Tuple _ _ [:: k0; k1] m0. + exists mu; first by rewrite /= andbT inE. + exists false => i; rewrite scale1r chiE. + have: (i : nat) \in iota 0 2 by rewrite mem_iota (eqP m0) (valP i). + rewrite !inE; case/pred2P=> ->; first by rewrite !subrr linear0. + by rewrite -eq_mu /F !chiE. +have m_gt2: (2 < m.+2)%N by rewrite !ltnS lt0n. +pose i2 := Ordinal m_gt2. +case: (@vchar_isometry_base3 (tau (F 1 0)) (tau (F i2 0))); auto. +case=> [[[k1 k0] k2] e] []; set d := (-1) ^+ e => eq10 eq20. +rewrite /= !inE => /and3P[/norP[nek10 nek12]]; rewrite eq_sym => nek20 _. +have muP i: + {k | (i == 0) ==> (k == k0) & tau (F i 0) == d *: ('chi_k0 - 'chi_k)}. +- apply: sig2W; have [-> | nei0] := altP (i =P 0). + by exists k0; rewrite ?eqxx // /F !subrr !linear0. + have /(vchar_norm2 (Ztau _ (ZF i 0)))[k [k' nekk' eqFkk']] := htau2 i 0 nei0. + have [-> | neq_i1] := eqVneq i 1; first by exists k1; rewrite // -eq10. + have [-> | neq_i2] := eqVneq i i2; first by exists k2; rewrite // -eq20. + have:= @vchar_isometry_base4 (~~ e) k0 k1 k2 k k' nek12. + have ZdK u v w: '[u, v - w]_G = (-1) ^+ (~~ e) * '[u, d *: (w - v)]. + rewrite cfdotZr rmorph_sign mulrA -signr_addb addNb addbb mulN1r. + by rewrite -cfdotNr opprB. + rewrite -eqFkk' ZdK -eq10 {}ZdK -eq20 !htau1 //; try by rewrite eq_sym. + move/(_ (mulr1 _) (mulr1 _)); rewrite /d eqFkk'. + by case e => /eqP <-; [exists k | exists k']; rewrite ?scaler_sign ?opprB. +pose mu := [tuple of [seq s2val (muP i) | i <- ord_tuple m.+2]]; exists mu. + rewrite map_inj_uniq ?enum_uniq // => i j. + case: (muP i) (muP j) => /= ki _ /eqP eq_i0 [/= kj _ /eqP eq_j0] eq_kij. + apply/eqP; rewrite -eq_chi -subr_eq0 -cfnorm_eq0 -iso_tau ?ZF //. + rewrite -[chi i](subrK (chi 0)) -addrA linearD eq_i0 eq_kij -eq_j0. + by rewrite -linearD -opprB subrr !raddf0. +exists (~~ e) => i; rewrite -addbT signr_addb -/d -scalerA scaleN1r opprB. +rewrite -!tnth_nth -/(F i 0) tnth_map tnth_ord_tuple. +suffices /= ->: mu`_0 = k0 by case: (muP i) => /= k _ /eqP. +rewrite -(tnth_nth 0 _ 0) tnth_map tnth_ord_tuple. +by case: (muP 0) => /= k /(k =P k0). +Qed. + +(* This is Peterfalvi (1.5)(a). *) +Lemma cfResInd_sum_cfclass t : H <| G -> + 'Res[H] ('Ind[G] 'chi_t) + = #|'I_G['chi_t] : H|%:R *: \sum_(xi <- ('chi_t ^: G)%CF) xi. +Proof. +set T := 'I_G['chi_t] => nsHG; have [sHG nHG] := andP nsHG. +apply/cfun_inP=> h Hh; rewrite cfResE ?cfIndE // cfunE sum_cfunE. +apply: (canLR (mulKf (neq0CG H))). +rewrite mulrA -natrM Lagrange ?sub_Inertia //= -/T reindex_cfclass //=. +rewrite mulr_sumr [s in _ = s]big_mkcond /= (reindex_inj invg_inj). +rewrite (partition_big (conjg_Iirr t) xpredT) //=; apply: eq_bigr => i _. +have [[y Gy chi_i] | not_i_t] := cfclassP _ _ _; last first. + apply: big1 => z; rewrite groupV => /andP[Gz /eqP def_i]. + by case: not_i_t; exists z; rewrite // -def_i conjg_IirrE. +rewrite -(card_rcoset _ y) mulr_natl -sumr_const; apply: eq_big => z. + rewrite -(inj_eq irr_inj) conjg_IirrE chi_i mem_rcoset inE groupMr ?groupV //. + apply: andb_id2l => Gz; rewrite eq_sym (cfConjg_eqE _ nsHG) //. + by rewrite mem_rcoset inE groupM ?groupV. +rewrite groupV => /andP[Gz /eqP <-]. +by rewrite conjg_IirrE cfConjgE ?(subsetP nHG). +Qed. + +(* This is Peterfalvi (1.5)(b), main formula. *) +Lemma cfnorm_Ind_irr t : + H <| G -> '['Ind[G] 'chi[H]_t] = #|'I_G['chi_t] : H|%:R. +Proof. +set r := _%:R => HnG; have HsG := normal_sub HnG. +rewrite -Frobenius_reciprocity cfResInd_sum_cfclass //= cfdotZr rmorph_nat -/r. +rewrite reindex_cfclass // cfdot_sumr (bigD1 t) ?cfclass_refl //= cfnorm_irr. +rewrite big1 ?addr0 ?mulr1 // => j /andP[_ /negbTE]. +by rewrite eq_sym cfdot_irr => ->. +Qed. + +(* This is Peterfalvi (1.5)(b), irreducibility remark. *) +Lemma inertia_Ind_irr t : + H <| G -> 'I_G['chi[H]_t] \subset H -> 'Ind[G] 'chi_t \in irr G. +Proof. +rewrite -indexg_eq1 => nsHG /eqP r1. +by rewrite irrEchar cfInd_char ?irr_char //= cfnorm_Ind_irr ?r1. +Qed. + +(* This is Peterfalvi (1.5)(c). *) +Lemma cfclass_Ind_cases t1 t2 : H <| G -> + if 'chi_t2 \in ('chi[H]_t1 ^: G)%CF + then 'Ind[G] 'chi_t1 = 'Ind[G] 'chi_t2 + else '['Ind[G] 'chi_t1, 'Ind[G] 'chi_t2] = 0. +Proof. +move=> nsHG; have [/cfclass_Ind-> // | not_ch1Gt2] := ifPn. +rewrite -Frobenius_reciprocity cfResInd_sum_cfclass // cfdotZr rmorph_nat. +rewrite cfdot_sumr reindex_cfclass // big1 ?mulr0 // => j; rewrite cfdot_irr. +case: eqP => // <- /idPn[]; apply: contra not_ch1Gt2 => /cfclassP[y Gy ->]. +by apply/cfclassP; exists y^-1%g; rewrite ?groupV ?cfConjgK. +Qed. + +(* Useful consequences of (1.5)(c) *) +Lemma not_cfclass_Ind_ortho i j : + H <| G -> ('chi_i \notin 'chi_j ^: G)%CF -> + '['Ind[G, H] 'chi_i, 'Ind[G, H] 'chi_j] = 0. +Proof. by move/(cfclass_Ind_cases i j); rewrite cfclass_sym; case: ifP. Qed. + +Lemma cfclass_Ind_irrP i j : + H <| G -> + reflect ('Ind[G, H] 'chi_i = 'Ind[G, H] 'chi_j) ('chi_i \in 'chi_j ^: G)%CF. +Proof. +move=> nsHG; have [sHG _] := andP nsHG. +case: ifP (cfclass_Ind_cases j i nsHG) => [|_ Oji]; first by left. +right=> eq_chijG; have /negP[]: 'Ind[G] 'chi_i != 0 by exact: Ind_irr_neq0. +by rewrite -cfnorm_eq0 {1}eq_chijG Oji. +Qed. + +Lemma card_imset_Ind_irr (calX : {set Iirr H}) : + H <| G -> {in calX, forall i, 'Ind 'chi_i \in irr G} -> + {in calX & G, forall i y, conjg_Iirr i y \in calX} -> + #|calX| = (#|G : H| * #|[set cfIirr ('Ind[G] 'chi_i) | i in calX]|)%N. +Proof. +move=> nsHG irrIndX sXGX; have [sHG _] := andP nsHG; set f := fun i => cfIirr _. +rewrite -sum1_card (partition_big_imset f) /= mulnC -sum_nat_const. +apply: eq_bigr => _ /imsetP[i Xi ->]; transitivity (size (cfclass 'chi_i G)). + rewrite -sum1_size reindex_cfclass //; apply: eq_bigl => j. + case Xj: (j \in calX). + rewrite -(inj_eq irr_inj) !(cfIirrPE irrIndX) //. + exact/eqP/cfclass_Ind_irrP. + apply/esym/(contraFF _ Xj)=> /cfclassP[y Gy Dj]. + by rewrite -conjg_IirrE in Dj; rewrite (irr_inj Dj) sXGX. +rewrite -(Lagrange_index (Inertia_sub G 'chi_i)) ?sub_Inertia //. +rewrite -size_cfclass ((#|_ : _| =P 1)%N _) ?muln1 // -eqC_nat. +by rewrite -cfnorm_Ind_irr // -(cfIirrPE irrIndX) ?cfnorm_irr. +Qed. + +(* This is Peterfalvi (1.5)(d). *) +Lemma scaled_cfResInd_sum_cfclass t : H <| G -> + let chiG := 'Ind[G] 'chi_t in + (chiG 1%g / '[chiG]) *: 'Res[H] chiG + = #|G : H|%:R *: (\sum_(xi <- ('chi_t ^: G)%CF) xi 1%g *: xi). +Proof. +move=> nsHG chiG; have [sHG _] := andP nsHG. +rewrite cfResInd_sum_cfclass // cfnorm_Ind_irr // scalerA cfInd1 //. +rewrite divfK ?pnatr_eq0 -?lt0n // -scalerA linear_sum !reindex_cfclass //=. +congr (_ *: _); apply: eq_bigr => _ /cfclassP[y _ ->]. +by rewrite cfConjg1. +Qed. + +(* This is Peterfalvi (1.5)(e). *) +Lemma odd_induced_orthogonal t : + H <| G -> odd #|G| -> t != 0 -> + '['Ind[G, H] 'chi_t, ('Ind[G] 'chi_t)^*] = 0. +Proof. +move=> nsHG oddG nz_t; have [sHG _] := andP nsHG. +have:= cfclass_Ind_cases t (conjC_Iirr t) nsHG. +rewrite conjC_IirrE conj_cfInd; case: cfclassP => // [[g Gg id_cht]]. +have oddH: odd #|H| := pgroup.oddSg sHG oddG. +case/eqP: nz_t; apply: irr_inj; rewrite irr0. +apply/eqP; rewrite -odd_eq_conj_irr1 // id_cht; apply/eqP. +have F1: ('chi_t ^ (g ^+ 2))%CF = 'chi_t. + rewrite (cfConjgM _ nsHG) // -id_cht -conj_cfConjg -id_cht. + exact: cfConjCK. +suffices /eqP->: g == ((g ^+ 2) ^+ #|G|./2.+1)%g. + elim: _./2.+1 => [|n IHn]; first exact: cfConjgJ1. + by rewrite expgS (cfConjgM _ nsHG) ?groupX // F1. +rewrite eq_mulVg1 expgS -expgM mul2n -mulgA mulKg -expgS -order_dvdn. +by rewrite -add1n -[1%N](congr1 nat_of_bool oddG) odd_double_half order_dvdG. +Qed. + +(* This is Peterfalvi (1.6)(a). *) +Lemma sub_cfker_Ind_irr A i : + H \subset G -> G \subset 'N(A) -> + (A \subset cfker ('Ind[G, H] 'chi_i)) = (A \subset cfker 'chi_i). +Proof. by move=> sHG nAG; rewrite cfker_Ind_irr ?sub_gcore. Qed. + +(* Some consequences and related results. *) +Lemma sub_cfker_Ind (A : {set gT}) chi : + A \subset H -> H \subset G -> G \subset 'N(A) -> chi \is a character -> + (A \subset cfker ('Ind[G, H] chi)) = (A \subset cfker chi). +Proof. +move=> sAH sHG nAG Nchi; have [-> | nz_chi] := eqVneq chi 0. + by rewrite raddf0 !cfker_cfun0 !(subset_trans sAH). +by rewrite cfker_Ind ?sub_gcore. +Qed. + +Lemma cfInd_irr_eq1 i : + H <| G -> ('Ind[G, H] 'chi_i == 'Ind[G, H] 1) = (i == 0). +Proof. +case/andP=> sHG nHG; apply/eqP/idP=> [chi1 | /eqP->]; last by rewrite irr0. +rewrite -subGcfker -(sub_cfker_Ind_irr _ sHG nHG) chi1 -irr0. +by rewrite sub_cfker_Ind_irr ?cfker_irr0. +Qed. + +Lemma sub_cfker_constt_Res_irr (A : {set gT}) i j : + j \in irr_constt ('Res[H, G] 'chi_i) -> + A \subset H -> H \subset G -> G \subset 'N(A) -> + (A \subset cfker 'chi_j) = (A \subset cfker 'chi_i). +Proof. +move=> iHj sAH sHG nAG; apply/idP/idP=> kerA. + have jGi: i \in irr_constt ('Ind 'chi_j) by rewrite constt_Ind_Res. + rewrite (subset_trans _ (cfker_constt _ jGi)) ?cfInd_char ?irr_char //=. + by rewrite sub_cfker_Ind_irr. +rewrite (subset_trans _ (cfker_constt _ iHj)) ?cfRes_char ?irr_char //=. +by rewrite cfker_Res ?irr_char // subsetI sAH. +Qed. + +Lemma sub_cfker_constt_Ind_irr (A : {set gT}) i j : + i \in irr_constt ('Ind[G, H] 'chi_j) -> + A \subset H -> H \subset G -> G \subset 'N(A) -> + (A \subset cfker 'chi_j) = (A \subset cfker 'chi_i). +Proof. by rewrite constt_Ind_Res; apply: sub_cfker_constt_Res_irr. Qed. + +(* This is a stronger version of Peterfalvi (1.6)(b). *) +Lemma cfIndMod (K : {group gT}) (phi : 'CF(H / K)) : + K \subset H -> H \subset G -> K <| G -> + 'Ind[G] (phi %% K)%CF = ('Ind[G / K] phi %% K)%CF. +Proof. by move=> sKH sHG /andP[_ nKG]; rewrite cfIndMorph ?ker_coset. Qed. + +Lemma cfIndQuo (K : {group gT}) (phi : 'CF(H)) : + K \subset cfker phi -> H \subset G -> K <| G -> + 'Ind[G / K] (phi / K)%CF = ('Ind[G] phi / K)%CF. +Proof. +move=> kerK sHG nsKG; have sKH := subset_trans kerK (cfker_sub phi). +have nsKH := normalS sKH sHG nsKG. +by apply: canRL (cfModK nsKG) _; rewrite -cfIndMod // cfQuoK. +Qed. + +Section IndSumInertia. + +Variable s : Iirr H. + +Let theta := 'chi_s. +Let T := 'I_G[theta]. +Let calA := irr_constt ('Ind[T] theta). +Let calB := irr_constt ('Ind[G] theta). +Let AtoB (t : Iirr T) := Ind_Iirr G t. +Let e_ t := '['Ind theta, 'chi[T]_t]. + +Hypothesis nsHG: H <| G. +(* begin hide *) +Let sHG : H \subset G. Proof. exact: normal_sub. Qed. +Let nHG : G \subset 'N(H). Proof. exact: normal_norm. Qed. +Let nsHT : H <| T. Proof. exact: normal_Inertia. Qed. +Let sHT : H \subset T. Proof. exact: normal_sub. Qed. +Let nHT : T \subset 'N(H). Proof. exact: normal_norm. Qed. +Let sTG : T \subset G. Proof. exact: subsetIl. Qed. +(* end hide *) + +(* This is Peterfalvi (1.7)(a). *) +Lemma cfInd_sum_Inertia : + [/\ {in calA, forall t, 'Ind 'chi_t \in irr G}, + {in calA, forall t, 'chi_(AtoB t) = 'Ind 'chi_t}, + {in calA &, injective AtoB}, + AtoB @: calA =i calB + & 'Ind[G] theta = \sum_(t in calA) e_ t *: 'Ind 'chi_t]. +Proof. +have [AtoBirr AtoBinj defB _ _] := constt_Inertia_bijection s nsHG. +split=> // [i Ai|]; first exact/cfIirrE/AtoBirr. +rewrite -(cfIndInd _ sTG sHT) {1}['Ind theta]cfun_sum_constt linear_sum. +by apply: eq_bigr => i _; rewrite linearZ. +Qed. + +Hypothesis abTbar : abelian (T / H). + +(* This is Peterfalvi (1.7)(b). *) +Lemma cfInd_central_Inertia : + exists2 e, [/\ e \in Cnat, e != 0 & {in calA, forall t, e_ t = e}] + & [/\ 'Ind[G] theta = e *: \sum_(j in calB) 'chi_j, + #|calB|%:R = #|T : H|%:R / e ^+ 2 + & {in calB, forall i, 'chi_i 1%g = #|G : T|%:R * e * theta 1%g}]. +Proof. +have [t1 At1] := constt_cfInd_irr s sHT; pose psi1 := 'chi_t1. +pose e := '['Ind theta, psi1]. +have NthT: 'Ind[T] theta \is a character by rewrite cfInd_char ?irr_char. +have Ne: e \in Cnat by rewrite Cnat_cfdot_char_irr. +have Dpsi1H: 'Res[H] psi1 = e *: theta. + have psi1Hs: s \in irr_constt ('Res psi1) by rewrite -constt_Ind_Res. + rewrite (Clifford_Res_sum_cfclass nsHT psi1Hs) cfclass_invariant ?subsetIr //. + by rewrite big_seq1 cfdot_Res_l cfdotC conj_Cnat. +have linL j: 'chi[T / H]_j \is a linear_char by apply/char_abelianP. +have linLH j: ('chi_j %% H)%CF \is a linear_char := cfMod_lin_char (linL j). +pose LtoT (j : Iirr (T / H)) := mul_mod_Iirr t1 j. +have LtoTE j: 'chi_(LtoT j) = ('chi_j %% H)%CF * psi1. + by rewrite !(mod_IirrE, cfIirrE) // mul_lin_irr ?mem_irr ?cfMod_lin_char. +have psiHG: 'Ind ('Res[H] psi1) = \sum_j 'chi_(LtoT j). + transitivity ((cfReg (T / H) %% H)%CF * psi1); last first. + rewrite cfReg_sum linear_sum /= mulr_suml; apply: eq_bigr => i _. + by rewrite LtoTE // lin_char1 ?scale1r. + apply/cfun_inP=> x Tx; rewrite cfunE cfModE // cfRegE mulrnAl mulrb. + rewrite (sameP eqP (kerP _ (subsetP nHT x Tx))) ker_coset. + case: ifPn => [Hx | H'x]; last by rewrite (cfun_on0 (cfInd_normal _ _)). + rewrite card_quotient // -!(cfResE _ sHT) // cfRes_Ind_invariant ?cfunE //. + by rewrite -subsetIidl (subset_trans _ (sub_inertia_Res _ _)) ?sub_Inertia. +have imLtoT: {subset calA <= codom LtoT}. + move=> t At; apply/codomP/exists_eqP. + have{At}: t \in irr_constt ('Ind ('Res[H] 'chi_t1)). + by rewrite Dpsi1H linearZ irr_consttE cfdotZl mulf_neq0. + apply: contraR; rewrite negb_exists => /forallP imL't. + by rewrite psiHG cfdot_suml big1 // => j _; rewrite cfdot_irr mulrb ifN_eqC. +have De_ t: t \in calA -> e_ t = e. + case/imLtoT/codomP=> j ->; rewrite /e_ LtoTE /e -!cfdot_Res_r rmorphM /=. + by rewrite cfRes_sub_ker ?cfker_mod // mulr_algl lin_char1 ?scale1r. +have{imLtoT} A_1 t: t \in calA -> 'chi_t 1%g = e * theta 1%g. + case/imLtoT/codomP=> j ->; rewrite LtoTE //= cfunE. + by rewrite (lin_char1 (linLH j)) mul1r -(cfRes1 H) Dpsi1H cfunE. +exists e => //; have [_ defAtoB injAtoB imAtoB ->] := cfInd_sum_Inertia. +rewrite -(eq_bigl _ _ imAtoB) -(eq_card imAtoB) big_imset //= scaler_sumr. +split=> [||i]; first by apply: eq_bigr => t2 At2; rewrite De_ ?defAtoB. + apply: (mulIf (irr1_neq0 s)); rewrite mulrAC -cfInd1 // mulr_natl mulrC invfM. + rewrite ['Ind _]cfun_sum_constt sum_cfunE mulr_sumr card_in_imset //. + rewrite -sumr_const; apply: eq_bigr => t At. + by rewrite -mulrA -/(e_ t) De_ // cfunE A_1 ?mulKf. +by rewrite -imAtoB => /imsetP[t At ->]; rewrite defAtoB ?cfInd1 ?A_1 ?mulrA. +Qed. + +(* This is Peterfalvi (1.7)(c). *) +Lemma cfInd_Hall_central_Inertia : + Hall T H -> + [/\ 'Ind[G] theta = \sum_(i in calB) 'chi_i, #|calB| = #|T : H| + & {in calB, forall i, 'chi_i 1%g = #|G : T|%:R * theta 1%g}]. +Proof. +case/andP=> _ hallH; have [e [_ _ De]] := cfInd_central_Inertia. +suffices ->: e = 1. + by case=> -> /eqP; rewrite scale1r expr1n divr1 mulr1 eqC_nat => /eqP. +suffices{De} [t Dtheta]: exists i, 'Res[H, T] 'chi_i = theta. + have e_t_1: e_ t = 1 by rewrite /e_ -cfdot_Res_r Dtheta cfnorm_irr. + by rewrite -(De t) // irr_consttE -/(e_ t) e_t_1 oner_eq0. +have ITtheta: T \subset 'I[theta] := subsetIr _ _. +have solT: solvable (T / H) := abelian_sol abTbar. +have [|t []] := extend_solvable_coprime_irr nsHT solT ITtheta; last by exists t. +rewrite coprime_sym coprime_mull !(coprime_dvdl _ hallH) ?cfDet_order_dvdG //. +by rewrite -dvdC_nat !CdivE truncCK ?Cnat_irr1 // dvd_irr1_cardG. +Qed. + +End IndSumInertia. + +(* This is Peterfalvi (1.8). *) +Lemma irr1_bound_quo (B C D : {group gT}) i : + B <| C -> B \subset cfker 'chi[G]_i -> + B \subset D -> D \subset C -> C \subset G -> (D / B \subset 'Z(C / B))%g -> + 'chi_i 1%g <= #|G : C|%:R * sqrtC #|C : D|%:R. +Proof. +move=> BnC BsK BsD DsC CsG QsZ. +case: (boolP ('Res[C] 'chi_i == 0))=> [HH|]. + have: ('Res[C] 'chi_i) 1%g = 0 by rewrite (eqP HH) cfunE. + by rewrite cfResE // => HH1; case/eqP: (irr1_neq0 i). +have IC := cfRes_char C (irr_char i). +case/neq0_has_constt=> i1 Hi1. +have CIr: i \in irr_constt ('Ind[G] 'chi_i1). + by rewrite inE /= -Frobenius_reciprocity /= cfdotC conjC_eq0. +have BsKi : B \subset cfker 'chi_i1. + suff BsKri: B \subset cfker ('Res[C] 'chi_i). + by apply: (subset_trans BsKri); exact: (cfker_constt _ Hi1). + apply/subsetP=> g GiG. + have F: g \in C by rewrite (subsetP (subset_trans BsD _)). + rewrite cfkerEchar // inE F !cfResE //. + by move: (subsetP BsK _ GiG); rewrite cfkerEirr inE. +pose i2 := quo_Iirr B i1. +have ZsC: 'Z(C / B)%g \subset 'Z('chi_i2)%CF. + by rewrite -(cap_cfcenter_irr (C / B)); apply: bigcap_inf. +have CBsH: C :&: B \subset D. + apply/subsetP=> g; rewrite inE; case/andP=> _ HH. + by apply: (subsetP (BsD)). +have I1B: 'chi_i1 1%g ^+ 2 <= #|C : D|%:R. + case: (irr1_bound i2)=> HH _; move: HH. + have ->: 'chi_i2 1%g = 'chi_i1 1%g. + by rewrite quo_IirrE // -(coset_id (group1 B)) cfQuoE. + move/ler_trans; apply. + rewrite ler_nat // -(index_quotient_eq CBsH) ?normal_norm //. + rewrite -(@leq_pmul2l #|'Z('chi_i2)%CF|) ?cardG_gt0 ?cfcenter_sub //. + rewrite Lagrange ?quotientS ?cfcenter_sub //. + rewrite -(@leq_pmul2l #|(D / B)%g|) ?cardG_gt0 //. + rewrite mulnA mulnAC Lagrange ?quotientS //. + rewrite mulnC leq_pmul2l ?cardG_gt0 // subset_leq_card //. + exact: subset_trans QsZ ZsC. +have IC': 'Ind[G] 'chi_i1 \is a character := cfInd_char G (irr_char i1). +move: (char1_ge_constt IC' CIr); rewrite cfInd1 //= => /ler_trans-> //. +have chi1_1_ge0: 0 <= 'chi_i1 1%g by rewrite ltrW ?irr1_gt0. +rewrite ler_pmul2l ?gt0CiG //. +by rewrite -(@ler_pexpn2r _ 2) -?topredE /= ?sqrtC_ge0 ?ler0n ?sqrtCK. +Qed. + +(* This is Peterfalvi (1.9)(a). *) +Lemma extend_coprime_Qn_aut a b (Qa Qb : fieldExtType rat) w_a w_b + (QaC : {rmorphism Qa -> algC}) (QbC : {rmorphism Qb -> algC}) + (mu : {rmorphism algC -> algC}) : + coprime a b -> + a.-primitive_root w_a /\ <<1; w_a>>%VS = {:Qa}%VS -> + b.-primitive_root w_b /\ <<1; w_b>>%VS = {:Qb}%VS -> + {nu : {rmorphism algC -> algC} | forall x, nu (QaC x) = mu (QaC x) + & forall y, nu (QbC y) = QbC y}. +Proof. +move=> coab [pr_w_a genQa] [pr_w_b genQb]. +have [k co_k_a Dmu]: {k | coprime k a & mu (QaC w_a) = QaC (w_a ^+ k)}. + have prCw: a.-primitive_root (QaC w_a) by rewrite fmorph_primitive_root. + by have [k coka ->] := aut_prim_rootP mu prCw; rewrite -rmorphX; exists k. +pose k1 := chinese a b k 1; have /Qn_aut_exists[nu Dnu]: coprime k1 (a * b). + rewrite coprime_mulr -!(coprime_modl k1) chinese_modl ?chinese_modr //. + by rewrite !coprime_modl co_k_a coprime1n. +exists nu => [x | y]. + have /Fadjoin_polyP[p Qp ->]: x \in <<1; w_a>>%VS by rewrite genQa memvf. + rewrite -!horner_map -!map_poly_comp !map_Qnum_poly // Dmu Dnu -rmorphX /=. + by rewrite -(prim_expr_mod pr_w_a) chinese_modl // prim_expr_mod. + by rewrite exprM (prim_expr_order pr_w_a) expr1n rmorph1. +have /Fadjoin_polyP[p Qp ->]: y \in <<1; w_b>>%VS by rewrite genQb memvf. +rewrite -!horner_map -!map_poly_comp !map_Qnum_poly // Dnu -rmorphX /=. + by rewrite -(prim_expr_mod pr_w_b) chinese_modr // prim_expr_mod. +by rewrite mulnC exprM (prim_expr_order pr_w_b) expr1n rmorph1. +Qed. + +(* This intermediate result in the proof of Peterfalvi (1.9)(b) is used in *) +(* he proof of (3.9)(c). *) +Lemma dvd_restrict_cfAut a (v : {rmorphism algC -> algC}) : + exists2 u : {rmorphism algC -> algC}, + forall gT0 G0 chi x, + chi \in 'Z[irr (@gval gT0 G0)] -> #[x] %| a -> u (chi x) = v (chi x) + & forall chi x, chi \in 'Z[irr G] -> coprime #[x] a -> u (chi x) = chi x. +Proof. +have [-> | a_gt0] := posnP a. + exists v => // chi x Zchi; rewrite /coprime gcdn0 order_eq1 => /eqP->. + by rewrite aut_Cint ?Cint_vchar1. +pose b := (#|G|`_(\pi(a)^'))%N. +have co_a_b: coprime a b := pnat_coprime (pnat_pi a_gt0) (part_pnat _ _). +have [Qa _ [QaC _ [w_a genQa memQa]]] := group_num_field_exists [group of Zp a]. +have [Qb _ [QbC _ [w_b genQb memQb]]] := group_num_field_exists [group of Zp b]. +rewrite !card_Zp ?part_gt0 // in Qa QaC w_a genQa memQa Qb QbC w_b genQb memQb. +have [nu nuQa nuQb] := extend_coprime_Qn_aut QaC QbC v co_a_b genQa genQb. +exists nu => [gt0 G0 chi x Zchi x_dv_a | chi x Zchi co_x_a]. + without loss{Zchi} Nchi: chi / chi \is a character. + move=> IH; case/vcharP: Zchi => [chi1 Nchi1 [chi2 Nchi2 ->]]. + by rewrite !cfunE !rmorphB !IH. + by have [xa <-] := memQa _ _ _ Nchi x x_dv_a; rewrite nuQa. +without loss{Zchi} Nchi: chi / chi \is a character. + move=> IH; case/vcharP: Zchi => [chi1 Nchi1 [chi2 Nchi2 ->]]. + by rewrite !cfunE rmorphB !IH. +have [Gx | /cfun0->] := boolP (x \in G); last by rewrite rmorph0. +have{Gx} x_dv_b: (#[x] %| b)%N. + rewrite coprime_sym coprime_pi' // in co_x_a. + by rewrite -(part_pnat_id co_x_a) partn_dvd ?order_dvdG. +by have [xb <-] := memQb _ _ _ Nchi x x_dv_b; rewrite nuQb. +Qed. + +(* This is Peterfalvi (1.9)(b). *) +(* We have strengthened the statement of this lemma so that it can be used *) +(* rather than reproved for Peterfalvi (3.9). In particular we corrected a *) +(* quantifier inversion in the original statement: the automorphism is *) +(* constructed uniformly for all (virtual) characters. We have also removed *) +(* the spurrious condition that a be a \pi(a) part of #|G| -- the proof works *) +(* for all a, and indeed the first part holds uniformaly for all groups! *) +Lemma make_pi_cfAut a k : + coprime k a -> + exists2 u : {rmorphism algC -> algC}, + forall (gT0 : finGroupType) (G0 : {group gT0}) chi x, + chi \in 'Z[irr G0] -> #[x] %| a -> cfAut u chi x = chi (x ^+ k)%g + & forall chi x, chi \in 'Z[irr G] -> coprime #[x] a -> cfAut u chi x = chi x. +Proof. +move=> co_k_a; have [v Dv] := Qn_aut_exists co_k_a. +have [u Du_a Du_a'] := dvd_restrict_cfAut a v. +exists u => [gt0 G0 | ] chi x Zchi a_x; last by rewrite cfunE Du_a'. +rewrite cfunE {u Du_a'}Du_a //. +without loss{Zchi} Nchi: chi / chi \is a character. + move=> IH; case/vcharP: Zchi => [chi1 Nchi1 [chi2 Nchi2 ->]]. + by rewrite !cfunE rmorphB !IH. +have [sXG0 | G0'x] := boolP (<[x]> \subset G0); last first. + have /(<[x]> =P _) gen_xk: generator <[x]> (x ^+ k). + by rewrite generator_coprime coprime_sym (coprime_dvdr a_x). + by rewrite !cfun0 ?rmorph0 -?cycle_subG -?gen_xk. +rewrite -!(cfResE chi sXG0) ?cycle_id ?mem_cycle //. +rewrite ['Res _]cfun_sum_cfdot !sum_cfunE rmorph_sum; apply: eq_bigr => i _. +have chiX := lin_charX (char_abelianP _ (cycle_abelian x) i) _ (cycle_id x). +rewrite !cfunE rmorphM aut_Cnat ?Cnat_cfdot_char_irr ?cfRes_char //. +by congr (_ * _); rewrite Dv -chiX // -expg_mod_order (eqnP a_x) chiX. +Qed. + +Section ANT. +Import ssrint. + +(* This section covers Peterfalvi (1.10). *) +(* We have simplified the statement somewhat by substituting the global ring *) +(* of algebraic integers for the specific ring Z[eta]. Formally this amounts *) +(* to strengthening (b) and weakening (a) accordingly, but since actually the *) +(* Z[eta] is equal to the ring of integers of Q[eta] (cf. Theorem 6.4 in J.S. *) +(* Milne's course notes on Algebraic Number Theory), the simplified statement *) +(* is actually equivalent to the textbook one. *) +Variable (p : nat) (eps : algC). +Hypothesis (pr_eps : p.-primitive_root eps). +Local Notation e := (1 - eps). + +(* This is Peterfalvi (1.10) (a). *) +Lemma vchar_ker_mod_prim : {in G & G & 'Z[irr G], forall x y (chi : 'CF(G)), + #[x] = p -> y \in 'C[x] -> chi (x * y)%g == chi y %[mod e]}%A. +Proof. +move=> x y chi Gx Gy Zchi ox cxy; pose X := <<[set x; y]>>%G. +have [Xx Xy]: x \in X /\ y \in X by apply/andP; rewrite -!sub1set -join_subG. +have sXG: X \subset G by rewrite join_subG !sub1set Gx. +suffices{chi Zchi} IHiX i: ('chi[X]_i (x * y)%g == 'chi_i y %[mod e])%A. + rewrite -!(cfResE _ sXG) ?groupM //. + have irr_free := (free_uniq (basis_free (irr_basis X))). + have [c Zc ->] := (zchar_expansion irr_free (cfRes_vchar X Zchi)). + rewrite !sum_cfunE /eqAmod -sumrB big_seq rpred_sum // => _ /irrP[i ->]. + by rewrite !cfunE [(_ %| _)%A]eqAmodMl // rpred_Cint. +have lin_chi: 'chi_i \is a linear_char. + apply/char_abelianP; rewrite -[gval X]joing_idl -joing_idr abelianY. + by rewrite !cycle_abelian cycle_subG /= cent_cycle. +rewrite lin_charM // -{2}['chi_i y]mul1r eqAmodMr ?Aint_irr //. +have [|k ->] := (prim_rootP pr_eps) ('chi_i x). + by rewrite -lin_charX // -ox expg_order lin_char1. +rewrite -[_ ^+ k](subrK 1) subrX1 -[_ - 1]opprB mulNr -mulrN mulrC. +rewrite eqAmod_addl_mul // rpredN rpred_sum // => n _. +by rewrite rpredX ?(Aint_prim_root pr_eps). +Qed. + +(* This is Peterfalvi (1.10)(b); the primality condition is only needed here. *) +Lemma int_eqAmod_prime_prim n : + prime p -> n \in Cint -> (n == 0 %[mod e])%A -> (p %| n)%C. +Proof. +move=> p_pr Zn; rewrite /eqAmod unfold_in subr0. +have p_gt0 := prime_gt0 p_pr. +case: ifPn => [_ /eqP->// | nz_e e_dv_n]. +suffices: (n ^+ p.-1 == 0 %[mod p])%A. + rewrite eqAmod0_rat ?rpredX ?rpred_nat 1?rpred_Cint // !dvdC_int ?rpredX //. + by rewrite floorCX // abszX Euclid_dvdX // => /andP[]. +rewrite /eqAmod subr0 unfold_in pnatr_eq0 eqn0Ngt p_gt0 /=. +pose F := \prod_(1 <= i < p) ('X - (eps ^+ i)%:P). +have defF: F = \sum_(i < p) 'X^i. + apply: (mulfI (monic_neq0 (monicXsubC 1))); rewrite -subrX1. + by rewrite -(factor_Xn_sub_1 pr_eps) big_ltn. +have{defF} <-: F.[1] = p :> Algebraics.divisor. + rewrite -[p]card_ord -[rhs in _ = rhs]sumr_const defF horner_sum. + by apply: eq_bigr => i _; rewrite hornerXn expr1n. +rewrite -[p.-1]card_ord {F}horner_prod big_add1 big_mkord -prodfV. +rewrite -prodr_const -big_split rpred_prod //= => k _; rewrite !hornerE. +rewrite -[n](divfK nz_e) -[_ * _ / _]mulrA rpredM {e_dv_n}//. +have p'k: ~~ (p %| k.+1)%N by rewrite gtnNdvd // -{2}(prednK p_gt0) ltnS. +have [r {1}->]: exists r, eps = eps ^+ k.+1 ^+ r. + have [q _ /dvdnP[r Dr]] := Bezoutl p (ltn0Sn k); exists r; apply/esym/eqP. + rewrite -exprM (eq_prim_root_expr pr_eps _ 1) mulnC -Dr addnC gcdnC. + by rewrite -prime_coprime // in p'k; rewrite (eqnP p'k) modnMDl. +rewrite -[1 - _]opprB subrX1 -mulNr opprB mulrC. +rewrite mulKf; last by rewrite subr_eq0 eq_sym -(prim_order_dvd pr_eps). +by apply: rpred_sum => // i _; rewrite !rpredX ?(Aint_prim_root pr_eps). +Qed. + +End ANT. + +End Main. + + |
