\import Category
\import Category.Adjoint
\import Category.Comma
\import Category.Functor
\import Category.Limit
\import Equiv
\import Function.Meta
\import HLevel
\import Logic
\import Meta
\import Paths
\import Paths.Meta
\class RightAdjointCounit \extends Functor {
| LAdj : Functor D C
| epsilon : NatTrans (Comp LAdj \this) Id
\field isAdjoint-inv {X : D} {Y : C} : Equiv {Hom X (F Y)} {Hom (LAdj X) Y} (epsilon Y ∘ LAdj.Func __)
\func eta : NatTrans Id (Comp \this LAdj) \cowith
| trans X => isAdjoint-inv.ret (id (LAdj X))
| natural {_} {_} _ => isAdjoint-inv.isInj $ unfold $ rewrite (Func-o {LAdj}, Func-o {LAdj}) $
rewriteI (o-assoc, o-assoc) $
rewrite (isAdjoint-inv.f_ret, id-left, epsilon.natural) $
rewrite (o-assoc, isAdjoint-inv.f_ret, id-right) idp
\func adjoint-eta {X : D} {Y : C} (g : Hom (LAdj X) Y) : isAdjoint-inv.ret g = Func g ∘ eta X =>
isAdjoint-inv.isInj $ unfold $ rewrite (isAdjoint-inv.f_ret _, Func-o {LAdj}) $
rewriteI o-assoc $ rewrite (epsilon.natural, o-assoc, isAdjoint-inv.f_ret _, id-right) idp
} \where {
\use \coerce fromAdjoint (F : RightAdjoint) : RightAdjointCounit \cowith
| Functor => F
| LAdj => F.LAdj
| epsilon => F.epsilon
| isAdjoint-inv => \new Equiv {
| ret => F.isAdjoint
| ret_f => F.eta_eps_equiv.f_sec
| sec => F.isAdjoint
| f_sec => F.eta_eps_equiv.ret_f
}
\use \coerce toAdjoint (F : RightAdjointCounit) : RightAdjoint => \new RightAdjoint {
| Functor => F
| LAdj => LAdj
| eta => eta
| isAdjoint => \new QEquiv {
| ret => isAdjoint-inv
| ret_f _ => unfold $ rewriteI (adjoint-eta _ ) $ isAdjoint-inv.f_ret _
| f_sec _ => isAdjoint-inv.isInj $ unfold $ run {
rewrite (Func-o {LAdj}),
rewriteI o-assoc,
rewrite (epsilon.natural, o-assoc, isAdjoint-inv.f_ret _, id-right) idp
}
}
}
}
\func comma-precat {C D : Precat} (L : Functor D C) (b : C) => commaPrecat {D} {TrivialCat} {C} L (Const b)
\func comma-cat {C : Precat} {D : Cat} (L : Functor D C) (b : C) => commaCat {D} {TrivialCat} {C} L (Const b)
\class Coreflection {C D : Precat} (L : Functor D C) (B : C) {
| \classifying Coreflected : D
| corefl-map : Hom (L Coreflected) B
\property isCoreflection {Z : D} : Equiv {Hom Z Coreflected} {Hom (L Z) B} (\lam x => corefl-map ∘ (L.Func x))
\func to-comma : comma-precat L B => (Coreflected, (), corefl-map)
\func coreflection-map (x : comma-precat L B) : Hom {comma-precat L B} x to-comma
| (x, s, d) => (Equiv.ret {isCoreflection} d, id {TrivialCat} s, rewrite id-left $ Equiv.f_ret {isCoreflection} d)
\func to-comma-terminal : terminal-obj (comma-precat L B) => terminal-ind {comma-precat L B} to-comma
(\lam (p, s, q) => Contr.make (coreflection-map (p, s, q))
(\lam a => exts (inv $ Equiv.adjoint $ a.3 *> id-left, cases a.2 \with {
| Graph.empty p1 => idp
| Graph.cons e x => absurd e
}))
)
}
\where {
\func from-comma-terminal {C D : Precat} {L : Functor D C} {b : C} (terminal : terminal-obj (comma-precat L b))
: Coreflection L b => \new Coreflection {
| Coreflected => terminal.apex.1
| corefl-map => terminal.apex.3
| isCoreflection {z} => \new QEquiv {
| ret g => (terminalMap' {comma-precat L b} {terminal} {z, (), g}).1
| f_sec y => (terminalMap' {comma-precat L b} {terminal} {z, (), y}).3 *> id-left
| ret_f x =>
\let x-comma : comma-precat L b => (z, (), terminal.apex.3 ∘ L.Func x)
| x-map : Hom {comma-precat L b} x-comma terminal.apex => (x, id {TrivialCat} (), inv id-left)
\in
path (\lam i => ((inv $ terminal-unique' {comma-precat L b} {terminal} {x-comma} {x-map}) @ i).1)
}
}
\func terminal-in-comma {C D : Precat} (L : Functor D C) (B : C)
: Section {Coreflection L B} {terminal-obj (comma-precat L B)} => \new Section {
| f coref => Coreflection.to-comma-terminal {coref}
| ret => Coreflection.from-comma-terminal
| ret_f _ => idp
}
\where {
\func to-comma-isInj (x y : Coreflection L B) (eq : Coreflection.to-comma-terminal {x} = Coreflection.to-comma-terminal {y})
: x = y =>
inv (ret_f {terminal-in-comma L B} x) *> pmap (ret {terminal-in-comma L B}) eq *> ret_f {terminal-in-comma L B} y
}
\use\level isProp {C : Precat} {D : Cat} {L : Functor D C} {B : C}
(x y : Coreflection L B) : x = y =>
\let s : Coreflection.to-comma-terminal {x} = Coreflection.to-comma-terminal {y} => terminal-prop {comma-cat L B} _ _ \in
terminal-in-comma.to-comma-isInj x y s
}
\class RightAdjointCoreflection \extends Functor {
| L : Functor D C
\field coreflection (Z : C) : Coreflection {C} {D} L Z
| F X => coreflection X
| Func {X} {_} f => Equiv.ret {isCoreflection} (f ∘ corefl-map {coreflection X})
| Func-id {_} => unfold $ rewrite id-left $ inv $ Equiv.adjoint $ unfold $ rewrite (Func-id {L}, id-right) idp
| Func-o {_} {Y} {Z} {_} {_} => run {
unfold,
inv,
Equiv.adjoint,
unfold,
rewrite (Func-o {L}),
rewriteI o-assoc ,
rewrite (Equiv.f_ret {isCoreflection {coreflection Z}}),
rewrite o-assoc ,
rewrite (Equiv.f_ret {isCoreflection {coreflection Y}}),
inv o-assoc
}
\func eval-trans : NatTrans (Comp L \this) Id \cowith {
| trans c => corefl-map {coreflection c}
| natural _ => unfold $ Equiv.f_ret {isCoreflection} _
}
\func is-adjoint-counit {X : D} {Y : C} : Equiv {Hom X (F Y)} {Hom (L X) Y} (eval-trans Y ∘ L.Func __) =>
isCoreflection
}
\where {
\use \coerce toAdjointCounit(F : RightAdjointCoreflection) : RightAdjointCounit
\cowith {
| Functor => F
| LAdj => F.L
| epsilon => eval-trans
| isAdjoint-inv => is-adjoint-counit
}
\use \coerce fromAdjointCounit (F : RightAdjointCounit) : RightAdjointCoreflection F.C F.D F.LAdj \cowith {
| coreflection => \lam Z => \new Coreflection {
| Coreflected => F Z
| corefl-map => F.epsilon Z
| isCoreflection => F.isAdjoint-inv
}}
\use\level isProp {C : Precat} {D : Cat} (L : Functor D C)
(adj1 adj2 : RightAdjointCoreflection C D L) : adj1 = adj2
\elim adj1, adj2
| (coref1), (coref2) => exts (\lam Z => Coreflection.isProp {C} {D} {L} (coreflection {coref1} Z) (coreflection{coref2} Z))
}