Definition group_of of phant gT : predArgType := group_type.
Local Notation groupT := (group_of (Phant gT)).
Identity Coercion type_of_group : group_of >-> group_type.
Canonical group_subType := Eval hnf in [subType for gval].
Definition group_eqMixin := Eval hnf in [eqMixin of group_type by <:].
Canonical group_eqType := Eval hnf in EqType group_type group_eqMixin.
Definition group_choiceMixin := [choiceMixin of group_type by <:].
Canonical group_choiceType :=
Eval hnf in ChoiceType group_type group_choiceMixin.
Definition group_countMixin := [countMixin of group_type by <:].
Canonical group_countType := Eval hnf in CountType group_type group_countMixin.
Canonical group_subCountType := Eval hnf in [subCountType of group_type].
Definition group_finMixin := [finMixin of group_type by <:].
Canonical group_finType := Eval hnf in FinType group_type group_finMixin.
Canonical group_subFinType := Eval hnf in [subFinType of group_type].
(* No predType or baseFinGroupType structures, as these would hide the *)
(* group-to-set coercion and thus spoil unification.                  *)
Canonical group_of_subType := Eval hnf in [subType of groupT].
Canonical group_of_eqType := Eval hnf in [eqType of groupT].
Canonical group_of_choiceType := Eval hnf in [choiceType of groupT].
Canonical group_of_countType := Eval hnf in [countType of groupT].
Canonical group_of_subCountType := Eval hnf in [subCountType of groupT].
Canonical group_of_finType := Eval hnf in [finType of groupT].
Canonical group_of_subFinType := Eval hnf in [subFinType of groupT].
Definition group (A : {set gT}) gA : groupT := @Group A gA.
Definition clone_group G :=
let: Group _ gP := G return {type of Group for G} -> groupT in fun k => k gP.

(* Specifications: *)
Lemma group_inj : injective gval. Proof. exact: val_inj. Qed.
Lemma groupP (G : groupT) : group_set G. Proof. by case: G. Qed.
Lemma congr_group (H K : groupT) : H = K -> H :=: K.
Lemma trivgP : reflect (G :=: 1) (G \subset [1]).
Lemma trivg_card_le1 : (G :==: 1) = (#|G| <= 1).
Lemma mulGS A B : (G * A \subset G * B) = (A \subset G * B).
Lemma mulSG A B : (A * G \subset B * G) = (A \subset B * G).
Lemma mul_subG A B : A \subset G -> B \subset G -> A * B \subset G.
Lemma groupVl x : x^-1 \in G -> x \in G.
Lemma groupMr x y : x \in G -> (y * x \in G) = (y \in G).
Lemma mulGSgid A x : x \in A -> A \subset G -> G * A = G.
(* Left cosets *)
Lemma lcoset_refl x : x \in x *: G.
Lemma lcoset_transl x y z : x \in y *: G -> (x \in z *: G) = (y \in z *: G).
Lemma rcoset_transl x y z : x \in G :* y -> (x \in G :* z) = (y \in G :* z).
Lemma rcoset_repr x : G :* (repr (G :* x)) = G :* x.
Lemma mem_lcosets A x : (x *: G \in lcosets G A) = (x \in A * G).
(* Conjugates. *)
Lemma group_setJ A x : group_set (A :^ x) = group_set A.
Lemma class_sym x y : (x \in y ^: G) = (y \in x ^: G).
Lemma classG_eq1 x : (x ^: G == 1) = (x == 1).
Lemma class_subG x A : x \in G -> A \subset G -> x ^: A \subset G.
Lemma repr_classesP xG :
reflect (repr xG \in G /\ xG = repr xG ^: G) (xG \in classes G).
Lemma mem_repr_classes xG : xG \in classes G -> repr xG \in xG.
Lemma mem_class_support A x : x \in A -> x \in class_support A G.
Lemma class_supportGidr A : {in G, normalised (class_support A G)}.
Lemma class_support_subG A : A \subset G -> class_support A G \subset G.
Lemma sub_class_support A : A \subset class_support A G.
Lemma class_supportD1 A : (class_support A G)^# =  cover (A^# :^: G).
Inductive subg_of : predArgType := Subg x & x \in G.