\import Category \import Category.Adjoint \import Category.Functor \import Category.Limit \import Equiv \import Function.Meta \import Homotopy.Fibration \import Meta \import Paths \import Paths.Meta \func subPrecat {C : Precat} {X : \hType obj} (f : X -> C) : Precat X \cowith | Hom x y => Hom (f x) (f y) | id x => id (f x) | o h g => o h g | id-left => id-left | id-right => id-right | o-assoc => o-assoc \where { \func embedding {C : Precat} {X : \hType obj} (f : X -> C) : FullyFaithfulFunctor (subPrecat f) C f \cowith | Func h => h | Func-id => idp | Func-o => idp | isFullyFaithful => idEquiv \func pred {C : Precat} (P : C -> \Prop) => subPrecat (Total.proj P) \where \func embedding {C : Precat} (P : C -> \Prop) => subPrecat.embedding (Total.proj P) \func funcLift {C D : Precat} {X : \hType} (f : X -> D) (g : C -> X) (G : Functor C D) (p : \Pi {a : C} -> Iso {D} {f (g a)} {G a}) : Functor C (subPrecat f) g \cowith | Func h => p.hinv ∘ G.Func h ∘ p.f | Func-id => rewrite (G.Func-id, id-right) p.hinv_f | Func-o => rewrite G.Func-o $ later (rewrite (p.f_hinv, id-left) $ pmap (`∘ _) (inv o-assoc) *> o-assoc) *> pmap (_ ∘) (pmap (`∘ _) o-assoc *> o-assoc) *> inv o-assoc } \func subCat {C : Cat} {X : \hType obj} (e : Embedding {X} {C}) : Cat \cowith | Precat => subPrecat e | univalence => Cat.makeUnivalence $ later \lam (j : Iso) => \have (t,r) => Cat.univalenceToTransport (\new Iso j.f j.hinv j.hinv_f j.f_hinv) \in (sec {e.isEmb j.dom j.cod} t, pmap (transport (Hom (e j.dom)) __ (id (e j.dom))) (f_sec {e.isEmb j.dom j.cod} t) *> r) \class ReflectiveSubPrecat \extends FullyFaithfulFunctor, RightAdjoint { | reflector : D -> C | reflectorMap (X : D) : Hom X (F (reflector X)) \field isReflective {X : D} {Y : C} : Equiv {Hom (reflector X) Y} {Hom X (F Y)} (Func __ ∘ reflectorMap X) | LAdj { | F => reflector | Func {X} {Y} h => isReflective.ret (reflectorMap Y ∘ h) | Func-id => rewrite id-right (unfold (rewrite (Func-id, id-left) idp) *> isReflective.ret_f (id _)) | Func-o => run { isReflective.isInj, unfold, rewrite (isReflective.f_ret, Func-o, o-assoc, isReflective.f_ret), rewriteI {2} o-assoc, rewrite isReflective.f_ret, inv o-assoc } } | eta { | trans => reflectorMap | natural h => inv (isReflective.f_ret _) } | isAdjoint => isReflective } \where { \func fromRightAdjoint (F : RightAdjoint) {ff : FullyFaithfulFunctor { | Functor => F }} : ReflectiveSubPrecat \cowith | FullyFaithfulFunctor => ff | reflector => F.LAdj | reflectorMap => F.eta | isReflective => isAdjoint } \func reflectiveSubPrecatColimit {J : Precat} (I : ReflectiveSubPrecat) (F : Functor J I.C) (c : Colimit (Comp I F)) : Limit F.op \cowith | apex => I.reflector c.apex | coneMap j => I.inverse (reflectorMap _ ∘ c.coneMap j) | coneCoh h => I.isFaithful $ run { rewrite I.Func-o, repeat {2} (rewrite I.inverse-right), rewrite o-assoc, pmap (_ ∘) (c.coneCoh h) } | limMap {z} c' => I.isReflective.ret (c.limMap (Cone.map I.op {J.op} c')) | limBeta c' j => I.isFullyFaithful.isInj $ Func-o *> pmap (_ ∘) I.inverse-right *> inv o-assoc *> pmap (`∘ _) (I.isReflective.f_ret _) *> c.limBeta (Cone.map I.op {J.op} c') j | limUnique {z} {f} {g} p => inv (I.isReflective.ret_f f) *> pmap I.isReflective.ret (c.limUnique \lam j => o-assoc *> (rewrite I.inverse-right in inv I.Func-o *> pmap I.Func (p j) *> I.Func-o) *> inv o-assoc) *> I.isReflective.ret_f g