(* (c) Copyright 2006-2016 Microsoft Corporation and Inria.                  *)
(* Distributed under the terms of CeCILL-B.                                  *)
From mathcomp
From mathcomp
(******************************************************************************)
(*  Partial, semidirect, central, and direct products.                        *)
(*  ++ Internal products, with A, B : {set gT}, are partial operations :      *)
(*  partial_product A B == A * B if A is a group normalised by the group B,   *)
(*                         and the empty set otherwise.                       *)
(*              A ><| B == A * B if this is a semi-direct product (i.e., if A *)
(*                         is normalised by B and intersects it trivially).   *)
(*               A \* B == A * B if this is a central product ([A, B] = 1).   *)
(*               A \x B == A * B if this is a direct product.                 *)
(* [complements to K in G] == set of groups H s.t. K * H = G and K :&: H = 1. *)
(*      [splits G, over K] == [complements to K in G] is not empty.           *)
(*             remgr A B x == the right remainder in B of x mod A, i.e.,      *)
(*                            some element of (A :* x) :&: B.                 *)
(*             divgr A B x == the "division" in B of x by A: for all x,       *)
(*                            x = divgr A B x * remgr A B x.                  *)
(* ++ External products :                                                     *)
(* pairg1, pair1g == the isomorphisms aT1 -> aT1 * aT2, aT2 -> aT1 * aT2.     *)
(*                    (aT1 * aT2 has a direct product group structure.)       *)
(*   sdprod_by to == the semidirect product defined by to : groupAction H K.  *)
(*                   This is a finGroupType; the actual semidirect product is *)
(*                   the total set [set: sdprod_by to] on that type.          *)
(*  sdpair[12] to == the isomorphisms injecting K and H into                  *)
(*                   sdprod_by to = sdpair1 to @* K ><| sdpair2 to @* H.      *)
(* External central products (with identified centers) will be defined later  *)
(* in file center.v.                                                          *)
(* ++ Morphisms on product groups:                                            *)
(*   pprodm nAB fJ fAB == the morphism extending fA and fB on A <*> B when    *)
(*                        nAB : B \subset 'N(A),                              *)
(*                        fJ : {in A & B, morph_actj fA fB}, and              *)
(*                        fAB : {in A :&: B, fA =1 fB}.                       *)
(*     sdprodm defG fJ == the morphism extending fA and fB on G, given        *)
(*                        defG : A ><| B = G and                              *)
(*                        fJ : {in A & B, morph_act 'J 'J fA fB}.             *)
(*     xsdprodm fHKact == the total morphism on sdprod_by to induced by       *)
(*                        fH : {morphism H >-> rT}, fK : {morphism K >-> rT}, *)
(*                        with to : groupAction K H,                          *)
(*                        given fHKact : morph_act to 'J fH fK.               *)
(* cprodm defG cAB fAB == the morphism extending fA and fB on G, when         *)
(*                        defG : A \* B = G,                                  *)
(*                        cAB : fB @* B \subset 'C(fB @* A),                  *)
(*                        and fAB : {in A :&: B, fA =1 fB}.                   *)
(*     dprodm defG cAB == the morphism extending fA and fB on G, when         *)
(*                        defG : A \x B = G and                               *)
(*                        cAB : fA @* B \subset 'C(fA @* A)                   *)
(*        mulgm (x, y) == x * y; mulgm is an isomorphism from setX A B to G   *)
(*                        iff A \x B = G .                                    *)
(******************************************************************************)
Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.
Section Defs.
Variables gT : finGroupType.
Implicit Types A B C : {set gT}.
Definition partial_product A B :=
if A == 1 then B else if B == 1 then A else
if [&& group_set A, group_set B & B \subset 'N(A)] then A * B else set0.
Definition semidirect_product A B :=
if A :&: B \subset 1%G then partial_product A B else set0.
Definition central_product A B :=
if B \subset 'C(A) then partial_product A B else set0.
Definition direct_product A B :=
if A :&: B \subset 1%G then central_product A B else set0.
Definition complements_to_in A B :=
[set K : {group gT} | A :&: K == 1 & A * K == B].
Definition splits_over B A := complements_to_in A B != set0.
(* Product remainder functions -- right variant only. *)
Definition remgr A B x := repr (A :* x :&: B).
Definition divgr A B x := x * (remgr A B x)^-1.
End Defs.
Arguments partial_product _ _%g _%g : clear implicits.
Arguments semidirect_product _ _%g _%g : clear implicits.
Arguments central_product _ _%g _%g : clear implicits.
Arguments complements_to_in _ _%g _%g.
Arguments splits_over _ _%g _%g.
Arguments remgr _ _%g _%g _%g.
Arguments divgr _ _%g _%g _%g.
Arguments direct_product : clear implicits.
Notation pprod := (partial_product _).
Notation sdprod := (semidirect_product _).
Notation cprod := (central_product _).
Notation dprod := (direct_product _).
Notation "G ><| H" := (sdprod G H)%g (at level 40, left associativity).
Notation "G \* H" := (cprod G H)%g (at level 40, left associativity).
Notation "G \x H" := (dprod G H)%g (at level 40, left associativity).
Notation "[ 'complements' 'to' A 'in' B ]" := (complements_to_in A B)
(at level 0, format "[ 'complements'  'to'  A  'in'  B ]") : group_scope.
Notation "[ 'splits' B , 'over' A ]" := (splits_over B A)
(at level 0, format "[ 'splits'  B ,  'over'  A ]") : group_scope.
(* Prenex Implicits remgl divgl. *)
Prenex Implicits remgr divgr.
Section InternalProd.
Variable gT : finGroupType.
Implicit Types A B C : {set gT}.
Implicit Types G H K L M : {group gT}.
Local Notation pprod := (partial_product gT).
Local Notation sdprod := (semidirect_product gT) (only parsing).
Local Notation cprod := (central_product gT) (only parsing).
Local Notation dprod := (direct_product gT) (only parsing).

(* Specifications: *)
Lemma pprod1g : left_id 1 pprod.
Lemma mul0g : left_zero (@set0 gT) mulg.
Lemma pprodP A B G :
pprod A B = G -> [/\ are_groups A B, A * B = G & B \subset 'N(A)].
Lemma pprodE K H : H \subset 'N(K) -> pprod K H = K * H.
Lemma pprodEY K H : H \subset 'N(K) -> pprod K H = K <*> H.
(* Properties of the remainders *)
Lemma remgrMl K B x y : y \in K -> remgr K B (y * x) = remgr K B x.
Lemma remgr1 K H x : x \in K -> remgr K H x = 1.
Lemma remgrMid x y : x \in K -> y \in H -> remgr K H (x * y) = y.
(* Complements, and splitting. *)
Lemma complP H A B :
reflect (A :&: H = 1 /\ A * H = B) (H \in [complements to A in B]).