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.
(** * Universal morphisms *)
[Loading ML file number_string_notation_plugin.cmxs (using legacy method) ... done]
Require Import Category.Dual Functor.Dual.Require Import Category.Objects.Require Import InitialTerminalCategory.Core InitialTerminalCategory.Functors.Require Comma.Core.Local Set Warnings"-notation-overridden". (* work around bug #5567, https://coq.inria.fr/bugs/show_bug.cgi?id=5567, notation-overridden,parsing should not trigger for only printing notations *)Import Comma.Core.Local Set Warnings"notation-overridden".Require Import Trunc Types.Sigma HoTT.Tactics.Require Import Basics.Tactics.Set Universe Polymorphism.Set Implicit Arguments.Generalizable All Variables.Set Asymmetric Patterns.LocalOpen Scope morphism_scope.SectionUniversalMorphism.(** Quoting Wikipedia: Suppose that [U : D → C] is a functor from a category [D] to a category [C], and let [X] be an object of [C]. Consider the following dual (opposite) notions: *)Local Ltacuniv_hprop_t UniversalProperty :=
apply @istrunc_succ in UniversalProperty;
eapply @istrunc_sigma;
first [ intro;
simpl;
match goal with
| [ |- context[?m o 1] ]
=> simplrewrite (right_identity _ _ _ m)
| [ |- context[1 o ?m] ]
=> simplrewrite (left_identity _ _ _ m)
end;
assumption
| bytypeclasses eauto ].(** ** Initial morphisms *)SectionInitialMorphism.(** *** Definition *)VariablesCD : PreCategory.VariableX : C.VariableU : Functor D C.(** An initial morphism from [X] to [U] is an initial object in the category [(X ↓ U)] of morphisms from [X] to [U]. In other words, it consists of a pair [(A, φ)] where [A] is an object of [D] and [φ: X → U A] is a morphism in [C], such that the following initial property is satisfied: - Whenever [Y] is an object of [D] and [f : X → U Y] is a morphism in [C], then there exists a unique morphism [g : A → Y] such that the following diagram commutes:<< φ X -----> U A A \ . . \ . U g . g f \ . . ↘ ↓ ↓ U Y Y>> *)DefinitionIsInitialMorphism (Ap : object (X / U)) :=
IsInitialObject (X / U) Ap.(** *** Introduction rule *)SectionIntroductionAbstractionBarrier.
C, D: PreCategory X: C U: Functor D C A: D p: morphism C X (U _0 A)%object Ap:= {|
CommaCategory.a := tt;
CommaCategory.b := A;
CommaCategory.f := p
|}: CommaCategory.object !X U UniversalProperty: forall (A' : D)
(p' : morphism C X
(U _0 A')%object),
Contr
{m : morphism D A A' &
U _1 m o p = p'}
IsInitialMorphism Ap
C, D: PreCategory X: C U: Functor D C A: D p: morphism C X (U _0 A)%object Ap:= {|
CommaCategory.a := tt;
CommaCategory.b := A;
CommaCategory.f := p
|}: CommaCategory.object !X U UniversalProperty: forall (A' : D)
(p' : morphism C X
(U _0 A')%object),
Contr
{m : morphism D A A' &
U _1 m o p = p'}
IsInitialMorphism Ap
C, D: PreCategory X: C U: Functor D C A: D p: morphism C X (U _0 A)%object Ap:= {|
CommaCategory.a := tt;
CommaCategory.b := A;
CommaCategory.f := p
|}: CommaCategory.object !X U UniversalProperty: forall (A' : D)
(p' : morphism C X
(U _0 A')%object),
Contr
{m : morphism D A A' &
U _1 m o p = p'} x: (X / U)%category
Contr (morphism (X / U) Ap x)
C, D: PreCategory X: C U: Functor D C A: D p: morphism C X (U _0 A)%object Ap:= {|
CommaCategory.a := tt;
CommaCategory.b := A;
CommaCategory.f := p
|}: CommaCategory.object !X U x: (X / U)%category UniversalProperty: Contr
{m
: morphism D A
(CommaCategory.b x) &
U _1 m o p = CommaCategory.f x}
Contr (morphism (X / U) Ap x)
(** We want to preserve the computation rules for the morphisms, even though they're unique up to unique isomorphism. *)
C, D: PreCategory X: C U: Functor D C A: D p: morphism C X (U _0 A)%object Ap:= {|
CommaCategory.a := tt;
CommaCategory.b := A;
CommaCategory.f := p
|}: CommaCategory.object !X U x: (X / U)%category UniversalProperty: Contr
{m
: morphism D A
(CommaCategory.b x) &
U _1 m o p = CommaCategory.f x}
?A <~> morphism (X / U) Ap x
C, D: PreCategory X: C U: Functor D C A: D p: morphism C X (U _0 A)%object Ap:= {|
CommaCategory.a := tt;
CommaCategory.b := A;
CommaCategory.f := p
|}: CommaCategory.object !X U x: (X / U)%category UniversalProperty: Contr
{m
: morphism D A
(CommaCategory.b x) &
U _1 m o p = CommaCategory.f x}
Contr ?A
C, D: PreCategory X: C U: Functor D C A: D p: morphism C X (U _0 A)%object Ap:= {|
CommaCategory.a := tt;
CommaCategory.b := A;
CommaCategory.f := p
|}: CommaCategory.object !X U x: (X / U)%category UniversalProperty: Contr
{m
: morphism D A
(CommaCategory.b x) &
U _1 m o p = CommaCategory.f x}
?A <~> morphism (X / U) Ap x
apply CommaCategory.issig_morphism.
C, D: PreCategory X: C U: Functor D C A: D p: morphism C X (U _0 A)%object Ap:= {|
CommaCategory.a := tt;
CommaCategory.b := A;
CommaCategory.f := p
|}: CommaCategory.object !X U x: (X / U)%category UniversalProperty: Contr
{m
: morphism D A
(CommaCategory.b x) &
U _1 m o p = CommaCategory.f x}
Contr
{g
: morphism (NatCategory.Core.nat_category (S O))
(CommaCategory.a Ap) (CommaCategory.a x) &
{h
: morphism D (CommaCategory.b Ap)
(CommaCategory.b x) &
U _1 h o CommaCategory.f Ap =
CommaCategory.f x o X _1 g}}
C, D: PreCategory X: C U: Functor D C A: D p: morphism C X (U _0 A)%object Ap:= {|
CommaCategory.a := tt;
CommaCategory.b := A;
CommaCategory.f := p
|}: CommaCategory.object !X U x: (X / U)%category UniversalProperty: Contr
{m
: morphism D A
(CommaCategory.b x) &
U _1 m o p = CommaCategory.f x}
IsHProp
{g
: morphism (NatCategory.Core.nat_category (S O))
(CommaCategory.a Ap) (CommaCategory.a x) &
{h
: morphism D (CommaCategory.b Ap)
(CommaCategory.b x) &
U _1 h o CommaCategory.f Ap =
CommaCategory.f x o X _1 g}}
C, D: PreCategory X: C U: Functor D C A: D p: morphism C X (U _0 A)%object Ap:= {|
CommaCategory.a := tt;
CommaCategory.b := A;
CommaCategory.f := p
|}: CommaCategory.object !X U x: (X / U)%category UniversalProperty: Contr
{m
: morphism D A
(CommaCategory.b x) &
U _1 m o p = CommaCategory.f x}
{g
: morphism (NatCategory.Core.nat_category (S O))
(CommaCategory.a Ap)
(CommaCategory.a x) &
{h
: morphism D (CommaCategory.b Ap) (CommaCategory.b x)
&
U _1 h o CommaCategory.f Ap =
CommaCategory.f x o X _1 g}}
C, D: PreCategory X: C U: Functor D C A: D p: morphism C X (U _0 A)%object Ap:= {|
CommaCategory.a := tt;
CommaCategory.b := A;
CommaCategory.f := p
|}: CommaCategory.object !X U x: (X / U)%category UniversalProperty: Contr
{m
: morphism D A
(CommaCategory.b x) &
U _1 m o p = CommaCategory.f x}
IsHProp
{g
: morphism (NatCategory.Core.nat_category (S O))
(CommaCategory.a Ap) (CommaCategory.a x) &
{h
: morphism D (CommaCategory.b Ap)
(CommaCategory.b x) &
U _1 h o CommaCategory.f Ap =
CommaCategory.f x o X _1 g}}
abstract univ_hprop_t UniversalProperty.
C, D: PreCategory X: C U: Functor D C A: D p: morphism C X (U _0 A)%object Ap:= {|
CommaCategory.a := tt;
CommaCategory.b := A;
CommaCategory.f := p
|}: CommaCategory.object !X U x: (X / U)%category UniversalProperty: Contr
{m
: morphism D A
(CommaCategory.b x) &
U _1 m o p = CommaCategory.f x}
{g
: morphism (NatCategory.Core.nat_category (S O))
(CommaCategory.a Ap) (CommaCategory.a x) &
{h
: morphism D (CommaCategory.b Ap) (CommaCategory.b x)
&
U _1 h o CommaCategory.f Ap =
CommaCategory.f x o X _1 g}}
C, D: PreCategory X: C U: Functor D C A: D p: morphism C X (U _0 A)%object Ap:= {|
CommaCategory.a := tt;
CommaCategory.b := A;
CommaCategory.f := p
|}: CommaCategory.object !X U x: (X / U)%category UniversalProperty: Contr
{m
: morphism D A
(CommaCategory.b x) &
U _1 m o p = CommaCategory.f x}
{h
: morphism D (CommaCategory.b Ap) (CommaCategory.b x)
&
U _1 h o CommaCategory.f Ap =
CommaCategory.f x o X _1 tt}
C, D: PreCategory X: C U: Functor D C A: D p: morphism C X (U _0 A)%object Ap:= {|
CommaCategory.a := tt;
CommaCategory.b := A;
CommaCategory.f := p
|}: CommaCategory.object !X U x: (X / U)%category UniversalProperty: Contr
{m
: morphism D A
(CommaCategory.b x) &
U _1 m o p = CommaCategory.f x}
U
_1 (center
{m : morphism D A (CommaCategory.b x) &
U _1 m o p = CommaCategory.f x}).1
o CommaCategory.f Ap = CommaCategory.f x o X _1 tt
abstract (progressrewrite?right_identity, ?left_identity;
exact (@center _ UniversalProperty).2).Defined.DefinitionBuild_IsInitialMorphism_curried
(A : D)
(p : morphism C X (U A))
(Ap := CommaCategory.Build_object !X U tt A p)
(m : forall (A' : D) (p' : morphism C X (U A')),
morphism D A A')
(H : forall (A' : D) (p' : morphism C X (U A')),
U _1 (m A' p') o p = p')
(H' : forall (A' : D) (p' : morphism C X (U A')) m',
U _1 m' o p = p'
-> m A' p' = m')
: IsInitialMorphism Ap
:= Build_IsInitialMorphism
A
p
(funA'p' =>
Build_Contr _ (m A' p'; H A' p')
(funm' => path_sigma
_
(m A' p'; H A' p')
m'
(H' A' p' m'.1 m'.2)
(center _))).(** Projections from nested sigmas are currently rather slow. We should just be able to do<< Definition Build_IsInitialMorphism_uncurried (univ : { A : D | { p : morphism C X (U A) | let Ap := CommaCategory.Build_object !X U tt A p in forall (A' : D) (p' : morphism C X (U A')), { m : morphism D A A' | { H : U _1 m o p = p' | forall m', U _1 m' o p = p' -> m = m' }}}}) := @Build_IsInitialMorphism_curried (univ.1) (univ.2.1) (fun A' p' => (univ.2.2 A' p').1) (fun A' p' => (univ.2.2 A' p').2.1) (fun A' p' => (univ.2.2 A' p').2.2).>> But that's currently too slow. (About 6-8 seconds, on my machine.) So instead we factor out all of the type parts by hand, and then apply them after. *)Letmake_uncurriedA'B'C'D'E'0
(E'1 : forallaa'bb' (c : C' a a'), D' a a' b b' c -> E'0 a a' -> Type)
(E' : forallaa'bb' (c : C' a a'), D' a a' b b' c -> E'0 a a' -> Type)
F'
(f : forall (a : A')
(b : B' a)
(c : forall (a' : A') (b' : B' a'),
C' a a')
(d : forall (a' : A') (b' : B' a'),
D' a a' b b' (c a' b'))
(e : forall (a' : A') (b' : B' a')
(e0 : E'0 a a')
(e1 : E'1 a a' b b' (c a' b') (d a' b') e0),
E' a a' b b' (c a' b') (d a' b') e0),
F' a b)
(univ
: { a : A'
| { b : B' a
| forall (a' : A') (b' : B' a'),
{ c : C' a a'
| { d : D' a a' b b' c
| forall (e0 : E'0 a a')
(e1 : E'1 a a' b b' c d e0),
E' a a' b b' c d e0 }}}})
: F' univ.1 univ.2.1
:= f
(univ.1)
(univ.2.1)
(funA'p' => (univ.2.2 A' p').1)
(funA'p' => (univ.2.2 A' p').2.1)
(funA'p' => (univ.2.2 A' p').2.2).DefinitionBuild_IsInitialMorphism_uncurried
: forall (univ
: { A : D
| { p : morphism C X (U A)
| letAp := CommaCategory.Build_object !X U tt A p inforall (A' : D) (p' : morphism C X (U A')),
{ m : morphism D A A'
| { H : U _1 m o p = p'
| forallm',
U _1 m' o p = p'
-> m = m' }}}}),
IsInitialMorphism (CommaCategory.Build_object !X U tt univ.1 univ.2.1)
:= @make_uncurried
_ _ _ _ _ _ _ _
(@Build_IsInitialMorphism_curried).EndIntroductionAbstractionBarrier.GlobalArguments Build_IsInitialMorphism : simpl never.GlobalArguments Build_IsInitialMorphism_curried : simpl never.GlobalArguments Build_IsInitialMorphism_uncurried : simpl never.(** *** Elimination rule *)SectionEliminationAbstractionBarrier.VariableAp : object (X / U).DefinitionIsInitialMorphism_object (M : IsInitialMorphism Ap) : D
:= CommaCategory.b Ap.DefinitionIsInitialMorphism_morphism (M : IsInitialMorphism Ap)
: morphism C X (U (IsInitialMorphism_object M))
:= CommaCategory.f Ap.DefinitionIsInitialMorphism_property_morphism (M : IsInitialMorphism Ap)
(Y : D) (f : morphism C X (U Y))
: morphism D (IsInitialMorphism_object M) Y
:= CommaCategory.h
(@center _ (M (CommaCategory.Build_object !X U tt Y f))).DefinitionIsInitialMorphism_property_morphism_property
(M : IsInitialMorphism Ap)
(Y : D) (f : morphism C X (U Y))
: (U _1 (IsInitialMorphism_property_morphism M Y f))
o IsInitialMorphism_morphism M = f
:= concat
(CommaCategory.p
(@center _ (M (CommaCategory.Build_object !X U tt Y f))))
(right_identity _ _ _ _).DefinitionIsInitialMorphism_property_morphism_unique
(M : IsInitialMorphism Ap)
(Y : D) (f : morphism C X (U Y))
m'
(H : U _1 m' o IsInitialMorphism_morphism M = f)
: IsInitialMorphism_property_morphism M Y f = m'
:= ap
(@CommaCategory.h _ _ _ _ _ _ _)
(@contr _
(M (CommaCategory.Build_object !X U tt Y f))
(CommaCategory.Build_morphism
Ap (CommaCategory.Build_object !X U tt Y f)
tt m' (H @ (right_identity _ _ _ _)^)%path)).DefinitionIsInitialMorphism_property
(M : IsInitialMorphism Ap)
(Y : D) (f : morphism C X (U Y))
: Contr { m : morphism D (IsInitialMorphism_object M) Y
| U _1 m o IsInitialMorphism_morphism M = f }
:= Build_Contr _ (IsInitialMorphism_property_morphism M Y f;
IsInitialMorphism_property_morphism_property M Y f)
(funm' => path_sigma
_
(IsInitialMorphism_property_morphism M Y f;
IsInitialMorphism_property_morphism_property M Y f)
m'
(@IsInitialMorphism_property_morphism_unique M Y f m'.1 m'.2)
(center _)).EndEliminationAbstractionBarrier.GlobalArguments IsInitialMorphism_object : simpl never.GlobalArguments IsInitialMorphism_morphism : simpl never.GlobalArguments IsInitialMorphism_property : simpl never.GlobalArguments IsInitialMorphism_property_morphism : simpl never.GlobalArguments IsInitialMorphism_property_morphism_property : simpl never.GlobalArguments IsInitialMorphism_property_morphism_unique : simpl never.EndInitialMorphism.(** ** Terminal morphisms *)SectionTerminalMorphism.(** *** Definition *)VariablesCD : PreCategory.VariableU : Functor D C.VariableX : C.(** A terminal morphism from [U] to [X] is a terminal object in the comma category [(U ↓ X)] of morphisms from [U] to [X]. In other words, it consists of a pair [(A, φ)] where [A] is an object of [D] and [φ : U A -> X] is a morphism in [C], such that the following terminal property is satisfied: - Whenever [Y] is an object of [D] and [f : U Y -> X] is a morphism in [C], then there exists a unique morphism [g : Y -> A] such that the following diagram commutes:<< Y U Y . . \ g . U g . \ f . . \ ↓ ↓ ↘ A U A -----> X φ>> *)Local Notationop_object Ap
:= (CommaCategory.Build_object
(Functors.from_terminal C^op X) (U^op)
(CommaCategory.b (Ap : object (U / X)))
(CommaCategory.a (Ap : object (U / X)))
(CommaCategory.f (Ap : object (U / X)))
: object ((X : object C^op) / U^op)).DefinitionIsTerminalMorphism (Ap : object (U / X)) : Type
:= @IsInitialMorphism
(C^op)
_
X
(U^op)
(op_object Ap).(** *** Introduction rule *)SectionIntroductionAbstractionBarrier.DefinitionBuild_IsTerminalMorphism
: forall
(*(Ap : Object (U ↓ X))*)
(A : D)(* := CommaCategory.a Ap*)
(p : morphism C (U A) X)(*:= CommaCategory.f Ap*)
(Ap := CommaCategory.Build_object U !X A tt p)
(UniversalProperty
: forall (A' : D) (p' : morphism C (U A') X),
Contr { m : morphism D A' A
| p o U _1 m = p' }),
IsTerminalMorphism Ap
:= @Build_IsInitialMorphism
(C^op)
(D^op)
X
(U^op).DefinitionBuild_IsTerminalMorphism_curried
: forall
(A : D)
(p : morphism C (U A) X)
(Ap := CommaCategory.Build_object U !X A tt p)
(m : forall (A' : D) (p' : morphism C (U A') X),
morphism D A' A)
(H : forall (A' : D) (p' : morphism C (U A') X),
p o U _1 (m A' p') = p')
(H' : forall (A' : D) (p' : morphism C (U A') X) m',
p o U _1 m' = p'
-> m A' p' = m'),
IsTerminalMorphism Ap
:= @Build_IsInitialMorphism_curried
(C^op)
(D^op)
X
(U^op).DefinitionBuild_IsTerminalMorphism_uncurried
: forall
(univ : { A : D
| { p : morphism C (U A) X
| letAp := CommaCategory.Build_object U !X A tt p inforall (A' : D) (p' : morphism C (U A') X),
{ m : morphism D A' A
| { H : p o U _1 m = p'
| forallm',
p o U _1 m' = p'
-> m = m' }}}}),
IsTerminalMorphism (CommaCategory.Build_object U !X univ.1 tt univ.2.1)
:= @Build_IsInitialMorphism_uncurried
(C^op)
(D^op)
X
(U^op).EndIntroductionAbstractionBarrier.(** *** Elimination rule *)SectionEliminationAbstractionBarrier.VariableAp : object (U / X).VariableM : IsTerminalMorphism Ap.DefinitionIsTerminalMorphism_object : D :=
@IsInitialMorphism_object C^op D^op X U^op (op_object Ap) M.DefinitionIsTerminalMorphism_morphism
: morphism C (U IsTerminalMorphism_object) X
:= @IsInitialMorphism_morphism C^op D^op X U^op (op_object Ap) M.DefinitionIsTerminalMorphism_property
: forall (Y : D) (f : morphism C (U Y) X),
Contr { m : morphism D Y IsTerminalMorphism_object
| IsTerminalMorphism_morphism o U _1 m = f }
:= @IsInitialMorphism_property C^op D^op X U^op (op_object Ap) M.DefinitionIsTerminalMorphism_property_morphism
: forall (Y : D) (f : morphism C (U Y) X),
morphism D Y IsTerminalMorphism_object
:= @IsInitialMorphism_property_morphism
C^op D^op X U^op (op_object Ap) M.DefinitionIsTerminalMorphism_property_morphism_property
: forall (Y : D) (f : morphism C (U Y) X),
IsTerminalMorphism_morphism
o (U _1 (IsTerminalMorphism_property_morphism Y f))
= f
:= @IsInitialMorphism_property_morphism_property
C^op D^op X U^op (op_object Ap) M.DefinitionIsTerminalMorphism_property_morphism_unique
: forall (Y : D) (f : morphism C (U Y) X)
m'
(H : IsTerminalMorphism_morphism o U _1 m' = f),
IsTerminalMorphism_property_morphism Y f = m'
:= @IsInitialMorphism_property_morphism_unique
C^op D^op X U^op (op_object Ap) M.EndEliminationAbstractionBarrier.EndTerminalMorphism.SectionUniversalMorphism.(** The term universal morphism refers either to an initial morphism or a terminal morphism, and the term universal property refers either to an initial property or a terminal property. In each definition, the existence of the morphism [g] intuitively expresses the fact that [(A, φ)] is ``general enough'', while the uniqueness of the morphism ensures that [(A, φ)] is ``not too general''. *)EndUniversalMorphism.EndUniversalMorphism.Arguments Build_IsInitialMorphism [C D] X U A p UniversalProperty _.Arguments Build_IsTerminalMorphism [C D] U X A p UniversalProperty _.