math-comp
math-comp copied to clipboard
WIP galmx : gal_of -> matrix
Motivation for this change
Adding the operator galmx which gives a matrix representation of an element of a galois group. It was used in a -- now deleted -- proof in the proof of Abel-Ruffini's theorem:
Variables (F0 : fieldType) (L : splittingFieldType F0).
Implicit Types (E F K : {subfield L}) (w : L) (n : nat).
(* - each element of G is diagonalizable *)
(* - the elements of G are simultaneously diagonalizable *)
(* - their eigenvalues are n-th root of the unity because their minimal *)
(* polynomial divides X^n - 1 *)
(* - let (r1, ..., rn) be their common basis *)
(* - we use the fact : ri^n is unchanged by any m of G => ri^n is in E *)
(* - let lambda be the eigenvalue which corresponds to m and ri *)
(* - then m(ri^n) = (m(ri))^n (m automorphism) *)
(* - m(ri) = lambda ri (lambda eigenvalue) *)
(* - lambda^n ri^n = ri^n (lambda is an n-th root of the unity) *)
(* - ri^n is unchanged by m *)
(* - then ri^n is in E *)
(* - ri is a radical element on E *)
Lemma abelian_radical_ext w E F (n := \dim_E F) :
n.-primitive_root w -> w \in E -> galois E F ->
abelian 'Gal(F / E) -> radical.-ext E F.
Proof.
set G := (X in abelian X) => w_root wE galois_EF abelian_G.
have subv_EF := galois_subW galois_EF.
have n_gt0 : (n > 0)%N by rewrite /n -dim_aspaceOver ?adim_gt0.
have asimp := (mem_aspaceOver, subv_adjoin_seq).
suff [/= w_ /andP[w_basis /allP w_F] m_w {abelian_G}] :
{ w_ : n.-tuple L |
basis_of (aspaceOver E F) (w_ : seq (fieldOver E)) && all (mem F) w_ &
forall i m, m \in G -> exists2 l, (l \in E) && (l ^+ n == 1)
& m (tnth w_ i) = l * tnth w_ i }.
pose f i := <<E & take i w_>>%AS.
have f0E : f 0%N = E by apply/val_inj; rewrite /f/= take0 Fadjoin_nil.
have Ew_eq_F : <<E & w_>>%AS = F :> {vspace _}.
apply/eqP; rewrite eqEsubv/=; apply/andP; split.
by apply/Fadjoin_seqP; split.
apply/subvP => x; rewrite -(mem_aspaceOver subv_EF).
move=> /(coord_basis w_basis)->; rewrite memv_suml// => i _.
rewrite fieldOver_scaleE/= rpredM//.
by rewrite (subvP (subv_adjoin_seq _ _))//; apply: valP.
have lt_iw : (i < size w_)%N by rewrite size_tuple.
by rewrite (subvP (seqv_sub_adjoin _ (mem_nth 0 lt_iw)))// memv_line.
exists (ExtData w_ [tuple of nseq n n]) => //; apply/forallP=> /= i.
rewrite {2}/tnth nth_nseq ltn_ord; apply/radicalP; split=> //.
suff: (tnth w_ i) ^+ n \in fixedField G.
by rewrite (galois_fixedField _)//; apply/(subvP (subv_adjoin_seq _ _)).
apply/fixedFieldP; first by rewrite rpredX ?[_ \in _]w_F ?mem_nth ?size_tuple.
move=> g /(m_w i)[l /andP[lE /eqP lX1]].
by rewrite (tnth_nth 0) rmorphX/= => ->; rewrite exprMn lX1 mul1r.
pose LE := [fieldExtType subvs_of E of fieldOver E].
have [e e_basis] : { e : n.-1.+1.-tuple _ | basis_of (aspaceOver E F) e}.
rewrite prednK//; have := vbasisP (aspaceOver E F); move: (vbasis _).
by rewrite dim_aspaceOver// => e; exists e.
have e_free := basis_free e_basis.
have Gminpoly g : g \in G -> mxminpoly (galmx e g) %| 'X ^+ n - 1.
move=> gG; rewrite mxminpoly_min// rmorphB rmorph1 rmorphX/= horner_mx_X.
apply: (canLR (addrK _)); rewrite add0r -galmxX//.
by rewrite [n]galois_dim// expg_cardG// galmx1.
have /sig2W [p p_unit dG] : codiagonalisable [seq galmx e g | g in G].
apply/codiagonalisableP; split.
apply/all_commP => _ _ /mapP[g gG ->] /mapP[g' g'G ->].
rewrite ?mem_enum in gG g'G.
by rewrite -![_ *m _]galmxM// (centsP abelian_G).
move=> _/mapP[g gG ->]; rewrite mem_enum in gG *.
pose l := [seq Subvs wE ^+ i | i <- index_iota 0 n].
apply/diagonalisableP; exists l.
rewrite map_inj_in_uniq ?iota_uniq//.
move=> x y; rewrite !mem_index_iota !leq0n/= => x_n y_n.
move=> /(congr1 val)/=/eqP; rewrite !rmorphX/=.
by rewrite (eq_prim_root_expr w_root) !modn_small// => /eqP.
rewrite big_map (@factor_Xn_sub_1 _ _ (Subvs wE)) ?Gminpoly//.
by rewrite /= -(fmorph_primitive_root [rmorphism of vsval]).
pose w_ := [tuple galvec e (row i p) | i < n.-1.+1].
rewrite -[n]prednK//; exists w_.
apply/andP; split; last by apply/allP => _ /mapP[/=i _ ->]; rewrite galvec_in.
rewrite basisEdim; apply/andP; split; last first.
by rewrite size_tuple dim_aspaceOver// prednK.
apply/subvP => x /=; rewrite mem_aspaceOver// => xEF.
have [l ->] : exists l, x = galvec e (l *m p).
by exists (galrow e x *m invmx p); rewrite mulmxKV ?galrowK.
rewrite span_def big_map big_enum_cond/= mulmx_sum_row linear_sum/=.
by apply: memv_sumr => i _; rewrite linearZ/= [_ \in _]memvZ// memv_line.
move=> i g gG; have /allP /(_ (galmx e g) (map_f _ _))/sim_diagPex := dG.
case=> // [|M pg]; first by rewrite mem_enum.
exists (val (M 0 i)); [apply/andP; split|]; first by rewrite /= subvsP.
rewrite [X in _ ^+ X]prednK// -subr_eq0.
have := Gminpoly _ gG; rewrite (simLR _ pg)//.
move => /dvdpP [q] /(congr1 (val \o horner^~ (M 0 i)))/=.
rewrite hornerM hornerD hornerN hornerXn hornerC/= rmorphX algid1 => ->.
rewrite mxminpoly_uconj ?unitmx_inv// mxminpoly_diag/= horner_prod.
set u := undup _; under eq_bigr do rewrite hornerXsubC.
suff /eqP-> : \prod_(i0 <- u) (M 0 i - i0) == 0 by rewrite mulr0.
rewrite prodf_seq_eq0; apply/hasP; exists (M 0 i); rewrite ?subrr ?eqxx//.
by rewrite mem_undup map_f ?mem_enum.
have /(simP p_unit)/(congr1 (mulmx (@delta_mx _ 1 _ 0 i))) := pg.
rewrite !mulmxA -!rowE row_diag_mx -scalemxAl -rowE => /(congr1 (galvec e)).
by rewrite galvecM// linearZ/= tnth_map tnth_ord_tuple.
Qed.
Things done/to do
- [ ] added corresponding entries in
CHANGELOG_UNRELEASED.md(do not edit former entries) - [ ] added corresponding documentation in the headers
Automatic note to reviewers
Read this Checklist and make sure there is a milestone.
@CohenCyril should we postpone this or try to move toward merging?
This is a WIP, let's postpone.
TODO: find where to put this alternative proof in math-comp (gallery?)