(** Isomorphism is an equivalence relation on objects. *)
(** The identity morphism forms an isomorphism, i.e., it is inverse to itself. This is reflexivity property for the equivalence relation of isomorphism on objects. *)
Program Definition Isomorphism_id {C : Category} {a : C} : a ≃ a :=
{|
iso_morphism := id;
inverse_morphism := id
|}.
(** Each ismorphism has an inverse isomorphism. Simply swap the morphisms and proofs of left and right inverse properties. This is symmetry property for the equivalence relation of isomorphism on objects. *)
Definition Inverse_Isomorphism {C : Category} {a b : C} (I : a ≃ b) : b ≃ a :=
{|
iso_morphism := I⁻¹;
inverse_morphism := I;
left_inverse := right_inverse I;
right_inverse := left_inverse I
|}.
Notation "f '⁻¹'" := (Inverse_Isomorphism f) : isomorphism_scope.
(** Isomorphisms compose. Simply compose the underlying morphisms of the isomorphism. Left and right inverse properties follow straightforwardly. This is transitivty property for the equivalence relation of isomorphism on objects. *)
Program Definition Isomorphism_Compose
{C : Category} {a b c : C} (I : a ≃ b) (I' : b ≃ c) : a ≃ c
:=
{|
iso_morphism := I' ∘ I;
inverse_morphism := I⁻¹ ∘ I'⁻¹
|}.
Next Obligation.
Next Obligation.
Notation "f ∘ g" := (Isomorphism_Compose g f) : isomorphism_scope.
Local Close Scope isomorphism_scope.
(** A monic arrow (AKA, mono, monomorphic arrow and monomorphism) m is an arrow such that for any two arrows g and h (of the appropriate domain and codomain) we have if m ∘ g = m ∘ h then g = h. *)
Record Monic {C : Category} (a b : Obj) :=
{
mono_morphism : a –≻ b;
mono_morphism_monomorphic : ∀ (c : Obj) (g h : c –≻ a),
(mono_morphism ∘ g = mono_morphism ∘ h) → g = h
}.
Coercion mono_morphism : Monic >-> Hom.
Arguments mono_morphism {_ _ _} _.
Arguments mono_morphism_monomorphic {_ _ _} _ _ _ _ _.
Notation "a ≫–> b" := (Monic a b) : morphism_scope.
Bind Scope morphism_scope with Monic.
(** An epic arrow (AKA, epi, epimorphic arrow and epimorphism) is a monomorphism in the opposite category. That is, m is epic if for any pair of arrows g and h (of the appropriate domain and codomain) we have if g ∘ m = h ∘ m then g = h. *)
Definition Epic {C : Category} (a b : C) := @Monic (C^op) b a.
Notation "a –≫ b" := (Epic a b) : morphism_scope.
Bind Scope morphism_scope with Epic.
(** The condition for a morphism to be mono-morphic. *)
Definition is_Monic {C : Category} {a b : Obj} (f : a –≻ b) :=
∀ (c : Obj) (g h : c –≻ a), (f ∘ g = f ∘ h) → g = h.
(** A mono-morphic morphism forms a Monic. *)
Definition is_Monic_Monic
{C : Category}
{a b : Obj}
{f : a –≻ b}
(H : is_Monic f)
: Monic a b
:=
{|
mono_morphism := f;
mono_morphism_monomorphic := H
|}
.
(** A morphism is ipic if it is monic in the opposit category. *)
Definition is_Epic {C : Category} {a b : C} (f : a –≻ b) :=
@is_Monic (C^op) b a f.
(** A morphism f : a –≻ b is split monic if there is another morphism g : b –≻ a such that g ∘ f = idₐ *)
Record is_split_Monic {C : Category} {a b : Obj} (f : a –≻ b) :=
{
is_split_monic_left_inverse : b –≻ a;
is_split_monic_left_inverse_is_left_inverse :
(is_split_monic_left_inverse ∘ f) = id
}
.
Arguments is_split_monic_left_inverse {_ _ _ _} _.
Arguments is_split_monic_left_inverse_is_left_inverse {_ _ _ _} _.
(** A morphism is ipic if it is monic in the opposit category. *)
Definition is_split_Epic {C : Category} {a b : C} (f : a –≻ b) :=
@is_split_Monic (C^op) b a f.
(** A split monic morphism is a monomorphism. *)
Program Definition is_split_Monic_Monic
{C : Category}
{a b : Obj}
{f : a –≻ b}
(H : is_split_Monic f)
: Monic a b
:=
{|
mono_morphism := f;
mono_morphism_monomorphic := fun c g h H1 => _
|}
.
Next Obligation.
(** If a monic morphism is split epic, it forms an isomorphism. *)
Program Definition Monic_is_split_Epic_Iso
{C : Category}
(a b : Obj)
(f : a ≫–> b)
(H : is_split_Epic f)
:
(a ≃ b)%isomorphism
:=
{|
iso_morphism := f;
inverse_morphism := is_split_monic_left_inverse H;
right_inverse := is_split_monic_left_inverse_is_left_inverse H
|}
.
Next Obligation.
(** If both g and (f ∘ g) are monic, then so is f. *)
Program Definition Compose_Monic_is_Monic_then_Monic
{C : Category}
{a b c : C}
(M : a –≻ b)
(M' : b ≫–> c)
(H : is_Monic (M' ∘ M))
:
Monic a b
:=
{|
mono_morphism := M;
mono_morphism_monomorphic := fun d g h H1 => _
|}
.
Next Obligation.
(** Monomorphisms compose. The case for epis follows by duality.*)
Section Mono_compose.
Context {C : Category} {a b c : C} (M : a ≫–> b) (M' : b ≫–> c).
Local Hint Resolve mono_morphism_monomorphic.
Local Obligation Tactic := eauto.
Program Definition Mono_compose : a ≫–> c :=
{|
mono_morphism := M' ∘ M
|}.
End Mono_compose.
Local Open Scope isomorphism_scope.
(** An isomorphism is both monic and epic. *)
Section Iso_Mono_Epi.
Context {C : Category} {a b : Obj} (I : a ≃ b).
Program Definition Ismorphism_Monic : a ≫–> b :=
{|
mono_morphism := I
|}.
Next Obligation. (* mono_morphism_monomorphism *)
Program Definition Ismorphism_Epic : b –≫ a :=
{|
mono_morphism := inverse_morphism I
|}.
Next Obligation. (* epi_morphism_epimorphism *)
End Iso_Mono_Epi.

(** If two objects are isomorphic in category C then they are also isomorphic in C^op. *)
Theorem CoIso {C : Category} (a b : C) : a ≃≃ b ::> C → a ≃≃ b ::> C^op.