Built with Alectryon, running Coq+SerAPI v8.18.0+0.18.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.
(* -*- mode: coq; mode: visual-line -*- *)
[Loading ML file number_string_notation_plugin.cmxs (using legacy method) ... done]
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasMorExt A
foralla : A^op * A,
fmap (uncurry Hom) (Id a) $== Id (uncurry Hom a)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasMorExt A a1: A^op a2: A f: uncurry Hom (a1, a2)
Id a2 $o f $o Id a1 = f
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasMorExt A a1: A^op a2: A f: uncurry Hom (a1, a2)
Id a2 $o f $o Id a1 $== f
exact (cat_idr _ $@ cat_idl f).
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasMorExt A
forall (abc : A^op * A)
(f : a $-> b) (g : b $-> c),
fmap (uncurry Hom) (g $o f) $==
fmap (uncurry Hom) g $o fmap (uncurry Hom) f
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasMorExt A a1: A^op a2: A b1: A^op b2: A c1: A^op c2: A f1: b1 $-> a1 f2: a2 $-> b2 g1: c1 $-> b1 g2: b2 $-> c2 h: uncurry Hom (a1, a2)
g2 $o f2 $o h $o (f1 $o g1) =
g2 $o (f2 $o h $o f1) $o g1
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasMorExt A a1: A^op a2: A b1: A^op b2: A c1: A^op c2: A f1: b1 $-> a1 f2: a2 $-> b2 g1: c1 $-> b1 g2: b2 $-> c2 h: uncurry Hom (a1, a2)
g2 $o f2 $o h $o (f1 $o g1) $==
g2 $o (f2 $o h $o f1) $o g1
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasMorExt A a1: A^op a2: A b1: A^op b2: A c1: A^op c2: A f1: b1 $-> a1 f2: a2 $-> b2 g1: c1 $-> b1 g2: b2 $-> c2 h: uncurry Hom (a1, a2)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasMorExt A a1: A^op a2: A b1: A^op b2: A c1: A^op c2: A f1: b1 $-> a1 f2: a2 $-> b2 g1: c1 $-> b1 g2: b2 $-> c2 h: uncurry Hom (a1, a2)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasMorExt A a1: A^op a2: A b1: A^op b2: A c1: A^op c2: A f1: b1 $-> a1 f2: a2 $-> b2 g1: c1 $-> b1 g2: b2 $-> c2 h: uncurry Hom (a1, a2)
g2 $o (f2 $o (h $o (f1 $o g1))) $==
g2 $o (f2 $o h $o f1 $o g1)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasMorExt A a1: A^op a2: A b1: A^op b2: A c1: A^op c2: A f1: b1 $-> a1 f2: a2 $-> b2 g1: c1 $-> b1 g2: b2 $-> c2 h: uncurry Hom (a1, a2)
f2 $o (h $o (f1 $o g1)) $== f2 $o h $o f1 $o g1
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasMorExt A a1: A^op a2: A b1: A^op b2: A c1: A^op c2: A f1: b1 $-> a1 f2: a2 $-> b2 g1: c1 $-> b1 g2: b2 $-> c2 h: uncurry Hom (a1, a2)
f2 $o (h $o (f1 $o g1)) $== f2 $o h $o (f1 $o g1)
refine (cat_assoc_opp _ _ _).Defined.
A: Type H: IsGraph A H0: Is01Cat A
Is0Bifunctor Hom
A: Type H: IsGraph A H0: Is01Cat A
Is0Bifunctor Hom
A: Type H: IsGraph A H0: Is01Cat A
Is01Cat A^op
A: Type H: IsGraph A H0: Is01Cat A
Is01Cat A
A: Type H: IsGraph A H0: Is01Cat A
Is0Functor (uncurry Hom)
A: Type H: IsGraph A H0: Is01Cat A
Is0Functor (uncurry Hom)
exact is0functor_hom.Defined.(** While it is possible to prove the bifunctor coherence condition from [Is1Cat_Strong], 1-functoriality requires morphism extensionality.*)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A IsGraph1: IsGraph A Is2Graph1: Is2Graph A Is01Cat1: Is01Cat A H0: Is1Cat A H1: HasMorExt A
Is1Bifunctor Hom
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A IsGraph1: IsGraph A Is2Graph1: Is2Graph A Is01Cat1: Is01Cat A H0: Is1Cat A H1: HasMorExt A
Is1Bifunctor Hom
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A IsGraph1: IsGraph A Is2Graph1: Is2Graph A Is01Cat1: Is01Cat A H0: Is1Cat A H1: HasMorExt A
Is1Functor (uncurry Hom)
exact is1functor_hom.Defined.Definitionfun01_hom {A} `{Is01Cat A}
: Fun01 (A^op * A) Type
:= @Build_Fun01 _ _ _ _ _ is0functor_hom.(** ** The covariant Yoneda lemma *)(** This is easier than the contravariant version because it doesn't involve any "op"s. *)Definitionopyon {A : Type} `{IsGraph A} (a : A) : A -> Type
:= funb => (a $-> b).(** We prove this explicitly instead of using the bifunctor instance above so that we can apply [fmap] in each argument independently without mapping an identity in the other. *)
A: Type H: IsGraph A H0: Is01Cat A a: A
Is0Functor (opyon a)
A: Type H: IsGraph A H0: Is01Cat A a: A
Is0Functor (opyon a)
A: Type H: IsGraph A H0: Is01Cat A a: A
foralla0b : A,
(a0 $-> b) -> opyon a a0 $-> opyon a b
A: Type H: IsGraph A H0: Is01Cat A a, b, c: A f: b $-> c g: a $-> b
a $-> c
exact (f $o g).Defined.
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A HasMorExt0: HasMorExt A a: A
Is1Functor (opyon a)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A HasMorExt0: HasMorExt A a: A
Is1Functor (opyon a)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A HasMorExt0: HasMorExt A a: A
forall (a0b : A) (fg : a0 $-> b),
f $== g -> fmap (opyon a) f $== fmap (opyon a) g
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A HasMorExt0: HasMorExt A a: A
foralla0 : A,
fmap (opyon a) (Id a0) $== Id (opyon a a0)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A HasMorExt0: HasMorExt A a: A
forall (a0bc : A) (f : a0 $-> b)
(g : b $-> c),
fmap (opyon a) (g $o f) $==
fmap (opyon a) g $o fmap (opyon a) f
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A HasMorExt0: HasMorExt A a: A
forall (a0b : A) (fg : a0 $-> b),
f $== g -> fmap (opyon a) f $== fmap (opyon a) g
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A HasMorExt0: HasMorExt A a, x, y: A f, g: x $-> y p: f $== g h: opyon a x
fmap (opyon a) f h = fmap (opyon a) g h
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A HasMorExt0: HasMorExt A a, x, y: A f, g: x $-> y p: f $== g h: opyon a x
fmap (opyon a) f h $== fmap (opyon a) g h
apply (cat_prewhisker p).
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A HasMorExt0: HasMorExt A a: A
foralla0 : A,
fmap (opyon a) (Id a0) $== Id (opyon a a0)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A HasMorExt0: HasMorExt A a, x: A h: opyon a x
fmap (opyon a) (Id x) h = Id (opyon a x) h
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A HasMorExt0: HasMorExt A a, x: A h: opyon a x
fmap (opyon a) (Id x) h $== Id (opyon a x) h
apply cat_idl.
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A HasMorExt0: HasMorExt A a: A
forall (a0bc : A) (f : a0 $-> b)
(g : b $-> c),
fmap (opyon a) (g $o f) $==
fmap (opyon a) g $o fmap (opyon a) f
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A HasMorExt0: HasMorExt A a, x, y, z: A f: x $-> y g: y $-> z h: opyon a x
fmap (opyon a) (g $o f) h =
(fmap (opyon a) g $o fmap (opyon a) f) h
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A HasMorExt0: HasMorExt A a, x, y, z: A f: x $-> y g: y $-> z h: opyon a x
fmap (opyon a) (g $o f) h $==
(fmap (opyon a) g $o fmap (opyon a) f) h
apply cat_assoc.Defined.(** We record these corollaries here, since we use some of them below. *)Definitionequiv_postcompose_cat_equiv {A : Type} `{HasEquivs A} `{!HasMorExt A}
{x y z : A} (f : y $<~> z)
: (x $-> y) <~> (x $-> z)
:= emap (opyon x) f.Definitionequiv_precompose_cat_equiv {A : Type} `{HasEquivs A} `{!HasMorExt A}
{x y z : A} (f : x $<~> y)
: (y $-> z) <~> (x $-> z)
:= @equiv_postcompose_cat_equiv A^op _ _ _ _ _ _ z y x f.(* The following implicitly use [hasequivs_core]. Note that when [A] has morphism extensionality, it doesn't follow that [core A] does. We'd need to know that being an equivalence is a proposition, and we don't assume that (since even for [Type] it requires [Funext], see [hasmorext_core_type]). So we need to assume this in the following results. *)(** Postcomposition with a cat_equiv is an equivalence between the types of equivalences. *)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A HasMorExt0: HasMorExt (core A) x, y, z: A f: y $<~> z
(x $<~> y) <~> (x $<~> z)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A HasMorExt0: HasMorExt (core A) x, y, z: A f: y $<~> z
(x $<~> y) <~> (x $<~> z)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A HasMorExt0: HasMorExt (core A) x, y, z: A f: y $<~> z
({| uncore := x |} $-> {| uncore := y |}) <~>
({| uncore := x |} $-> {| uncore := z |})
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A HasMorExt0: HasMorExt (core A) x, y, z: A f: y $<~> z
{| uncore := y |} $<~> {| uncore := z |}
exact f. (* It doesn't work to insert [f] on the previous line. *)Defined.
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A HasMorExt0: HasMorExt (core A) x, y, z: A f: x $<~> y
(y $<~> z) <~> (x $<~> z)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A HasMorExt0: HasMorExt (core A) x, y, z: A f: x $<~> y
(y $<~> z) <~> (x $<~> z)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A HasMorExt0: HasMorExt (core A) x, y, z: A f: x $<~> y
({| uncore := y |} $-> {| uncore := z |}) <~>
({| uncore := x |} $-> {| uncore := z |})
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A HasMorExt0: HasMorExt (core A) x, y, z: A f: x $<~> y
{| uncore := x |} $<~> {| uncore := y |}
exact f. (* It doesn't work to insert [f] on the previous line. *)Defined.
A: Type H: IsGraph A H0: Is01Cat A a: A F: A -> Type ff: Is0Functor F
F a -> opyon a $=> F
A: Type H: IsGraph A H0: Is01Cat A a: A F: A -> Type ff: Is0Functor F
F a -> opyon a $=> F
A: Type H: IsGraph A H0: Is01Cat A a: A F: A -> Type ff: Is0Functor F x: F a b: A f: opyon a b
F b
exact (fmap F f x).Defined.Definitionun_opyoneda {A : Type} `{Is01Cat A}
(a : A) (F : A -> Type) {ff : Is0Functor F}
: (opyon a $=> F) -> F a
:= funalpha => alpha a (Id a).
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A F: A -> Type Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F x: F a
Is1Natural (opyon a) F (opyoneda a F x)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A F: A -> Type Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F x: F a
Is1Natural (opyon a) F (opyoneda a F x)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A F: A -> Type Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F x: F a b, c: A f: b $-> c g: a $-> b
fmap F (f $o g) x = fmap F f (fmap F g x)
exact (fmap_comp F g f x).Defined.(** This is form of injectivity of [opyoneda]. *)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A F: A -> Type Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F x, x': F a p: forallb : A,
opyoneda a F x b == opyoneda a F x' b
x = x'
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A F: A -> Type Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F x, x': F a p: forallb : A,
opyoneda a F x b == opyoneda a F x' b
x = x'
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A F: A -> Type Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F x, x': F a p: forallb : A,
opyoneda a F x b == opyoneda a F x' b
fmap F (Id a) x = fmap F (Id a) x'
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A F: A -> Type Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F x, x': F a p: forallb : A,
opyoneda a F x b == opyoneda a F x' b
fmap F (Id a) x = fmap F (Id a) x'
exact (p a (Id a)).Defined.(** This says that [opyon] is faithful, although we haven't yet defined a graph structure on natural transformations to express this in that way. This follows from the previous result, but then would need [HasMorExt A], since the previous result assumes that [F] is a 1-functor, which is stronger than what is needed. The direct proof below only needs the weaker assumption [Is1Cat_Strong A]. *)Definitionopyon_faithful {A : Type} `{Is1Cat_Strong A}
(a b : A) (f g : b $-> a)
(p : forall (c : A) (h : a $-> c), h $o f = h $o g)
: f = g
:= (cat_idl_strong f)^ @ p a (Id a) @ cat_idl_strong g.(** The composite in one direction is the identity map. *)Definitionopyoneda_issect {A : Type} `{Is1Cat A} (a : A)
(F : A -> Type) `{!Is0Functor F, !Is1Functor F}
(x : F a)
: un_opyoneda a F (opyoneda a F x) = x
:= fmap_id F a x.(** We assume for the converse that the coherences in [A] are equalities (this is a weak funext-type assumption). Note that we do not in general recover the witness of 1-naturality. Indeed, if [A] is fully coherent, then a transformation of the form [opyoneda a F x] is always also fully coherently natural, so an incoherent witness of 1-naturality could not be recovered in this way. *)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat_Strong A a: A F: A -> Type Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F alpha: opyon a $=> F alnat: Is1Natural (opyon a) F alpha b: A
opyoneda a F (un_opyoneda a F alpha) b $== alpha b
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat_Strong A a: A F: A -> Type Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F alpha: opyon a $=> F alnat: Is1Natural (opyon a) F alpha b: A
opyoneda a F (un_opyoneda a F alpha) b $== alpha b
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat_Strong A a: A F: A -> Type Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F alpha: opyon a $=> F alnat: Is1Natural (opyon a) F alpha b: A f: a $-> b
fmap F f (alpha a (Id a)) = alpha b f
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat_Strong A a: A F: A -> Type Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F alpha: opyon a $=> F alnat: Is1Natural (opyon a) F alpha b: A f: a $-> b
(alpha b $o fmap (opyon a) f) (Id a) = alpha b f
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat_Strong A a: A F: A -> Type Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F alpha: opyon a $=> F alnat: Is1Natural (opyon a) F alpha b: A f: a $-> b
alpha b (f $o Id a) = alpha b f
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat_Strong A a: A F: A -> Type Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F alpha: opyon a $=> F alnat: Is1Natural (opyon a) F alpha b: A f: a $-> b
f $o Id a = f
exact (cat_idr_strong f).Defined.(** A natural transformation between representable functors induces a map between the representing objects. *)Definitionopyon_cancel {A : Type} `{Is01Cat A} (a b : A)
: (opyon a $=> opyon b) -> (b $-> a)
:= un_opyoneda a (opyon b).
A: Type H: IsGraph A H0: Is01Cat A a: A
Fun01 A Type
A: Type H: IsGraph A H0: Is01Cat A a: A
Fun01 A Type
rapply (Build_Fun01 _ _ (opyon a)).Defined.
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A HasMorExt0: HasMorExt A a: A
Fun11 A Type
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A HasMorExt0: HasMorExt A a: A
Fun11 A Type
rapply (Build_Fun11 _ _ (opyon a)).Defined.(** An equivalence between representable functors induces an equivalence between the representing objects. *)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A Is1Cat_Strong0: Is1Cat_Strong A a, b: A
opyon1 a $<~> opyon1 b -> b $<~> a
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A Is1Cat_Strong0: Is1Cat_Strong A a, b: A
opyon1 a $<~> opyon1 b -> b $<~> a
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A Is1Cat_Strong0: Is1Cat_Strong A a, b: A f: opyon1 a $<~> opyon1 b
b $<~> a
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A Is1Cat_Strong0: Is1Cat_Strong A a, b: A f: opyon1 a $<~> opyon1 b
f a (Id a) $o (f b)^-1 (Id b) = Id a
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A Is1Cat_Strong0: Is1Cat_Strong A a, b: A f: opyon1 a $<~> opyon1 b
(f b)^-1 (Id b) $o f a (Id a) = Id b
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A Is1Cat_Strong0: Is1Cat_Strong A a, b: A f: opyon1 a $<~> opyon1 b
f a (Id a) $o (f b)^-1 (Id b) = Id a
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A Is1Cat_Strong0: Is1Cat_Strong A a, b: A f: opyon1 a $<~> opyon1 b
(f a)^-1 (f a (Id a) $o Id b) = Id a
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A Is1Cat_Strong0: Is1Cat_Strong A a, b: A f: opyon1 a $<~> opyon1 b
(f a)^-1 (f a (Id a) $o Id b) = (f a)^-1 (f a (Id a))
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A Is1Cat_Strong0: Is1Cat_Strong A a, b: A f: opyon1 a $<~> opyon1 b
f a (Id a) $o Id b = f a (Id a)
srapply cat_idr_strong.
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A Is1Cat_Strong0: Is1Cat_Strong A a, b: A f: opyon1 a $<~> opyon1 b
(f b)^-1 (Id b) $o f a (Id a) = Id b
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A Is1Cat_Strong0: Is1Cat_Strong A a, b: A f: opyon1 a $<~> opyon1 b
f b ((f b)^-1 (Id b) $o Id a) = Id b
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A Is1Cat_Strong0: Is1Cat_Strong A a, b: A f: opyon1 a $<~> opyon1 b
f b ((f b)^-1 (Id b) $o Id a) = f b ((f b)^-1 (Id b))
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A Is1Cat_Strong0: Is1Cat_Strong A a, b: A f: opyon1 a $<~> opyon1 b
(f b)^-1 (Id b) $o Id a = (f b)^-1 (Id b)
srapply cat_idr_strong.Defined.
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A HasMorExt0: HasMorExt A a, b: A
b $<~> a -> opyon1 a $<~> opyon1 b
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A HasMorExt0: HasMorExt A a, b: A
b $<~> a -> opyon1 a $<~> opyon1 b
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A HasMorExt0: HasMorExt A a, b: A e: b $<~> a
opyon1 a $<~> opyon1 b
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A HasMorExt0: HasMorExt A a, b: A e: b $<~> a
foralla0 : A, opyon a a0 $<~> opyon b a0
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A HasMorExt0: HasMorExt A a, b: A e: b $<~> a
Is1Natural (opyon a) (opyon b) (funa0 : A => ?e a0)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A HasMorExt0: HasMorExt A a, b: A e: b $<~> a
foralla0 : A, opyon a a0 $<~> opyon b a0
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A HasMorExt0: HasMorExt A a, b: A e: b $<~> a c: A
opyon a c $<~> opyon b c
exact (equiv_precompose_cat_equiv e).
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A HasMorExt0: HasMorExt A a, b: A e: b $<~> a
Is1Natural (opyon a) (opyon b)
(funa0 : A =>
(func : A => equiv_precompose_cat_equiv e) a0)
rapply is1natural_opyoneda.Defined.(** ** The covariant Yoneda lemma using 0-groupoids *)(** We repeat the above, regarding [opyon] as landing in 0-groupoids, using the 1-category structure on [ZeroGpd] in [ZeroGroupoid.v]. This has many advantages. It avoids [HasMorExt], which means that we don't need [Funext] in many examples. It also avoids [Is1Cat_Strong], which means the results all have the same hypotheses, namely that [A] is a 1-category. This allows us to simplify the proof of [opyon_equiv_0gpd], making use of [opyoneda_isretr_0gpd]. *)Definitionopyon_0gpd {A : Type} `{Is1Cat A} (a : A) : A -> ZeroGpd
:= funb => Build_ZeroGpd (a $-> b) _ _ _.
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A
Is0Functor (uncurry opyon_0gpd)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A
Is0Functor (uncurry opyon_0gpd)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A
forallab : A^op * A,
(a $-> b) ->
uncurry opyon_0gpd a $-> uncurry opyon_0gpd b
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a1, a2, b1, b2: A f1: b1 $-> a1 f2: a2 $-> b2
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A
Is0Bifunctor opyon_0gpd
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A
Is0Bifunctor opyon_0gpd
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A
Is01Cat A^op
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A
Is01Cat A
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A
Is0Functor (uncurry opyon_0gpd)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A
Is0Functor (uncurry opyon_0gpd)
exact is0functor_hom_0gpd.Defined.
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A
Is1Bifunctor opyon_0gpd
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A
Is1Bifunctor opyon_0gpd
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A
Is1Functor (uncurry opyon_0gpd)
exact is1functor_hom_0gpd.Defined.
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A
Is0Functor (opyon_0gpd a)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A
Is0Functor (opyon_0gpd a)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A
foralla0b : A,
(a0 $-> b) -> opyon_0gpd a a0 $-> opyon_0gpd a b
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a, b, c: A f: b $-> c
opyon_0gpd a b $-> opyon_0gpd a c
exact (Build_Morphism_0Gpd (opyon_0gpd a b) (opyon_0gpd a c) (cat_postcomp a f) _).Defined.
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A
Is1Functor (opyon_0gpd a)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A
Is1Functor (opyon_0gpd a)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A
forall (a0b : A) (fg : a0 $-> b),
f $== g ->
fmap (opyon_0gpd a) f $== fmap (opyon_0gpd a) g
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A
foralla0 : A,
fmap (opyon_0gpd a) (Id a0) $== Id (opyon_0gpd a a0)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A
forall (a0bc : A) (f : a0 $-> b)
(g : b $-> c),
fmap (opyon_0gpd a) (g $o f) $==
fmap (opyon_0gpd a) g $o fmap (opyon_0gpd a) f
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A
forall (a0b : A) (fg : a0 $-> b),
f $== g ->
fmap (opyon_0gpd a) f $== fmap (opyon_0gpd a) g
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a, x, y: A f, g: x $-> y p: f $== g h: opyon_0gpd a x
fmap (opyon_0gpd a) f h $== fmap (opyon_0gpd a) g h
apply (cat_prewhisker p).
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A
foralla0 : A,
fmap (opyon_0gpd a) (Id a0) $== Id (opyon_0gpd a a0)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a, x: A h: opyon_0gpd a x
fmap (opyon_0gpd a) (Id x) h $== Id (opyon_0gpd a x) h
apply cat_idl.
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A
forall (a0bc : A) (f : a0 $-> b)
(g : b $-> c),
fmap (opyon_0gpd a) (g $o f) $==
fmap (opyon_0gpd a) g $o fmap (opyon_0gpd a) f
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a, x, y, z: A f: x $-> y g: y $-> z h: opyon_0gpd a x
fmap (opyon_0gpd a) (g $o f) h $==
(fmap (opyon_0gpd a) g $o fmap (opyon_0gpd a) f) h
apply cat_assoc.Defined.
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A F: A -> ZeroGpd Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F
F a -> opyon_0gpd a $=> F
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A F: A -> ZeroGpd Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F
F a -> opyon_0gpd a $=> F
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A F: A -> ZeroGpd Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F x: F a b: A
opyon_0gpd a b $-> F b
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A F: A -> ZeroGpd Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F x: F a b: A
Is0Functor (funf : opyon_0gpd a b => fmap F f x)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A F: A -> ZeroGpd Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F x: F a b: A
foralla0b0 : opyon_0gpd a b,
(a0 $-> b0) -> fmap F a0 x $-> fmap F b0 x
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A F: A -> ZeroGpd Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F x: F a b: A f1, f2: opyon_0gpd a b h: f1 $-> f2
fmap F f1 x $-> fmap F f2 x
exact (fmap2 F h x).Defined.Definitionun_opyoneda_0gpd {A : Type} `{Is1Cat A}
(a : A) (F : A -> ZeroGpd) {ff : Is0Functor F}
: (opyon_0gpd a $=> F) -> F a
:= funalpha => alpha a (Id a).
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A F: A -> ZeroGpd Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F x: F a
Is1Natural (opyon_0gpd a) F (opyoneda_0gpd a F x)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A F: A -> ZeroGpd Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F x: F a
Is1Natural (opyon_0gpd a) F (opyoneda_0gpd a F x)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A F: A -> ZeroGpd Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F x: F a b, c: A f: b $-> c g: a $-> b
fmap F (cat_postcomp a f g) x $==
fmap F f (fmap F g x)
exact (fmap_comp F g f x).Defined.(** This is form of injectivity of [opyoneda_0gpd]. *)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A F: A -> ZeroGpd Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F x, x': F a p: forallb : A,
opyoneda_0gpd a F x b $== opyoneda_0gpd a F x' b
x $== x'
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A F: A -> ZeroGpd Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F x, x': F a p: forallb : A,
opyoneda_0gpd a F x b $== opyoneda_0gpd a F x' b
x $== x'
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A F: A -> ZeroGpd Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F x, x': F a p: forallb : A,
opyoneda_0gpd a F x b $== opyoneda_0gpd a F x' b
fmap F (Id a) x $== fmap F (Id a) x'
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A F: A -> ZeroGpd Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F x, x': F a p: forall (b : A) (x0 : a $-> b),
fmap F x0 x $== fmap F x0 x'
fmap F (Id a) x $== fmap F (Id a) x'
exact (p a (Id a)).Defined.(** This says that [opyon_0gpd] is faithful, although we haven't yet defined a graph structure on natural transformations to express this in that way. *)Definitionopyon_faithful_0gpd {A : Type} `{Is1Cat A} (a b : A)
(f g : b $-> a) (p : forall (c : A) (h : a $-> c), h $o f $== h $o g)
: f $== g
:= opyoneda_isinj_0gpd a _ f g p.(** The composite in one direction is the identity map. *)Definitionopyoneda_issect_0gpd {A : Type} `{Is1Cat A} (a : A)
(F : A -> ZeroGpd) `{!Is0Functor F, !Is1Functor F}
(x : F a)
: un_opyoneda_0gpd a F (opyoneda_0gpd a F x) $== x
:= fmap_id F a x.(** For the other composite, note that we do not in general recover the witness of 1-naturality. Indeed, if [A] is fully coherent, then a transformation of the form [opyoneda a F x] is always also fully coherently natural, so an incoherent witness of 1-naturality could not be recovered in this way. *)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A F: A -> ZeroGpd Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F alpha: opyon_0gpd a $=> F alnat: Is1Natural (opyon_0gpd a) F alpha b: A
opyoneda_0gpd a F (un_opyoneda_0gpd a F alpha) b $==
alpha b
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A F: A -> ZeroGpd Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F alpha: opyon_0gpd a $=> F alnat: Is1Natural (opyon_0gpd a) F alpha b: A
opyoneda_0gpd a F (un_opyoneda_0gpd a F alpha) b $==
alpha b
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A F: A -> ZeroGpd Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F alpha: opyon_0gpd a $=> F alnat: Is1Natural (opyon_0gpd a) F alpha b: A f: opyon_0gpd a b
opyoneda_0gpd a F (un_opyoneda_0gpd a F alpha) b f $==
alpha b f
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A F: A -> ZeroGpd Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F alpha: opyon_0gpd a $=> F alnat: Is1Natural (opyon_0gpd a) F alpha b: A f: opyon_0gpd a b
(alpha b $o fmap (opyon_0gpd a) f) (Id a) $==
alpha b f
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A F: A -> ZeroGpd Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F alpha: opyon_0gpd a $=> F alnat: Is1Natural (opyon_0gpd a) F alpha b: A f: opyon_0gpd a b
alpha b (cat_postcomp a f (Id a)) $== alpha b f
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A a: A F: A -> ZeroGpd Is0Functor0: Is0Functor F Is1Functor0: Is1Functor F alpha: opyon_0gpd a $=> F alnat: Is1Natural (opyon_0gpd a) F alpha b: A f: opyon_0gpd a b
cat_postcomp a f (Id a) $-> f
exact (cat_idr f).Defined.(** A natural transformation between representable functors induces a map between the representing objects. *)Definitionopyon_cancel_0gpd {A : Type} `{Is1Cat A} (a b : A)
: (opyon_0gpd a $=> opyon_0gpd b) -> (b $-> a)
:= un_opyoneda_0gpd a (opyon_0gpd b).(** Since no extra hypotheses are needed, we use the name with "1" for the [Fun11] version. *)Definitionopyon1_0gpd {A : Type} `{Is1Cat A} (a : A) : Fun11 A ZeroGpd
:= Build_Fun11 _ _ (opyon_0gpd a).(** An equivalence between representable functors induces an equivalence between the representing objects. We explain how this compares to [opyon_equiv] above. Instead of assuming that each [f c : (a $-> c) -> (b $-> c)] is an equivalence of types, it only needs to be an equivalence of 0-groupoids. For example, this means that we have a map [g c : (b $-> c) -> (a $-> c)] such that for each [k : a $-> c], [g c (f c k) $== k], rather than [g c (f c k) = k] as the version with types requires. Similarly, the naturality is up to 2-cells, instead of up to paths. This allows us to avoid [Funext] and [HasMorExt] when using this result. As a side benefit, we also don't require that [A] is strong. The proof is also simpler, since we can re-use the work done in [opyoneda_isretr_0gpd]. *)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A a, b: A f: opyon1_0gpd a $<~> opyon1_0gpd b
b $<~> a
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A a, b: A f: opyon1_0gpd a $<~> opyon1_0gpd b
b $<~> a
(* These are the maps that will define the desired equivalence: *)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A a, b: A f: opyon1_0gpd a $<~> opyon1_0gpd b fa:= f a (Id a): opyon1_0gpd b a
b $<~> a
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A a, b: A f: opyon1_0gpd a $<~> opyon1_0gpd b fa:= f a (Id a): opyon1_0gpd b a gb:= f^-1$ b (Id b): opyon1_0gpd a b
b $<~> a
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A a, b: A f: opyon1_0gpd a $<~> opyon1_0gpd b fa:= f a (Id a): opyon1_0gpd b a gb:= f^-1$ b (Id b): opyon1_0gpd a b
fa $o gb $== Id a
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A a, b: A f: opyon1_0gpd a $<~> opyon1_0gpd b fa:= f a (Id a): opyon1_0gpd b a gb:= f^-1$ b (Id b): opyon1_0gpd a b
gb $o fa $== Id b
(* [opyoneda_0gpd] is defined by postcomposition, so [opyoneda_isretr_0gpd] simplifies both LHSs.*)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A a, b: A f: opyon1_0gpd a $<~> opyon1_0gpd b fa:= f a (Id a): opyon1_0gpd b a gb:= f^-1$ b (Id b): opyon1_0gpd a b
fa $o gb $== Id a
exact (opyoneda_isretr_0gpd _ _ f^-1$ a fa $@ cat_eissect (f a) (Id a)).
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A a, b: A f: opyon1_0gpd a $<~> opyon1_0gpd b fa:= f a (Id a): opyon1_0gpd b a gb:= f^-1$ b (Id b): opyon1_0gpd a b
gb $o fa $== Id b
exact (opyoneda_isretr_0gpd _ _ f b gb $@ cat_eisretr (f b) (Id b)).Defined.(** Since [opyon_0gpd] is a 1-functor, postcomposition with a [cat_equiv] is an equivalence between the hom 0-groupoids. Note that we do not require [HasMorExt], as [equiv_postcompose_cat_equiv] does. *)Definitionequiv_postcompose_cat_equiv_0gpd {A : Type} `{HasEquivs A}
{x y z : A} (f : y $<~> z)
: opyon_0gpd x y $<~> opyon_0gpd x z
:= emap (opyon_0gpd x) f.(** The dual result, which is used in the next result. *)Definitionequiv_precompose_cat_equiv_0gpd {A : Type} `{HasEquivs A}
{x y z : A} (f : x $<~> y)
: opyon_0gpd y z $<~> opyon_0gpd x z
:= @equiv_postcompose_cat_equiv_0gpd A^op _ _ _ _ _ z y x f.(** A converse to [opyon_equiv_0gpd]. Together, we get a logical equivalence between [b $<~> a] and [opyon_0gpd a $<~> opyon_0gpd b], without [HasMorExt]. *)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A a, b: A e: b $<~> a
opyon1_0gpd a $<~> opyon1_0gpd b
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A a, b: A e: b $<~> a
opyon1_0gpd a $<~> opyon1_0gpd b
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A a, b: A e: b $<~> a
foralla0 : A, opyon1_0gpd a a0 $<~> opyon1_0gpd b a0
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A a, b: A e: b $<~> a
Is1Natural (opyon1_0gpd a)
(opyon1_0gpd b) (funa0 : A => ?e a0)
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A a, b: A e: b $<~> a
foralla0 : A, opyon1_0gpd a a0 $<~> opyon1_0gpd b a0
A: Type IsGraph0: IsGraph A Is2Graph0: Is2Graph A Is01Cat0: Is01Cat A H: Is1Cat A H0: HasEquivs A a, b: A e: b $<~> a
Is1Natural (opyon1_0gpd a)
(opyon1_0gpd b)
(funa0 : A =>
(func : A => equiv_precompose_cat_equiv_0gpd e) a0)
rapply is1natural_opyoneda_0gpd.Defined.(** ** The contravariant Yoneda lemma *)(** We can deduce this from the covariant version with some boilerplate. *)Definitionyon {A : Type} `{IsGraph A} (a : A) : A^op -> Type
:= opyon (A:=A^op) a.Global Instanceis0functor_yon {A : Type} `{H : Is01Cat A} (a : A)
: Is0Functor (yon a)
:= is0functor_opyon (A:=A^op) a.Global Instanceis1functor_yon {A : Type} `{H : Is1Cat A} `{!HasMorExt A} (a : A)
: Is1Functor (yon a)
:= is1functor_opyon (A:=A^op) a.Definitionyoneda {A : Type} `{Is01Cat A} (a : A)
(F : A^op -> Type) `{!Is0Functor F}
: F a -> (yon a $=> F)
:= @opyoneda (A^op) _ _ a F _.Definitionun_yoneda {A : Type} `{Is01Cat A} (a : A)
(F : A^op -> Type) `{!Is0Functor F}
: (yon a $=> F) -> F a
:= un_opyoneda (A:=A^op) a F.Global Instanceis1natural_yoneda {A : Type} `{Is1Cat A} (a : A)
(F : A^op -> Type) `{!Is0Functor F, !Is1Functor F} (x : F a)
: Is1Natural (yon a) F (yoneda a F x)
:= is1natural_opyoneda (A:=A^op) a F x.Definitionyoneda_isinj {A : Type} `{Is1Cat A} (a : A)
(F : A^op -> Type) `{!Is0Functor F, !Is1Functor F}
(x x' : F a) (p : forallb, yoneda a F x b == yoneda a F x' b)
: x = x'
:= opyoneda_isinj (A:=A^op) a F x x' p.Definitionyon_faithful {A : Type} `{Is1Cat_Strong A}
(a b : A) (f g : b $-> a)
(p : forall (c : A) (h : c $-> b), f $o h = g $o h)
: f = g
:= opyon_faithful (A:=A^op) b a f g p.Definitionyoneda_issect {A : Type} `{Is1Cat A} (a : A)
(F : A^op -> Type) `{!Is0Functor F, !Is1Functor F} (x : F a)
: un_yoneda a F (yoneda a F x) = x
:= opyoneda_issect (A:=A^op) a F x.Definitionyoneda_isretr {A : Type} `{Is1Cat_Strong A} (a : A)
(F : A^op -> Type) `{!Is0Functor F}
(* Without the hint here, Coq guesses to first project from [Is1Cat_Strong A] and then pass to opposites, whereas what we need is to first pass to opposites and then project. *)
`{@Is1Functor _ _ _ _ _ (is1cat_is1cat_strong A^op) _ _ _ _ F _}
(alpha : yon a $=> F) {alnat : Is1Natural (yon a) F alpha}
(b : A)
: yoneda a F (un_yoneda a F alpha) b $== alpha b
:= opyoneda_isretr (A:=A^op) a F alpha b.Definitionyon_cancel {A : Type} `{Is01Cat A} (a b : A)
: (yon a $=> yon b) -> (a $-> b)
:= un_yoneda a (yon b).Definitionyon1 {A : Type} `{Is01Cat A} (a : A) : Fun01 A^op Type
:= opyon1 (A:=A^op) a.Definitionyon11 {A : Type} `{Is1Cat A} `{!HasMorExt A} (a : A) : Fun11 A^op Type
:= opyon11 (A:=A^op) a.Definitionyon_equiv {A : Type} `{HasEquivs A} `{!Is1Cat_Strong A}
(a b : A)
: (yon1 a $<~> yon1 b) -> (a $<~> b)
:= opyon_equiv (A:=A^op).Definitionnatequiv_yon_equiv {A : Type} `{HasEquivs A}
`{!HasMorExt A} (a b : A)
: (a $<~> b) -> (yon1 a $<~> yon1 b)
:= natequiv_opyon_equiv (A:=A^op).(** ** The contravariant Yoneda lemma using 0-groupoids *)Definitionyon_0gpd {A : Type} `{Is1Cat A} (a : A) : A^op -> ZeroGpd
:= opyon_0gpd (A:=A^op) a.Global Instanceis0functor_yon_0gpd {A : Type} `{Is1Cat A} (a : A)
: Is0Functor (yon_0gpd a)
:= is0functor_opyon_0gpd (A:=A^op) a.Global Instanceis1functor_yon_0gpd {A : Type} `{Is1Cat A} (a : A)
: Is1Functor (yon_0gpd a)
:= is1functor_opyon_0gpd (A:=A^op) a.Definitionyoneda_0gpd {A : Type} `{Is1Cat A} (a : A)
(F : A^op -> ZeroGpd) `{!Is0Functor F, !Is1Functor F}
: F a -> (yon_0gpd a $=> F)
:= opyoneda_0gpd (A:=A^op) a F.Definitionun_yoneda_0gpd {A : Type} `{Is1Cat A}
(a : A) (F : A^op -> ZeroGpd) {ff : Is0Functor F}
: (yon_0gpd a $=> F) -> F a
:= un_opyoneda_0gpd (A:=A^op) a F.Global Instanceis1natural_yoneda_0gpd {A : Type} `{Is1Cat A}
(a : A) (F : A^op -> ZeroGpd) `{!Is0Functor F, !Is1Functor F} (x : F a)
: Is1Natural (yon_0gpd a) F (yoneda_0gpd a F x)
:= is1natural_opyoneda_0gpd (A:=A^op) a F x.Definitionyoneda_isinj_0gpd {A : Type} `{Is1Cat A} (a : A)
(F : A^op -> ZeroGpd) `{!Is0Functor F, !Is1Functor F}
(x x' : F a) (p : forallb : A, yoneda_0gpd a F x b $== yoneda_0gpd a F x' b)
: x $== x'
:= opyoneda_isinj_0gpd (A:=A^op) a F x x' p.Definitionyon_faithful_0gpd {A : Type} `{Is1Cat A} (a b : A)
(f g : b $-> a) (p : forall (c : A) (h : c $-> b), f $o h $== g $o h)
: f $== g
:= opyon_faithful_0gpd (A:=A^op) b a f g p.Definitionyoneda_issect_0gpd {A : Type} `{Is1Cat A} (a : A)
(F : A^op -> ZeroGpd) `{!Is0Functor F, !Is1Functor F}
(x : F a)
: un_yoneda_0gpd a F (yoneda_0gpd a F x) $== x
:= opyoneda_issect_0gpd (A:=A^op) a F x.Definitionyoneda_isretr_0gpd {A : Type} `{Is1Cat A} (a : A)
(F : A^op -> ZeroGpd) `{!Is0Functor F, !Is1Functor F}
(alpha : yon_0gpd a $=> F) {alnat : Is1Natural (yon_0gpd a) F alpha}
(b : A)
: yoneda_0gpd a F (un_yoneda_0gpd a F alpha) b $== alpha b
:= opyoneda_isretr_0gpd (A:=A^op) a F alpha b.Definitionyon_cancel_0gpd {A : Type} `{Is1Cat A} (a b : A)
: (yon_0gpd a $=> yon_0gpd b) -> (a $-> b)
:= opyon_cancel_0gpd (A:=A^op) a b.Definitionyon1_0gpd {A : Type} `{Is1Cat A} (a : A) : Fun11 A^op ZeroGpd
:= opyon1_0gpd (A:=A^op) a.Definitionyon_equiv_0gpd {A : Type} `{HasEquivs A}
{a b : A} (f : yon1_0gpd a $<~> yon1_0gpd b)
: a $<~> b
:= opyon_equiv_0gpd (A:=A^op) f.Definitionnatequiv_yon_equiv_0gpd {A : Type} `{HasEquivs A}
{a b : A} (e : a $<~> b)
: yon1_0gpd (A:=A) a $<~> yon1_0gpd b
:= natequiv_opyon_equiv_0gpd (A:=A^op) (e : CatEquiv (A:=A^op) b a).