Built with Alectryon, running Coq+SerAPI v8.19.0+0.19.3. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑Ctrl+↓ to navigate, Ctrl+🖱️ to focus. On Mac, use ⌘ instead of Ctrl.
(** * Definitions and theorems about {iso,epi,mono,}morphisms in a precategory *)
[Loading ML file number_string_notation_plugin.cmxs (using legacy method) ... done]
Require Import HoTT.Tactics Basics.Trunc Basics.Tactics Types.Sigma Equivalences.Set Universe Polymorphism.Set Implicit Arguments.Generalizable All Variables.Set Asymmetric Patterns.LocalOpen Scope category_scope.LocalOpen Scope morphism_scope.(** ** Definition of isomorphism *)ClassIsIsomorphism {C : PreCategory} {sd} (m : morphism C s d) :=
{
morphism_inverse : morphism C d s;
left_inverse : morphism_inverse o m = identity _;
right_inverse : m o morphism_inverse = identity _
}.Arguments morphism_inverse {C s d} m {_}.LocalNotation"m ^-1" := (morphism_inverse m) : morphism_scope.#[export]
Hint Resolve left_inverse right_inverse : category morphism.#[export]
Hint Rewrite @left_inverse @right_inverse : category.#[export]
Hint Rewrite @left_inverse @right_inverse : morphism.ClassIsomorphic {C : PreCategory} sd :=
{
morphism_isomorphic : morphism C s d;
isisomorphism_isomorphic :: IsIsomorphism morphism_isomorphic
}.(*Coercion Build_Isomorphic : IsIsomorphism >-> Isomorphic.*)Coercionmorphism_isomorphic : Isomorphic >-> morphism.Coercionisisomorphism_isomorphic : Isomorphic >-> IsIsomorphism.LocalInfix"<~=~>" := Isomorphic : category_scope.(** ** Theorems about isomorphisms *)Sectioniso_contr.VariableC : PreCategory.Variablessd : C.Local NotationIsIsomorphism_sig_T m :=
{ inverse : morphism C d s
| { _ : inverse o m = identity _
| m o inverse = identity _ } } (only parsing).SectionIsIsomorphism.Variablem : morphism C s d.(** *** The inverse of a morphism is unique *)
C: PreCategory s, d: C m: morphism C s d m_inv0, m_inv1: morphism C d s left_inverse_0: m_inv0 o m = 1 right_inverse_1: m o m_inv1 = 1
m_inv0 = m_inv1
C: PreCategory s, d: C m: morphism C s d m_inv0, m_inv1: morphism C d s left_inverse_0: m_inv0 o m = 1 right_inverse_1: m o m_inv1 = 1
m_inv0 = m_inv1
transitivity (m_inv0 o m o m_inv1);
trysolve [ by (rewrite -> ?associativity; rewrite_hyp;
autorewrite with morphism)
| by (rewrite <- ?associativity; rewrite_hyp;
autorewrite with morphism) ].Qed.(** *** Equivalence between the record and sigma versions of [IsIsomorphism] *)
C: PreCategory s, d: C m: morphism C s d
{inverse : morphism C d s &
{_ : inverse o m = 1 & m o inverse = 1}} <~>
IsIsomorphism m
C: PreCategory s, d: C m: morphism C s d
{inverse : morphism C d s &
{_ : inverse o m = 1 & m o inverse = 1}} <~>
IsIsomorphism m
issig.Defined.(** *** Being an isomorphism is a mere proposition *)
C: PreCategory s, d: C m: morphism C s d
IsHProp (IsIsomorphism m)
C: PreCategory s, d: C m: morphism C s d
IsHProp (IsIsomorphism m)
C: PreCategory s, d: C m: morphism C s d
IsHProp
{inverse : morphism C d s &
{_ : inverse o m = 1 & m o inverse = 1}}
C: PreCategory s, d: C m: morphism C s d
forallxy : {inverse : morphism C d s &
{_ : inverse o m = 1 & m o inverse = 1}}, x = y
C: PreCategory s, d: C m: morphism C s d x: morphism C d s proj1: x o m = 1 proj2: m o x = 1 y: morphism C d s proj0: y o m = 1 proj3: m o y = 1
(x; proj1; proj2) = (y; proj0; proj3)
C: PreCategory s, d: C m: morphism C s d x: morphism C d s proj1: x o m = 1 proj2: m o x = 1 proj0: x o m = 1 proj3: m o x = 1
(x; proj1; proj2) = (x; proj0; proj3)
repeatmatch goal with
| _ => progresssimpl
| _ => exact (center _)
| _ => (existsidpath)
| _ => apply path_sigma_uncurried
end.Qed.EndIsIsomorphism.Local NotationIsomorphic_sig_T :=
{ m : morphism C s d
| IsIsomorphism m } (only parsing).(** *** Equivalence between record and sigma versions of [Isomorphic] *)
C: PreCategory s, d: C
{m : morphism C s d & IsIsomorphism m} <~> s <~=~> d
C: PreCategory s, d: C
{m : morphism C s d & IsIsomorphism m} <~> s <~=~> d
issig.Defined.Local NotationIsomorphic_full_sig_T :=
{ m : morphism C s d
| IsIsomorphism_sig_T m } (only parsing).(** *** Equivalence between record and fully sigma versions of [Isomorphic] *)Definitionissig_full_isomorphic
: Isomorphic_full_sig_T <~> Isomorphic s d
:= (issig_isomorphic oE equiv_functor_sigma_id issig_isisomorphism).(** *** Isomorphisms form an hSet *)
C: PreCategory s, d: C
IsHSet (s <~=~> d)
C: PreCategory s, d: C
IsHSet (s <~=~> d)
C: PreCategory s, d: C
IsHSet {m : morphism C s d & IsIsomorphism m}
typeclasses eauto.Qed.(** *** Equality between isomorphisms is determined by equality between their forward components *)
C: PreCategory s, d: C i, j: s <~=~> d
i = j -> i = j
C: PreCategory s, d: C i, j: s <~=~> d
i = j -> i = j
C: PreCategory s, d: C morphism_isomorphic0: morphism C s d isisomorphism_isomorphic0: IsIsomorphism
morphism_isomorphic0 morphism_isomorphic1: morphism C s d isisomorphism_isomorphic1: IsIsomorphism
morphism_isomorphic1
exact (center _).Defined.(** *** Relations between [path_isomorphic], [ap morphism_inverse], and [ap morphism_isomorphic] *)
C: PreCategory s, d: C i, j: s <~=~> d p: i = j
ap (@morphism_isomorphic C s d)
(path_isomorphic i j p) = p
C: PreCategory s, d: C i, j: s <~=~> d p: i = j
ap (@morphism_isomorphic C s d)
(path_isomorphic i j p) = p
C: PreCategory s, d: C i, j: s <~=~> d p: i = j
ap (@morphism_isomorphic C s d)
(paths_rect (morphism C s d) i
(fun (morphism_isomorphic1 : morphism C s d)
(_ : i = morphism_isomorphic1) =>
forallisisomorphism_isomorphic1 : IsIsomorphism
morphism_isomorphic1,
{|
morphism_isomorphic := i;
isisomorphism_isomorphic := i
|} =
{|
morphism_isomorphic := morphism_isomorphic1;
isisomorphism_isomorphic :=
isisomorphism_isomorphic1
|})
(funisisomorphism_isomorphic1 : IsIsomorphism i
=>
ap11 1 (center (i = isisomorphism_isomorphic1)))
j p j) = p
C: PreCategory s, d: C morphism_isomorphic0: morphism C s d isisomorphism_isomorphic0: IsIsomorphism
morphism_isomorphic0 morphism_isomorphic1: morphism C s d isisomorphism_isomorphic1: IsIsomorphism
morphism_isomorphic1 p: {|
morphism_isomorphic := morphism_isomorphic0;
isisomorphism_isomorphic :=
isisomorphism_isomorphic0
|} =
{|
morphism_isomorphic := morphism_isomorphic1;
isisomorphism_isomorphic :=
isisomorphism_isomorphic1
|}
ap (@morphism_isomorphic C s d)
(paths_rect (morphism C s d) morphism_isomorphic0
(fun (morphism_isomorphic1 : morphism C s d)
(_ : morphism_isomorphic0 =
morphism_isomorphic1) =>
forallisisomorphism_isomorphic1 : IsIsomorphism
morphism_isomorphic1,
{|
morphism_isomorphic := morphism_isomorphic0;
isisomorphism_isomorphic :=
isisomorphism_isomorphic0
|} =
{|
morphism_isomorphic := morphism_isomorphic1;
isisomorphism_isomorphic :=
isisomorphism_isomorphic1
|})
(funisisomorphism_isomorphic1 : IsIsomorphism
morphism_isomorphic0
=>
ap11 1
(center
(isisomorphism_isomorphic0 =
isisomorphism_isomorphic1)))
morphism_isomorphic1 p isisomorphism_isomorphic1) =
p
path_induction_hammer.Qed.
C: PreCategory s, d: C i, j: s <~=~> d p: i = j q: (fune : s <~=~> d => e^-1) i =
(fune : s <~=~> d => e^-1) j
ap (fune : s <~=~> d => e^-1) (path_isomorphic i j p) =
q
C: PreCategory s, d: C i, j: s <~=~> d p: i = j q: (fune : s <~=~> d => e^-1) i =
(fune : s <~=~> d => e^-1) j
ap (fune : s <~=~> d => e^-1) (path_isomorphic i j p) =
q
apply path_ishprop.Qed.(** *** Equality between isomorphisms is equivalent to by equality between their forward components *)
C: PreCategory s, d: C i, j: s <~=~> d
IsEquiv (path_isomorphic i j)
C: PreCategory s, d: C i, j: s <~=~> d
IsEquiv (path_isomorphic i j)
C: PreCategory s, d: C i, j: s <~=~> d
IsEquiv (path_isomorphic i j)
apply (isequiv_adjointify
(path_isomorphic i j)
(ap (@morphism_isomorphic _ _ _)));
intro; [ destruct i | destruct i, j ];
path_induction_hammer.Defined.Endiso_contr.Sectioniso_equiv_relation.VariableC : PreCategory.(** *** The identity is an isomorphism *)#[export] Instanceisisomorphism_identity (x : C) : IsIsomorphism (identity x)
:= {| morphism_inverse := identity x;
left_inverse := left_identity C x x (identity x);
right_inverse := right_identity C x x (identity x) |}.(** *** Inverses of isomorphisms are isomorphisms *)Definitionisisomorphism_inverse `(@IsIsomorphism C x y m) : IsIsomorphism m^-1
:= {| morphism_inverse := m;
left_inverse := right_inverse;
right_inverse := left_inverse |}.Local Ltaciso_comp_t inv_lemma :=
etransitivity; [ | apply inv_lemma ];
first [ rewrite -> ?associativity; apply ap
| rewrite <- ?associativity; apply ap ];
first [ rewrite -> ?associativity; rewrite inv_lemma
| rewrite <- ?associativity; rewrite inv_lemma ];
auto with morphism.(** *** Composition of isomorphisms gives an isomorphism *)
C: PreCategory y, z: C m0: morphism C y z H: IsIsomorphism m0 x: C m1: morphism C x y H0: IsIsomorphism m1
IsIsomorphism (m0 o m1)
C: PreCategory y, z: C m0: morphism C y z H: IsIsomorphism m0 x: C m1: morphism C x y H0: IsIsomorphism m1
IsIsomorphism (m0 o m1)
exists (m1^-1 o m0^-1);
[ abstract iso_comp_t @left_inverse
| abstract iso_comp_t @right_inverse ].Defined.#[local]
Hint Immediate isisomorphism_inverse : typeclass_instances.(** *** Being isomorphic is a reflexive relation *)#[export] Instanceisomorphic_refl : Reflexive (@Isomorphic C)
:= funx : C => {| morphism_isomorphic := identity x |}.(** *** Being isomorphic is a symmetric relation *)#[export] Instanceisomorphic_sym : Symmetric (@Isomorphic C)
:= funxyX => {| morphism_isomorphic := X^-1 |}.(** *** Being isomorphic is a transitive relation *)#[export] Instanceisomorphic_trans : Transitive (@Isomorphic C)
:= funxyzXY => {| morphism_isomorphic := @morphism_isomorphic _ _ _ Y o @morphism_isomorphic _ _ _ X |}.(** *** Equality gives rise to isomorphism *)Definitionidtoiso (xy : C) (H : x = y) : Isomorphic x y
:= match H in (_ = y0) return (x <~=~> y0) with
| 1%path => reflexivity x
end.Endiso_equiv_relation.#[export]
Hint Immediate isisomorphism_inverse : typeclass_instances.(** ** Epimorphisms and Monomorphisms *)(** Quoting Wikipedia: In category theory, an epimorphism (also called an epic morphism or, colloquially, an epi) is a morphism [f : X → Y] which is right-cancellative in the sense that, for all morphisms [g, g' : Y → Z], [g ∘ f = g' ∘ f → g = g'] Epimorphisms are analogues of surjective functions, but they are not exactly the same. The dual of an epimorphism is a monomorphism (i.e. an epimorphism in a category [C] is a monomorphism in the dual category [Cᵒᵖ]). *)ClassIsEpimorphism {C} {xy} (m : morphism C x y) :=
is_epimorphism : forallz (m1m2 : morphism C y z),
m1 o m = m2 o m
-> m1 = m2.ClassIsMonomorphism {C} {xy} (m : morphism C x y) :=
is_monomorphism : forallz (m1m2 : morphism C z x),
m o m1 = m o m2
-> m1 = m2.(** We make [IsEpimorphism] and [IsMonomorphism] transparent to typeclass search so that we can infer things like [IsHProp] automatically. *)#[global] Typeclasses Transparent IsEpimorphism IsMonomorphism.RecordEpimorphism {C} xy :=
{
Epimorphism_morphism :> morphism C x y;
Epimorphism_IsEpimorphism :> IsEpimorphism Epimorphism_morphism
}.RecordMonomorphism {C} xy :=
{
Monomorphism_morphism :> morphism C x y;
Monomorphism_IsMonomorphism :> IsMonomorphism Monomorphism_morphism
}.Existing Instances Epimorphism_IsEpimorphism Monomorphism_IsMonomorphism.LocalNotation"x ->> y" := (Epimorphism x y).LocalNotation"x (-> y" := (Monomorphism x y).ClassIsSectionOfCxy (s : morphism C x y) (r : morphism C y x)
:= is_sect_morphism : r o s = identity _.Arguments IsSectionOf [C x y] s r.SectionEpiMono.VariableC : PreCategory.Sectionproperties.(** *** The identity is an epimorphism *)
C: PreCategory x: C
IsEpimorphism 1
C: PreCategory x: C
IsEpimorphism 1
repeatintro; autorewrite with morphism in *; trivial.Qed.(** *** The identity is a monomorphism *)
C: PreCategory x: C
IsMonomorphism 1
C: PreCategory x: C
IsMonomorphism 1
repeatintro; autorewrite with morphism in *; trivial.Qed.(** *** Composition of epimorphisms gives an epimorphism *)
C: PreCategory s, d, d': C m0: morphism C d d' m1: morphism C s d
IsEpimorphism m0 ->
IsEpimorphism m1 -> IsEpimorphism (m0 o m1)
C: PreCategory s, d, d': C m0: morphism C d d' m1: morphism C s d
IsEpimorphism m0 ->
IsEpimorphism m1 -> IsEpimorphism (m0 o m1)
C: PreCategory s, d, d': C m0: morphism C d d' m1: morphism C s d X: IsEpimorphism m0 X0: IsEpimorphism m1 z: C m2, m3: morphism C d' z X1: m2 o (m0 o m1) = m3 o (m0 o m1)
m2 = m3
C: PreCategory s, d, d': C m0: morphism C d d' m1: morphism C s d X: IsEpimorphism m0 X0: IsEpimorphism m1 z: C m2, m3: morphism C d' z X1: m2 o m0 o m1 = m3 o m0 o m1
m2 = m3
apply_hyp.Qed.(** *** Composition of monomorphisms gives a monomorphism *)
C: PreCategory s, d, d': C m0: morphism C d d' m1: morphism C s d
IsMonomorphism m0 ->
IsMonomorphism m1 -> IsMonomorphism (m0 o m1)
C: PreCategory s, d, d': C m0: morphism C d d' m1: morphism C s d
IsMonomorphism m0 ->
IsMonomorphism m1 -> IsMonomorphism (m0 o m1)
C: PreCategory s, d, d': C m0: morphism C d d' m1: morphism C s d X: IsMonomorphism m0 X0: IsMonomorphism m1 z: C m2, m3: morphism C z s X1: m0 o m1 o m2 = m0 o m1 o m3
m2 = m3
C: PreCategory s, d, d': C m0: morphism C d d' m1: morphism C s d X: IsMonomorphism m0 X0: IsMonomorphism m1 z: C m2, m3: morphism C z s X1: m0 o (m1 o m2) = m0 o (m1 o m3)
m2 = m3
apply_hyp.Qed.Endproperties.(** *** Existence of {epi,mono}morphisms are a preorder *)Sectionequiv.#[export] Instancereflexive_epimorphism : Reflexive (@Epimorphism C)
:= funx => Build_Epimorphism (isepimorphism_identity x).#[export] Instancereflexive_monomorphism : Reflexive (@Monomorphism C)
:= funx => Build_Monomorphism (ismonomorphism_identity x).#[export] Instancetransitive_epimorphism : Transitive (@Epimorphism C)
:= fun___m0m1 => Build_Epimorphism (isepimorphism_compose m1 m0).#[export] Instancetransitive_monomorphism : Transitive (@Monomorphism C)
:= fun___m0m1 => Build_Monomorphism (ismonomorphism_compose m1 m0).Endequiv.Sectionsect.Local Ltacepi_mono_sect_t :=
lett :=
(solve [ autorewrite with morphism;
reflexivity
| rewrite_hyp;
autorewrite with morphism;
reflexivity ]) infirst [ rewrite -> ?associativity; t
| rewrite <- ?associativity; t].(** *** Retractions are epimorphisms *)
C: PreCategory x, y: C s: morphism C x y r: morphism C y x H: IsSectionOf s r
IsEpimorphism r
C: PreCategory x, y: C s: morphism C x y r: morphism C y x H: IsSectionOf s r
IsEpimorphism r
C: PreCategory x, y: C s: morphism C x y r: morphism C y x H: IsSectionOf s r z: C m1, m2: morphism C x z X: m1 o r = m2 o r
m1 = m2
C: PreCategory x, y: C s: morphism C x y r: morphism C y x H: r o s = 1 z: C m1, m2: morphism C x z X: m1 o r = m2 o r
m1 = m2
transitivity ((m1 o r) o s);
[ | transitivity ((m2 o r) o s) ];
epi_mono_sect_t.Qed.(** *** Sections are monomorphisms *)
C: PreCategory x, y: C s: morphism C x y r: morphism C y x H: IsSectionOf s r
IsMonomorphism s
C: PreCategory x, y: C s: morphism C x y r: morphism C y x H: IsSectionOf s r
IsMonomorphism s
C: PreCategory x, y: C s: morphism C x y r: morphism C y x H: IsSectionOf s r z: C m1, m2: morphism C z x X: s o m1 = s o m2
m1 = m2
transitivity (r o (s o m1));
[ | transitivity (r o (s o m2)) ];
epi_mono_sect_t.Qed.(** *** Isomorphisms are both sections and retractions *)#[export] Instanceissect_isisomorphism `(@IsIsomorphism C x y m)
: IsSectionOf m m^-1 | 1000
:= left_inverse.#[export] Instanceisretr_isisomorphism `(@IsIsomorphism C x y m)
: IsSectionOf m^-1 m | 1000
:= right_inverse.Endsect.(** *** Isomorphisms are therefore epimorphisms and monomorphisms *)Sectioniso.#[export] Instanceisepimorphism_isisomorphism `(@IsIsomorphism C s d m)
: IsEpimorphism m | 1000
:= _.#[export] Instanceismonomorphism_isisomorphism `(@IsIsomorphism C s d m)
: IsMonomorphism m | 1000
:= _.Endiso.EndEpiMono.#[export] Hint Immediate isisomorphism_inverse : typeclass_instances.#[export]
Hint Immediate
isepimorphism_identity ismonomorphism_identity
ismonomorphism_compose isepimorphism_compose
: category morphism.(** ** Lemmas about [idtoiso] *)Sectioniso_lemmas.Local Ltacidtoiso_t :=
path_induction; simpl; autorewrite with morphism; reflexivity.(** *** [transport]ing across an equality of morphisms is the same as conjugating with [idtoiso] *)
C, D: PreCategory s, d: C m1, m2: morphism C s d p: m1 = m2 s', d': morphism C s d -> D u: morphism D (s' m1) (d' m1)
transport
(funm : morphism C s d => morphism D (s' m) (d' m))
p u =
idtoiso D (ap d' p) o u o (idtoiso D (ap s' p))^-1
C, D: PreCategory s, d: C m1, m2: morphism C s d p: m1 = m2 s', d': morphism C s d -> D u: morphism D (s' m1) (d' m1)
transport
(funm : morphism C s d => morphism D (s' m) (d' m))
p u =
idtoiso D (ap d' p) o u o (idtoiso D (ap s' p))^-1