Built with Alectryon, running Coq+SerAPI v8.19.0+0.19.3. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑Ctrl+↓ to navigate, Ctrl+🖱️ to focus. On Mac, use ⌘ instead of Ctrl.
(** * Mapping Cylinders *)
[Loading ML file number_string_notation_plugin.cmxs (using legacy method) ... done]
Require Import Colimits.Pushout.LocalOpen Scope path_scope.(** As in topology, the mapping cylinder of a function [f : A -> B] is a way to replace it with an equivalent cofibration (dually to how [hfiber] replaces it with an equivalent fibration). We can't talk *internally* in type theory about cofibrations, but we can say metatheoretically what they are: functions with the isomorphism extension property. So while we can't literally say "let [f] be a cofibration" we can do a mostly equivalent thing and say "let [f] be a map and consider its mapping cylinder". Replacing a map by a cofibration can be useful because it allows us to make more equalities true definitionally. *)(** ** Definitions *)(** We define the mapping cylinder as the pushout of [f] and an identity map. Peter Lumsdaine has given a definition of HIT mapping cylinders that are dependent on the codomain, so that the second factor is not just an equivalence but a trivial fibration. However, at the moment we don't have a need for that. *)DefinitionCyl {AB : Type} (f : A -> B) : Type
:= Pushout idmap f.SectionMappingCylinder.Context {AB : Type} {f : A -> B}.Definitioncyl (a : A) : Cyl f
:= pushl a.Definitioncyr (b : B) : Cyl f
:= pushr b.Definitioncyglue (a : A)
: cyl a = cyr (f a)
:= pglue a.SectionCylInd.Context (P : Cyl f -> Type)
(cyla : foralla, P (cyl a))
(cylb : forallb, P (cyr b))
(cylg : foralla, DPath P (cyglue a) (cyla a) (cylb (f a))).DefinitionCyl_ind : forallc, P c
:= Pushout_ind _ cyla cylb cylg.DefinitionCyl_ind_beta_cyglue (a : A)
: apD Cyl_ind (cyglue a) = cylg a
:= Pushout_ind_beta_pglue _ _ _ _ _.EndCylInd.SectionCylRec.Context {P : Type} (cyla : A -> P) (cylb : B -> P) (cylg : cyla == cylb o f).DefinitionCyl_rec : Cyl f -> P
:= Pushout_rec _ cyla cylb cylg.DefinitionCyl_rec_beta_cyglue (a : A)
: ap Cyl_rec (cyglue a) = cylg a
:= Pushout_rec_beta_pglue _ _ _ _ _.EndCylRec.
A, B: Type f: A -> B
Cyl f <~> B
A, B: Type f: A -> B
Cyl f <~> B
(** Rather than adjointifying, we give all parts of the equivalence explicitly, so we can be sure of retaining the computational behavior of [eissect] and [eisretr]. However, it's easier to prove [eisadj] on the other side, so we reverse the equivalence first. *)
foralla : A,
(func : Cyl f =>
(cyr o Cyl_rec f idmap (funx0 : A => 1)) c = idmap c)
(cyl a)
A, B: Type f: A -> B
forallb : B,
(func : Cyl f =>
(cyr o Cyl_rec f idmap (funx0 : A => 1)) c = idmap c)
(cyr b)
A, B: Type f: A -> B
foralla : A,
DPath
(func : Cyl f =>
(cyr o Cyl_rec f idmap (funx0 : A => 1)) c =
idmap c) (cyglue a) (?cyla a) (?cylb (f a))
A, B: Type f: A -> B
foralla : A,
(func : Cyl f =>
(cyr o Cyl_rec f idmap (funx0 : A => 1)) c = idmap c)
(cyl a)
A, B: Type f: A -> B a: A
cyr (Cyl_rec f idmap (funx0 : A => 1) (cyl a)) =
cyl a
symmetry; apply cyglue.
A, B: Type f: A -> B
forallb : B,
(func : Cyl f =>
(cyr o Cyl_rec f idmap (funx0 : A => 1)) c = idmap c)
(cyr b)
intros b; reflexivity.
A, B: Type f: A -> B
foralla : A,
DPath
(func : Cyl f =>
(cyr o Cyl_rec f idmap (funx0 : A => 1)) c =
idmap c) (cyglue a)
((funa0 : A =>
(cyglue a0)^
:
(func : Cyl f =>
(cyr o Cyl_rec f idmap (funx0 : A => 1)) c =
idmap c) (cyl a0)) a) ((funb : B => 1) (f a))
A, B: Type f: A -> B a: A
transport
(func : Cyl f =>
cyr (Cyl_rec f idmap (funx0 : A => 1) c) = c)
(cyglue a) (cyglue a)^ = 1
A, B: Type f: A -> B a: A
((ap cyr
(ap (Cyl_rec f idmap (funx0 : A => 1)) (cyglue a)))^ @
(cyglue a)^) @ cyglue a = 1
A, B: Type f: A -> B a: A
((ap cyr 1)^ @ (cyglue a)^) @ cyglue a = 1
apply concat_pV_p.
A, B: Type f: A -> B
Cyl_rec f idmap (funx0 : A => 1) o cyr == idmap
intros b; reflexivity.
A, B: Type f: A -> B
forallx : B,
Cyl_ind
(func : Cyl f =>
(cyr o Cyl_rec f idmap (funx0 : A => 1)) c =
idmap c)
(funa : A =>
(cyglue a)^
:
(func : Cyl f =>
(cyr o Cyl_rec f idmap (funx0 : A => 1)) c =
idmap c) (cyl a)) (funb : B => 1)
(funa : A =>
(letX :=
fun (p : cyl a = cyr (f a))
(q : cyr
(Cyl_rec f idmap (funx0 : A => 1)
(cyl a)) = cyl a)
(r : cyr
(Cyl_rec f idmap (funx0 : A => 1)
(cyr (f a))) = cyr (f a)) =>
equiv_fun (dp_paths_FFlr p q r) in
X (cyglue a) (cyglue a)^ 1
(internal_paths_rew_r
(funp : Cyl_rec f idmap (funx0 : A => 1)
(cyl a) =
Cyl_rec f idmap (funx0 : A => 1)
(cyr (f a)) =>
((ap cyr p)^ @ (cyglue a)^) @ cyglue a = 1)
(concat_pV_p 1 (cyglue a))
(Cyl_rec_beta_cyglue f idmap
(funx0 : A => 1) a)))
:
DPath
(func : Cyl f =>
(cyr o Cyl_rec f idmap (funx0 : A => 1)) c =
idmap c) (cyglue a)
((funa0 : A =>
(cyglue a0)^
:
(func : Cyl f =>
(cyr o Cyl_rec f idmap (funx0 : A => 1)) c =
idmap c) (cyl a0)) a) ((funb : B => 1) (f a)))
(cyr x) =
ap cyr
(((funb : B => 1)
:
Cyl_rec f idmap (funx0 : A => 1) o cyr == idmap)
x)
intros b; reflexivity.Defined.Definitionap_pr_cyl_cyglue (a : A)
: ap pr_cyl (cyglue a) = 1
:= Cyl_rec_beta_cyglue _ _ _ a.(** The original map [f] factors definitionally through [Cyl f]. *)Definitionpr_cyl_cyl (a : A) : pr_cyl (cyl a) = f a
:= 1.EndMappingCylinder.(** Sometimes we have to specify the map explicitly. *)Definitioncyl' {AB} (f : A -> B) : A -> Cyl f := cyl.Definitionpr_cyl' {AB} (f : A -> B) : Cyl f -> B := pr_cyl.(** ** Functoriality *)SectionFunctorCyl.Context {ABA'B': Type} {f : A -> B} {f' : A' -> B'}
{ga : A -> A'} {gb : B -> B'}
(g : f' o ga == gb o f).
A, B, A', B': Type f: A -> B f': A' -> B' ga: A -> A' gb: B -> B' g: f' o ga == gb o f
Cyl f -> Cyl f'
A, B, A', B': Type f: A -> B f': A' -> B' ga: A -> A' gb: B -> B' g: f' o ga == gb o f
Cyl f -> Cyl f'
A, B, A', B': Type f: A -> B f': A' -> B' ga: A -> A' gb: B -> B' g: f' o ga == gb o f
A -> Cyl f'
A, B, A', B': Type f: A -> B f': A' -> B' ga: A -> A' gb: B -> B' g: f' o ga == gb o f
B -> Cyl f'
A, B, A', B': Type f: A -> B f': A' -> B' ga: A -> A' gb: B -> B' g: f' o ga == gb o f
?cyla == ?cylb o f
A, B, A', B': Type f: A -> B f': A' -> B' ga: A -> A' gb: B -> B' g: f' o ga == gb o f
A -> Cyl f'
exact (cyl o ga).
A, B, A', B': Type f: A -> B f': A' -> B' ga: A -> A' gb: B -> B' g: f' o ga == gb o f
B -> Cyl f'
exact (cyr o gb).
A, B, A', B': Type f: A -> B f': A' -> B' ga: A -> A' gb: B -> B' g: f' o ga == gb o f
cyl o ga == cyr o gb o f
A, B, A', B': Type f: A -> B f': A' -> B' ga: A -> A' gb: B -> B' g: f' o ga == gb o f a: A
cyl (ga a) = cyr (gb (f a))
A, B, A', B': Type f: A -> B f': A' -> B' ga: A -> A' gb: B -> B' g: f' o ga == gb o f a: A
cyl (ga a) = cyr (f' (ga a))
exact (cyglue (ga a)).Defined.Definitionap_functor_cyl_cyglue (a : A)
: ap functor_cyl (cyglue a) = cyglue (ga a) @ ap cyr (g a)
:= Cyl_rec_beta_cyglue _ _ _ a.(** The benefit of passing to the mapping cylinder is that it makes a square commute definitionally. *)Definitionfunctor_cyl_cyl (a : A) : cyl (ga a) = functor_cyl (cyl a)
:= 1.(** The other square also commutes, though not definitionally. *)Definitionpr_functor_cyl (c : Cyl f)
: pr_cyl (functor_cyl c) = gb (pr_cyl c)
:= ap (pr_cyl o functor_cyl) (eissect pr_cyl c)^.
A, B, A', B': Type f: A -> B f': A' -> B' ga: A -> A' gb: B -> B' g: f' o ga == gb o f a: A
pr_functor_cyl (cyl a) = g a
A, B, A', B': Type f: A -> B f': A' -> B' ga: A -> A' gb: B -> B' g: f' o ga == gb o f a: A
pr_functor_cyl (cyl a) = g a
(** Here we need [eissect pr_cyl (cyl a)] to compute. *)
A, B, A', B': Type f: A -> B f': A' -> B' ga: A -> A' gb: B -> B' g: f' o ga == gb o f a: A
ap (funx : Cyl f => pr_cyl (functor_cyl x))
(cyglue a) = g a
A, B, A', B': Type f: A -> B f': A' -> B' ga: A -> A' gb: B -> B' g: f' o ga == gb o f a: A
ap pr_cyl (ap functor_cyl (cyglue a)) = g a
A, B, A', B': Type f: A -> B f': A' -> B' ga: A -> A' gb: B -> B' g: f' o ga == gb o f a: A
ap pr_cyl (cyglue (ga a) @ ap cyr (g a)) = g a
A, B, A', B': Type f: A -> B f': A' -> B' ga: A -> A' gb: B -> B' g: f' o ga == gb o f a: A
ap pr_cyl (cyglue (ga a)) @ ap pr_cyl (ap cyr (g a)) =
g a
A, B, A', B': Type f: A -> B f': A' -> B' ga: A -> A' gb: B -> B' g: f' o ga == gb o f a: A
ap pr_cyl (ap cyr (g a)) = g a
A, B, A', B': Type f: A -> B f': A' -> B' ga: A -> A' gb: B -> B' g: f' o ga == gb o f a: A
ap (funx : B' => pr_cyl (cyr x)) (g a) = g a
apply ap_idmap.Defined.EndFunctorCyl.(** ** Coequalizers *)(** A particularly useful application is to replace a map of coequalizers with one where both squares commute definitionally. *)SectionCylCoeq.Context {BAfgB'A'f'g'}
{h : B -> B'} {k : A -> A'}
(p : k o f == f' o h) (q : k o g == g' o h).DefinitionCylCoeq : Type
:= Coeq (functor_cyl p) (functor_cyl q).Definitioncyl_cylcoeq : Coeq f g -> CylCoeq
:= functor_coeq cyl cyl (functor_cyl_cyl p) (functor_cyl_cyl q).
B, A: Type f, g: B -> A B', A': Type f', g': B' -> A' h: B -> B' k: A -> A' p: k o f == f' o h q: k o g == g' o h b: B
ap cyl_cylcoeq (cglue b) = cglue (cyl b)
B, A: Type f, g: B -> A B', A': Type f', g': B' -> A' h: B -> B' k: A -> A' p: k o f == f' o h q: k o g == g' o h b: B
ap cyl_cylcoeq (cglue b) = cglue (cyl b)
B, A: Type f, g: B -> A B', A': Type f', g': B' -> A' h: B -> B' k: A -> A' p: k o f == f' o h q: k o g == g' o h b: B
ap cyl_cylcoeq (cglue b) = ?Goal
B, A: Type f, g: B -> A B', A': Type f', g': B' -> A' h: B -> B' k: A -> A' p: k o f == f' o h q: k o g == g' o h b: B
?Goal = cglue (cyl b)
B, A: Type f, g: B -> A B', A': Type f', g': B' -> A' h: B -> B' k: A -> A' p: k o f == f' o h q: k o g == g' o h b: B
(ap coeq (functor_cyl_cyl p b) @ cglue (cyl b)) @
ap coeq (functor_cyl_cyl q b)^ = cglue (cyl b)
B, A: Type f, g: B -> A B', A': Type f', g': B' -> A' h: B -> B' k: A -> A' p: k o f == f' o h q: k o g == g' o h x: Cyl h
PathSquare (ap pr_cylcoeq (cglue x))
(cglue (pr_cyl x)) (ap coeq (pr_functor_cyl p x))
(ap coeq (pr_functor_cyl q x))
B, A: Type f, g: B -> A B', A': Type f', g': B' -> A' h: B -> B' k: A -> A' p: k o f == f' o h q: k o g == g' o h x: Cyl h
PathSquare (ap pr_cylcoeq (cglue x))
(cglue (pr_cyl x)) (ap coeq (pr_functor_cyl p x))
(ap coeq (pr_functor_cyl q x))
B, A: Type f, g: B -> A B', A': Type f', g': B' -> A' h: B -> B' k: A -> A' p: k o f == f' o h q: k o g == g' o h x: Cyl h
ap pr_cylcoeq (cglue x) @ ap coeq (pr_functor_cyl q x) =
ap coeq (pr_functor_cyl p x) @ cglue (pr_cyl x)
B, A: Type f, g: B -> A B', A': Type f', g': B' -> A' h: B -> B' k: A -> A' p: k o f == f' o h q: k o g == g' o h x: Cyl h
ap pr_cylcoeq (cglue x) =
(ap coeq (pr_functor_cyl p x) @ cglue (pr_cyl x)) @
(ap coeq (pr_functor_cyl q x))^
B, A: Type f, g: B -> A B', A': Type f', g': B' -> A' h: B -> B' k: A -> A' p: k o f == f' o h q: k o g == g' o h x: Cyl h
ap pr_cylcoeq (cglue x) =
(ap coeq (pr_functor_cyl p x) @ cglue (pr_cyl x)) @
ap coeq (pr_functor_cyl q x)^
rapply functor_coeq_beta_cglue.Defined.
B, A: Type f, g: B -> A B', A': Type f', g': B' -> A' h: B -> B' k: A -> A' p: k o f == f' o h q: k o g == g' o h
functor_coeq h k p q == pr_cylcoeq o cyl_cylcoeq
B, A: Type f, g: B -> A B', A': Type f', g': B' -> A' h: B -> B' k: A -> A' p: k o f == f' o h q: k o g == g' o h
functor_coeq h k p q == pr_cylcoeq o cyl_cylcoeq
B, A: Type f, g: B -> A B', A': Type f', g': B' -> A' h: B -> B' k: A -> A' p: k o f == f' o h q: k o g == g' o h c: Coeq f g
functor_coeq h k p q c = pr_cylcoeq (cyl_cylcoeq c)
B, A: Type f, g: B -> A B', A': Type f', g': B' -> A' h: B -> B' k: A -> A' p: k o f == f' o h q: k o g == g' o h c: Coeq f g
functor_coeq h k p q c =
functor_coeq (funx : B => pr_cyl (cyl x))
(funx : A => pr_cyl (cyl x))
(funb : B =>
ap pr_cyl (functor_cyl_cyl p b) @
pr_functor_cyl p (cyl b))
(funb : B =>
ap pr_cyl (functor_cyl_cyl q b) @
pr_functor_cyl q (cyl b)) c
B, A: Type f, g: B -> A B', A': Type f', g': B' -> A' h: B -> B' k: A -> A' p: k o f == f' o h q: k o g == g' o h c: Coeq f g
h == (funx : B => pr_cyl (cyl x))
B, A: Type f, g: B -> A B', A': Type f', g': B' -> A' h: B -> B' k: A -> A' p: k o f == f' o h q: k o g == g' o h c: Coeq f g
k == (funx : A => pr_cyl (cyl x))
B, A: Type f, g: B -> A B', A': Type f', g': B' -> A' h: B -> B' k: A -> A' p: k o f == f' o h q: k o g == g' o h c: Coeq f g
forallb : B,
?s (f b) @
(funb0 : B =>
ap pr_cyl (functor_cyl_cyl p b0) @
pr_functor_cyl p (cyl b0)) b = p b @ ap f' (?r b)
B, A: Type f, g: B -> A B', A': Type f', g': B' -> A' h: B -> B' k: A -> A' p: k o f == f' o h q: k o g == g' o h c: Coeq f g
forallb : B,
?s (g b) @
(funb0 : B =>
ap pr_cyl (functor_cyl_cyl q b0) @
pr_functor_cyl q (cyl b0)) b = q b @ ap g' (?r b)
B, A: Type f, g: B -> A B', A': Type f', g': B' -> A' h: B -> B' k: A -> A' p: k o f == f' o h q: k o g == g' o h c: Coeq f g
forallb : B,
(funx0 : A => 1) (f b) @
(funb0 : B =>
ap pr_cyl (functor_cyl_cyl p b0) @
pr_functor_cyl p (cyl b0)) b =
p b @ ap f' ((funx0 : B => 1) b)
B, A: Type f, g: B -> A B', A': Type f', g': B' -> A' h: B -> B' k: A -> A' p: k o f == f' o h q: k o g == g' o h c: Coeq f g
forallb : B,
(funx0 : A => 1) (g b) @
(funb0 : B =>
ap pr_cyl (functor_cyl_cyl q b0) @
pr_functor_cyl q (cyl b0)) b =
q b @ ap g' ((funx0 : B => 1) b)
B, A: Type f, g: B -> A B', A': Type f', g': B' -> A' h: B -> B' k: A -> A' p: k o f == f' o h q: k o g == g' o h c: Coeq f g b: B
1 @ (1 @ pr_functor_cyl p (cyl b)) = p b @ 1
B, A: Type f, g: B -> A B', A': Type f', g': B' -> A' h: B -> B' k: A -> A' p: k o f == f' o h q: k o g == g' o h c: Coeq f g b: B
1 @ (1 @ pr_functor_cyl q (cyl b)) = q b @ 1
B, A: Type f, g: B -> A B', A': Type f', g': B' -> A' h: B -> B' k: A -> A' p: k o f == f' o h q: k o g == g' o h c: Coeq f g b: B
pr_functor_cyl p (cyl b) = p b
B, A: Type f, g: B -> A B', A': Type f', g': B' -> A' h: B -> B' k: A -> A' p: k o f == f' o h q: k o g == g' o h c: Coeq f g b: B