(* Monotonicity with respect to inclusion *)
(* Self-expanding composition, and modulo *)
Variables (k : unit) (F1 F2 : object_map).
Definition comp_head : object_map := fun gT A => let: tt := k in F1 (F2 A).
Definition modulo : object_map :=
fun gT A => coset (F2 A) @*^-1 (F1 (A / (F2 A))).
End Definitions.
Section ClassDefinitions.
Structure iso_map := IsoMap {
apply : object_map;
_ : group_valued apply;
_ : closed apply;
_ : iso_continuous apply
}.
Local Coercion apply : iso_map >-> object_map.
Structure map := Map { iso_of_map : iso_map; _ : continuous iso_of_map }.
Local Coercion iso_of_map : map >-> iso_map.
Structure pmap := Pmap { map_of_pmap : map; _ : hereditary map_of_pmap }.
Local Coercion map_of_pmap : pmap >-> map.
Structure mono_map := MonoMap { map_of_mono : map; _ : monotonic map_of_mono }.
Local Coercion map_of_mono : mono_map >-> map.
Definition pack_iso F Fcont Fgrp Fsub := @IsoMap F Fgrp Fsub Fcont.
Definition clone_iso (F : object_map) :=
fun Fgrp Fsub Fcont (isoF := @IsoMap F Fgrp Fsub Fcont) =>
fun isoF0 & phant_id (apply isoF0) F & phant_id isoF isoF0 => isoF.
Definition clone (F : object_map) :=
fun isoF & phant_id (apply isoF) F =>
fun (funF0 : map) & phant_id (apply funF0) F =>
fun Fcont (funF := @Map isoF Fcont) & phant_id funF0 funF => funF.
Definition clone_pmap (F : object_map) :=
fun (funF : map) & phant_id (apply funF) F =>
fun (pfunF0 : pmap) & phant_id (apply pfunF0) F =>
fun Fher (pfunF := @Pmap funF Fher) & phant_id pfunF0 pfunF => pfunF.
Definition clone_mono (F : object_map) :=
fun (funF : map) & phant_id (apply funF) F =>
fun (mfunF0 : mono_map) & phant_id (apply mfunF0) F =>
fun Fmon (mfunF := @MonoMap funF Fmon) & phant_id mfunF0 mfunF => mfunF.
End ClassDefinitions.
Module Exports.
Identity Coercion fun_of_object_map : object_map >-> Funclass.
Coercion apply : iso_map >-> object_map.
Coercion iso_of_map : map >-> iso_map.
Coercion map_of_pmap : pmap >-> map.
Coercion map_of_mono : mono_map >-> map.
Coercion continuous_is_iso_continuous : continuous >-> iso_continuous.
Coercion pcontinuous_is_continuous : pcontinuous >-> continuous.
Coercion pcontinuous_is_hereditary : pcontinuous >-> hereditary.
Notation "[ 'igFun' 'by' Fsub & Fcont ]" :=
(pack_iso (continuous_is_iso_continuous Fcont) (fun gT G => groupP _) Fsub)
(at level 0, format "[ 'igFun'  'by'  Fsub  &  Fcont ]") : form_scope.
Notation "[ 'igFun' 'by' Fsub & ! Fcont ]" :=
(pack_iso Fcont (fun gT G => groupP _) Fsub)
(at level 0, format "[ 'igFun'  'by'  Fsub  &  ! Fcont ]") : form_scope.
Notation "[ 'igFun' 'of' F ]" := (@clone_iso F _ _ _ _ id id)
(at level 0, format "[ 'igFun'  'of'  F ]") : form_scope.
Notation "[ 'gFun' 'by' Fcont ]" := (Map Fcont)
(at level 0, format "[ 'gFun'  'by'  Fcont ]") : form_scope.
Notation "[ 'gFun' 'of' F ]" := (@clone F _ id _ id _ id)
(at level 0, format "[ 'gFun'  'of'  F ]") : form_scope.
Notation "[ 'pgFun' 'by' Fher ]" := (Pmap Fher)
(at level 0, format "[ 'pgFun'  'by'  Fher ]") : form_scope.
Notation "[ 'pgFun' 'of' F ]" := (@clone_pmap F _ id _ id _ id)
(at level 0, format "[ 'pgFun' 'of'  F ]") : form_scope.
Notation "[ 'mgFun' 'by' Fmon ]" := (MonoMap Fmon)
(at level 0, format "[ 'mgFun'  'by'  Fmon ]") : form_scope.
Notation "[ 'mgFun' 'of' F ]" := (@clone_mono F _ id _ id _ id)
(at level 0, format "[ 'mgFun' 'of'  F ]") : form_scope.
End Exports.
End GFunctor.
Export GFunctor.Exports.
Bind Scope gFun_scope with GFunctor.object_map.
Notation "F1 \o F2" := (GFunctor.comp_head tt F1 F2) : gFun_scope.
Notation "F1 %% F2" := (GFunctor.modulo F1 F2) : gFun_scope.
Section FunctorGroup.
Variables (F : GFunctor.iso_map) (gT : finGroupType) (G : {group gT}).

Lemma gFgroupset : group_set (F gT G). Proof. by case: F. Qed.
Canonical gFgroup := Group gFgroupset.