(* (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}).

Lemma prod_constt x : \prod_(0 <= p < #[x].+1) x.`_p = x.