Local Hint Extern 1 =>
match goal with
[x : {_ : _ & {_ : _ | _}} |- _] =>
let H :=
fresh "H"
in
let x1 :=
fresh x "1"
in
let x2 :=
fresh x "2"
in
destruct x as [x1 [x2 H]]
end.
Local Hint Extern 1 =>
match goal with
[x : Monic_Image_of |- _] =>
let H :=
fresh "H"
in
let x1 :=
fresh x "1"
in
let x2 :=
fresh x "2"
in
destruct x as [x1 [x2 H]]
end.
Local Hint Extern 1 =>
match goal with
[|- ?A = ?B] =>
assert (H : (projT1 A) = (projT1 B));
[|
apply (sigT_sig_proof_irrelevance _ _ H);
destruct H
]
end.
Program Definition Monic_PreSheaf_Image_of : PreSheaf C
:=
{|
FO := fun x => @Monic_Image_of _ _ (Trans (mono_morphism N) x);
FA := fun c c' h x =>
existT _ (G _a h (projT1 x))%morphism
(exist _ (F _a h (proj1_sig (projT2 x)))%morphism _)
|}
.
Program Definition Monic_PreSheaf_Morph_From_Monic_PreSheaf_Image_of_forward :
(Monic_PreSheaf_Image_of –≻ G)%nattrans
:=
{|
Trans := fun x => @Monic_From_Image_forward _ _ (Trans (mono_morphism N) x)
|}.
Program Definition Monic_PreSheaf_From_Monic_PreSheaf_Image_of_back :
(Monic_PreSheaf_Image_of –≻ F)%nattrans
:=
{|
Trans := fun x => @Monic_From_Image_back _ _ (Trans (mono_morphism N) x)
|}.
Program Definition Monic_PreSheaf_To_Monic_PreSheaf_Image_of :
(F –≻ Monic_PreSheaf_Image_of)%nattrans
:=
{|
Trans := fun x => @Monic_To_Image _ _ (Trans (mono_morphism N) x)
|}.
Definition Monic_PreSheaf_Iso_Monic_Factor_Monic :
@Monic (PShCat C) Monic_PreSheaf_Image_of G.

(* Specifications: *)
Theorem split_Epic_Monic_Factorization :
(mono_morphism N) =
(
(mono_morphism Monic_PreSheaf_Iso_Monic_Factor_Monic)
∘
(iso_morphism Monic_PreSheaf_Iso_Monic_Factor_Monic_Iso)
)%nattrans.