(* (c) Copyright 2006-2016 Microsoft Corporation and Inria.                  *)
(* Distributed under the terms of CeCILL-B.                                  *)
From mathcomp
From mathcomp
From mathcomp
(******************************************************************************)
(* Standard group notions and constructions based on the prime decomposition  *)
(* of the order of the group or its elements:                                 *)
(*        pi.-group G <=> G is a pi-group, i.e., pi.-nat #|G|.                *)
(*    -> Recall that here and in the sequel pi can be a single prime p.       *)
(*  pi.-subgroup(H) G <=> H is a pi-subgroup of G.                            *)
(*                     := (H \subset G) && pi.-group H.                       *)
(*    -> This is provided mostly as a shorhand, with few associated lemmas.   *)
(*       However, we do establish some results on maximal pi-subgroups.       *)
(*          pi.-elt x <=> x is a pi-element.                                  *)
(*                     := pi.-nat #[x] or pi.-group <[x]>.                    *)
(*             x.`_pi == the pi-constituent of x: the (unique) pi-element     *)
(*                       y \in <[x]> such that x * y^-1 is a pi'-element.     *)
(*      pi.-Hall(G) H <=> H is a Hall pi-subgroup of G.                       *)
(*                    := [&& H \subset G, pi.-group H & pi^'.-nat #|G : H|].  *)
(*    -> This is also eqivalent to H \subset G /\ #|H| = #|G|`_pi.            *)
(*      p.-Sylow(G) P <=> P is a Sylow p-subgroup of G.                       *)
(*    -> This is the display and preferred input notation for p.-Hall(G) P.   *)
(*          'Syl_p(G) == the set of the p-Sylow subgroups of G.               *)
(*                    := [set P : {group _} | p.-Sylow(G) P].                 *)
(*          p_group P <=> P is a p-group for some prime p.                    *)
(*           Hall G H <=> H is a Hall pi-subgroup of G for some pi.           *)
(*                    := coprime #|H| #|G : H| && (H \subset G).              *)
(*          Sylow G P <=> P is a Sylow p-subgroup of G for some p.            *)
(*                    := p_group P && Hall G P.                               *)
(*           'O_pi(G) == the pi-core (largest normal pi-subgroup) of G.       *)
(*   pcore_mod pi G H == the pi-core of G mod H.                              *)
(*                    := G :&: (coset H @*^-1 'O_pi(G / H)).                  *)
(*   'O_{pi2, pi1}(G) == the pi1,pi2-core of G.                               *)
(*                    := the pi1-core of G mod 'O_pi2(G).                     *)
(*     -> We have 'O_{pi2, pi1}(G) / 'O_pi2(G) = 'O_pi1(G / 'O_pi2(G))        *)
(*        with 'O_pi2(G) <| 'O_{pi2, pi1}(G) <| G.                            *)
(* 'O_{pn, ..., p1}(G) == the p1, ..., pn-core of G.                          *)
(*                    := the p1-core of G mod 'O_{pn, ..., p2}(G).            *)
(* Note that notions are always defined on sets even though their name        *)
(* indicates "group" properties; the actual definition of the notion never    *)
(* tests for the group property, since this property will always be provided  *)
(* by a (canonical) group structure. Similarly, p-group properties assume     *)
(* without test that p is a prime.                                            *)
(******************************************************************************)
Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.
Section PgroupDefs.
(* We defer the definition of the functors ('0_p(G), etc) because they need *)
(* to quantify over the finGroupType explicitly.                            *)
Variable gT : finGroupType.
Implicit Type (x : gT) (A B : {set gT}) (pi : nat_pred) (p n : nat).
Definition pgroup pi A := pi.-nat #|A|.
Definition psubgroup pi A B := (B \subset A) && pgroup pi B.
Definition p_group A := pgroup (pdiv #|A|) A.
Definition p_elt pi x := pi.-nat #[x].
Definition constt x pi := x ^+ (chinese #[x]`_pi #[x]`_pi^' 1 0).
Definition Hall A B := (B \subset A) && coprime #|B| #|A : B|.
Definition pHall pi A B := [&& B \subset A, pgroup pi B & pi^'.-nat #|A : B|].
Definition Syl p A := [set P : {group gT} | pHall p A P].
Definition Sylow A B := p_group B && Hall A B.
End PgroupDefs.
Arguments pgroup {gT} pi%N A%g.
Arguments psubgroup {gT} pi%N A%g B%g.
Arguments p_group {gT} A%g.
Arguments p_elt {gT} pi%N x.
Arguments constt {gT} x%g pi%N.
Arguments Hall {gT} A%g B%g.
Arguments pHall {gT} pi%N A%g B%g.
Arguments Syl {gT} p%N A%g.
Arguments Sylow {gT} A%g B%g.
Notation "pi .-group" := (pgroup pi)
(at level 2, format "pi .-group") : group_scope.
Notation "pi .-subgroup ( A )" := (psubgroup pi A)
(at level 8, format "pi .-subgroup ( A )") : group_scope.
Notation "pi .-elt" := (p_elt pi)
(at level 2, format "pi .-elt") : group_scope.
Notation "x .`_ pi" := (constt x pi)
(at level 3, format "x .`_ pi") : group_scope.
Notation "pi .-Hall ( G )" := (pHall pi G)
(at level 8, format "pi .-Hall ( G )") : group_scope.
Notation "p .-Sylow ( G )" := (nat_pred_of_nat p).-Hall(G)
(at level 8, format "p .-Sylow ( G )") : group_scope.
Notation "''Syl_' p ( G )" := (Syl p G)
(at level 8, p at level 2, format "''Syl_' p ( G )") : group_scope.
Section PgroupProps.
Variable gT : finGroupType.
Implicit Types (pi rho : nat_pred) (p : nat).
Implicit Types (x y z : gT) (A B C D : {set gT}) (G H K P Q R : {group gT}).

(* Specifications: *)
Lemma trivgVpdiv G : G :=: 1 \/ (exists2 p, prime p & p %| #|G|).
Lemma prime_subgroupVti G H : prime #|G| -> G \subset H \/ H :&: G = 1.
Lemma pgroupE pi A : pi.-group A = pi.-nat #|A|. Proof. by []. Qed.
Lemma sub_pgroup pi rho A : {subset pi <= rho} -> pi.-group A -> rho.-group A.
Lemma card_pgroup p G : p.-group G -> #|G| = (p ^ logn p #|G|)%N.
Lemma pgroupM pi G H : pi.-group (G * H) = pi.-group G && pi.-group H.
Lemma pgroupJ pi G x : pi.-group (G :^ x) = pi.-group G.
Lemma p_groupP P : p_group P -> exists2 p, prime p & p.-group P.
Lemma pgroup_pdiv p G :
p.-group G -> G :!=: 1 ->
[/\ prime p, p %| #|G| & exists m, #|G| = p ^ m.+1]%N.
Lemma coprime_p'group p K R :
coprime #|K| #|R| -> p.-group R -> R :!=: 1 -> p^'.-group K.
Lemma card_Hall pi G H : pi.-Hall(G) H -> #|H| = #|G|`_pi.
Lemma pHall_sub pi A B : pi.-Hall(A) B -> B \subset A.
Lemma pHallE pi G H : pi.-Hall(G) H = (H \subset G) && (#|H| == #|G|`_pi).
Lemma coprime_mulGp_Hall pi G K R :
K * R = G -> pi^'.-group K -> pi.-group R ->
pi^'.-Hall(G) K /\ pi.-Hall(G) R.
Lemma eq_in_pHall pi rho G H :
{in \pi(G), pi =i rho} -> pi.-Hall(G) H = rho.-Hall(G) H.
Lemma eq_pHall pi rho G H : pi =i rho -> pi.-Hall(G) H = rho.-Hall(G) H.
Lemma subHall_Sylow pi p G H P :
pi.-Hall(G) H -> p \in pi -> p.-Sylow(H) P -> p.-Sylow(G) P.
Lemma pHall_Hall pi A B : pi.-Hall(A) B -> Hall A B.
Lemma HallP G H : Hall G H -> exists pi, pi.-Hall(G) H.
Lemma coprime_sdprod_Hall_l G K H : K ><| H = G -> coprime #|K| #|H| = Hall G K.
Lemma coprime_sdprod_Hall_r G K H : K ><| H = G -> coprime #|K| #|H| = Hall G H.
Lemma compl_pHall pi K H G :
pi.-Hall(G) K -> (H \in [complements to K in G]) = pi^'.-Hall(G) H.
Lemma compl_p'Hall pi K H G :
pi^'.-Hall(G) K -> (H \in [complements to K in G]) = pi.-Hall(G) H.
Lemma sdprod_normal_pHallP pi K H G :
K <| G -> pi.-Hall(G) H -> reflect (K ><| H = G) (pi^'.-Hall(G) K).
Lemma pHallJ2 pi G H x : pi.-Hall(G :^ x) (H :^ x) = pi.-Hall(G) H.
Lemma psubgroupJ pi G H x :
x \in G -> pi.-subgroup(G) (H :^ x) = pi.-subgroup(G) H.
Lemma pHall_subl pi G K H :
H \subset K -> K \subset G -> pi.-Hall(G) H -> pi.-Hall(K) H.
Lemma Hall1 G : Hall G 1.
Lemma p_elt_exp pi x m : pi.-elt (x ^+ m) = (#[x]`_pi^' %| m).
Lemma mem_p_elt pi x G : pi.-group G -> x \in G -> pi.-elt x.
Lemma p_eltM pi x y : commute x y -> pi.-elt x -> pi.-elt y -> pi.-elt (x * y).
Lemma p_elt1 pi : pi.-elt (1 : gT).
Lemma consttNK pi x : x.`_pi^'^' = x.`_pi.
Lemma p'_elt_constt pi x : pi^'.-elt (x * (x.`_pi)^-1).
Lemma consttM pi x y : commute x y -> (x * y).`_pi = x.`_pi * y.`_pi.
Lemma consttX pi x n : (x ^+ n).`_pi = x.`_pi ^+ n.
Lemma constt1P pi x : reflect (x.`_pi = 1) (pi^'.-elt x).
Lemma constt_p_elt pi x : pi.-elt x -> x.`_pi = x.
Lemma sub_in_constt pi1 pi2 x :
{in \pi(#[x]), {subset pi1 <= pi2}} -> x.`_pi2.`_pi1 = x.`_pi1.
Lemma prod_constt x : \prod_(0 <= p < #[x].+1) x.`_p = x.
Lemma max_pgroupJ pi M G x :
x \in G -> [max M | pi.-subgroup(G) M] ->
[max M :^ x of M | pi.-subgroup(G) M].
Lemma comm_sub_max_pgroup pi H M G :
[max M | pi.-subgroup(G) M] -> pi.-group H -> H \subset G ->
commute H M -> H \subset M.
Lemma normal_sub_max_pgroup pi H M G :
[max M | pi.-subgroup(G) M] -> pi.-group H -> H <| G -> H \subset M.
Lemma norm_sub_max_pgroup pi H M G :
[max M | pi.-subgroup(G) M] -> pi.-group H -> H \subset G ->
H \subset 'N(M) -> H \subset M.
Lemma Hall_max pi H G : pi.-Hall(G) H -> [max H | pi.-subgroup(G) H].
Lemma pHall_id pi H G : pi.-Hall(G) H -> pi.-group G -> H :=: G.
Lemma psubgroup1 pi G : pi.-subgroup(G) 1.
(* These lemmas actually hold for maximal pi-groups, but below we'll *)
(* derive from the Cauchy lemma that a normal max pi-group is Hall.  *)
Lemma sub_normal_Hall pi G H K :
pi.-Hall(G) H -> H <| G -> K \subset G -> (K \subset H) = pi.-group K.
Lemma mem_normal_Hall pi H G x :
pi.-Hall(G) H -> H <| G -> x \in G -> (x \in H) = pi.-elt x.