\import Category
\import Category.Functor
\import Category.Slice
\import Category.Topos.Sheaf.Site
\import Function.Meta
\import Logic
\import Logic.Meta
\import Meta
\import Paths
\import Paths.Meta
\open Covering
\record SitePrehom \extends Functor {
\override C : Site
\override D : Site
| Func-cover {x : C} {P : Presieve x} : isCover x P -> Covering (F x) (Presieve.pushforward \this P)
\lemma Func-covering {x : C} {P : Presieve x} (x<=P : Covering x P) : Covering (F x) (Presieve.pushforward \this P) \elim x<=P
| covering-inj x>y y>x x>y>x Py => covering-inj (Func x>y) (Func y>x) (inv Func-o *> pmap Func x>y>x *> Func-id) $ inP (_, Py, idp)
| covering-trans x<=T T<=P => Covering.covering-trans* (Func-cover x<=T) \lam {_} (inP (px,Tpx,idp)) => Covering.covering-sub (Func-covering (T<=P Tpx))
\lam {_} (inP (z, inP (u,Pu,z>u,z>u_px), idp)) => inP (_, inP (u, Pu, idp), Func z>u, inv Func-o *> pmap Func z>u_px *> Func-o)
}
\record SiteHom \extends SitePrehom {
| Func-flat-terminal {u : D} : Covering u \lam v => ∃ (w : C) (Hom v.1 (F w))
| Func-flat-pullback {x y1 y2 : C} {p1 : Hom y1 x} {p2 : Hom y2 x} {u : D} {f : Hom u (F y1)} {g : Hom u (F y2)} (f_g : Func p1 ∘ f = Func p2 ∘ g)
: Covering u \lam v => ∃ (w : C) (f' : Hom w y1) (g' : Hom w y2) (p1 ∘ f' = p2 ∘ g') (h : Hom v.1 (F w)) (Func f' ∘ h = f ∘ v.2) (Func g' ∘ h = g ∘ v.2)
} \where {
\func id {C : Site} : SiteHom C C \cowith
| Functor => Id
| Func-cover {x} {P} c => covering-basic $ transport (isCover x) (ext \lam px => ext (\lam Ppx => inP (px,Ppx,idp), \lam (inP (py,Ppy,q)) => transportInv P q Ppy)) c
| Func-flat-terminal {u} => covering-id $ inP (u, C.id)
| Func-flat-pullback {x} {y1} {y2} {p1} {p2} {u} {f} {g} f_g => covering-id $ inP (u, f, g, f_g, C.id, idp, idp)
}
\record SiteDensePrehom \extends SitePrehom {
| Func-dense-image {u : D} : Covering u \lam v => ∃ (x : C) (Iso {D} {v.1} {F x})
| Func-dense-map {a b : C} (g : Hom (F a) (F b)) : Covering a \lam v => ∃ (h : Hom v.1 b) (g ∘ Func v.2 = Func h)
\lemma Func-dense-map-image {a : D} {b : C} (g : Hom a (F b))
: Covering a (\lam u => ∃ (x : C) (e : Iso {D} {F x} {u.1}) (h : Hom x b) (g ∘ u.2 ∘ e.f = Func h))
=> covering-trans* Func-dense-image \lam {pa} (inP (x,pa=Fx)) => covering-stable-retract pa=Fx.f pa=Fx.hinv pa=Fx.hinv_f $
covering-sub (Func-covering $ Func-dense-map $ g ∘ pa.2 ∘ pa=Fx.hinv) \lam {_} (inP (px, inP (px>b,pxc), idp)) =>
inP ((_,_), inP ((_,_), inP (px.1, idIso, px>b, id-right *> inv o-assoc *> inv o-assoc *> pxc), id, id-right), id, id-right)
\lemma Func-dense-map2-image {a : D} {b b' : C} (g : Hom a (F b)) (g' : Hom a (F b'))
: Covering a (\lam u => ∃ (x : C) (e : Iso {D} {F x} {u.1}) (h : Hom x b) (g ∘ u.2 ∘ e.f = Func h) (h' : Hom x b') (g' ∘ u.2 ∘ e.f = Func h'))
=> covering-trans* (Func-dense-map-image g) \lam {pa} (inP (x,Fx=pa,x>b,xbc)) => covering-stable-retract Fx=pa.hinv Fx=pa.f Fx=pa.f_hinv $
covering-sub (Func-covering $ Func-dense-map $ g' ∘ pa.2 ∘ Fx=pa.f) \lam {_} (inP (y, inP (y>b',yb'c), idp)) =>
inP ((_,_), inP ((_,_), inP (y.1, idIso, x>b ∘ y.2, id-right *> inv o-assoc *> inv o-assoc *> pmap (∘ _) xbc *> inv Func-o, y>b', id-right *> inv o-assoc *> inv o-assoc *> yb'c), id, id-right), id, id-right)
}
\record SiteDenseHom \extends SiteDensePrehom, SiteHom
| Func-dense-cover {x : C} {P : Presieve x} : Covering (F x) (Presieve.pushforward \this P) -> Covering x P
| Func-dense-equal {a b : C} (f g : Hom a b) : Func f = Func g -> Covering a \lam pa => f ∘ pa.2 = g ∘ pa.2
| Func-flat-terminal => covering-sub Func-dense-image \lam {v} (inP (x,v=Fx)) => inP (x,v=Fx)
| Func-flat-pullback {y0} {y1} {y2} {p1} {p2} {u} {f} {g} f_g => covering-trans* (Func-dense-map2-image f g)
\lam {pu} (inP (x,Fx=pu,x>y1,f_x>y1,x>y2,g_x>y2)) => covering-stable-retract Fx=pu.hinv Fx=pu.f Fx=pu.f_hinv $
covering-sub (Func-covering $ Func-dense-equal (p1 ∘ x>y1) (p2 ∘ x>y2) $ Func-o *> pmap (_ ∘) (inv f_x>y1) *> inv o-assoc *> pmap (∘ _) (inv o-assoc *> pmap (∘ _) f_g *> o-assoc) *> o-assoc *> pmap (_ ∘) g_x>y2 *> inv Func-o)
\lam {_} (inP (px,q,idp)) => inP ((_,_), inP ((_,_), inP (px.1, x>y1 ∘ px.2, x>y2 ∘ px.2, inv o-assoc *> q *> o-assoc, id,
id-right *> Func-o *> pmap (∘ _) (inv f_x>y1) *> o-assoc *> o-assoc,
id-right *> Func-o *> pmap (∘ _) (inv g_x>y2) *> o-assoc *> o-assoc), id, id-right), id, id-right)