{- | The construction of the image of a map from the paper - Egbert Rijke, The join construction, https://arxiv.org/pdf/1701.07538.pdf -} \import Data.SeqColimit \import Equiv \import Equiv.Univalence \import HLevel \import Homotopy.Fibration \import Homotopy.Pushout \import Logic \import Paths \import Paths.Meta \func MJoin {A B : \Type} (R : A -> B -> \Type) => PushoutData {\Sigma (x : A) (y : B) (R x y)} __.1 __.2 \where \class MData \noclassifying {A : \Type} {B : \Type (\suc \lp)} (f : A -> B) (R : B -> B -> \Type) (ret : \Pi (b b' : B) -> R b b' -> b = b') { \func MImageAppr (n : Nat) : \Sigma (X : \hType) (X -> B) \elim n | 0 => (A,f) | suc n => \let (X,g) => MImageAppr n \in (MJoin (\lam a x => R (f a) (g x)), PushoutData.rec f g (\lam q => ret (f q.1) (g q.2) q.3)) \func MImage => SeqColimit seq \func seq : Seq \cowith | A n => (MImageAppr n).1 | f x => pinr x \func dom-map (a : A) : MImage => inSC {seq} {0} a \lemma dom-map-surj (refl : \Pi {b : B} -> R b b) : Surjection dom-map => seqColimit-surj seq (\lam n => \new Surjection { | isSurjMap y => \case \elim y \with { | pinl a => inP (\case \elim n \with { | 0 => (a, inv (path (pglue ((a,a,refl) : \Sigma (a : A) (a' : A) (R (f a) (f a')))))) | suc n => (pinl a, inv (path (pglue ((a, pinl a, refl) : \Sigma (a : A) (x : (MImageAppr (suc n)).1) (R (f a) ((MImageAppr (suc n)).2 x)))))) }) | pinr x => inP (x,idp) } }) \func cod-map (x : MImage) : B \elim x | inSC {n} x => (MImageAppr n).2 x | quotSC {n} x => idp \lemma cod-map-emb (refl : \Pi {b : B} -> R b b) (refl-idp : \Pi {b : B} -> ret b b refl = idp) : Embedding cod-map => Embedding.fibers cod-map (\lam b => isContr'=>isProp (\lam (r : Fib cod-map b) => \case isSurjMap {dom-map-surj refl} r.1 \with { | inP r' => rewriteI (pmap cod-map r'.2 *> r.2) (fibers-contr refl refl-idp r'.1) })) \where \lemma fibers-contr (refl : \Pi {b : B} -> R b b) (refl-idp : \Pi {b : B} -> ret b b refl = idp) (a : A) : Contr (Fib cod-map (f a)) => \let | P x => cod-map x = f a | sec {b b' : B} (q : b = b') => transport (R b) q refl | sec-ret {b b' : B} (q : b = b') => Jl (\lam b'' q' => ret b b'' (sec q') = q') refl-idp q \in rewriteI (SeqColimit.flattening P) (constantMaps SeqColimit.flattening.total.seq (\lam n => ((pinl a, idp), \lam p => inv (ext (path (pglue ((a, p.1, sec (inv p.2)) : \Sigma (a : A) (x : (MImageAppr n).1) (R (f a) ((MImageAppr n).2 x)))), transport_path-left (ret (f a) ((MImageAppr n).2 p.1) (sec (inv p.2))) idp *> pmap inv (sec-ret (inv p.2)) *> inv_inv p.2))))) } \func YImage {A B : \Type} (S : A -> B -> \Type) => data.MImage \where { \open MJoin \instance data : MData S \cowith | R F G => \Pi (b : B) -> Equiv {F b} {G b} | ret F G r => path (\lam i b => Equiv-to-= (r b) @ i) \func dom-map (a : A) : YImage S => MData.dom-map a \lemma dom-map-surj : Surjection dom-map => MData.dom-map-surj (\lam {F} b => idEquiv {F b}) \func cod-map (y : YImage S) (b : B) : \Type => MData.cod-map y b \lemma cod-map-emb : Embedding cod-map => MData.cod-map-emb (\lam {F} b => idEquiv {F b}) (\lam {F} => \have p b : Equiv-to-= (idEquiv {F b}) = idp => univalence.ret_f idp \in path (\lam i => path (\lam j b => p b @ i @ j))) }