\import Category
\import Category.Adjoint
\import Category.Functor
\import Category.Limit
\import Equiv
\import Function.Meta
\import Homotopy.Fibration
\import Logic
\import Meta
\import Paths
\import Paths.Meta
\func subPrecat {C : Precat} {X : \Type} (f : X -> C) : Precat X \cowith
| Hom x y => Hom (f x) (f y)
| id => id
| o h g => o h g
| id-left => id-left
| id-right => id-right
| o-assoc => o-assoc
\where {
\func embedding {C : Precat} {X : \Type} (f : X -> C) : FullyFaithfulFunctor (subPrecat f) C f \cowith
| Func h => h
| Func-id => idp
| Func-o => idp
| isFullyFaithful => inP 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 : \Type} (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 : \Type} (e : Embedding {X} {C}) : Cat \cowith
| Precat => subPrecat e
| univalence => faithful-univalence (subPrecat.embedding e) e
\where {
\lemma faithful-univalence {C : Precat} {D : Cat} (F : FaithfulFunctor C D) (e : Embedding F) {a b : C} : IsEquiv (C.idtoiso {a} {b})
=> Cat.makeUnivalence \lam j =>
\have (t,r) => Cat.univalenceToTransport (F.Func-iso j)
\in ((e.isEmb j.dom j.cod).sec t, F.isFaithful $ inv id-right *> inv (Functor.transport_Hom-right _ F) *> pmap (transport (Hom (e j.dom)) __ _) ((e.isEmb j.dom j.cod).f_sec t) *> r)
\lemma faithful-reflects-iso {C : Precat} {D : Cat} (F : FaithfulFunctor C D) (e : Embedding F) {a b : C} {f : Hom a b} (fi : Iso (F.Func f)) : Iso f
=> \let | coh => Jl (\lam b p => F.Func (C.=_hom p) = D.=_hom (pmap e p)) F.Func-id
| p => (e.isEmb a b).sec (D.isotoid fi)
\in transport (Iso __) (F.isFaithful $ coh p *> pmap D.=_hom ((e.isEmb a b).f_sec (D.isotoid fi)) *> D.idtoiso_isotoid) (C.idtoiso p)
}
\lemma subCat-iso {C : Precat} {X : \Type} {f : X -> C} (e : Iso {subPrecat f}) : Iso {C} {f e.dom} {f e.cod} e \cowith
| hinv => e.hinv
| hinv_f => e.hinv_f
| f_hinv => e.f_hinv
\where {
\protected \lemma conv {C : Precat} {X : \Type} {f : X -> C} {x x' : X} (e : Iso {C} {f x} {f x'}) : Iso {subPrecat f} {x} {x'} e \cowith
| hinv => e.hinv
| hinv_f => e.hinv_f
| f_hinv => e.f_hinv
}
\class ReflectiveSubPrecat \extends FullyFaithfulFunctor {
| reflector : D -> C
| reflectorMap (X : D) : Hom X (F (reflector X))
\field isReflective {X : D} {Y : C} : QEquiv {Hom (reflector X) Y} {Hom X (F Y)} (Func __ ∘ reflectorMap X)
\func toAdjunction : Adjunction.FromReflector D C \this \cowith
| LOb => reflector
| etaMap => reflectorMap _
| eta-adjoint => inP isReflective
} \where {
\func fromAdjunction (A : Adjunction) {ff : \Pi {X Y : A.D} -> IsEquiv (RAdj.Func {X} {Y})} : ReflectiveSubPrecat \cowith
| Functor => A.RAdj
| isFullyFaithful => ff
| reflector => A.LAdj
| reflectorMap => A.eta
| isReflective => A.eta_epsilon-equiv
}
\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 => IsEquiv.isInj I.isFullyFaithful $ 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