Built with Alectryon. 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.
Require Import Basics.Overture Basics.Tactics Basics.PathGroupoids Basics.Trunc Basics.Equivalences.Require Import Basics.Overture Basics.Tactics Basics.PathGroupoids Basics.Trunc Basics.Equivalences.Require Import Types.Unit Types.Paths Types.UniverseTypes.Sigma.Require Import Truncations.Core Truncations.Connectedness.Require Import Colimits.Pushout Homotopy.Suspension.Require Import Homotopy.NullHomotopy.Require Import HFiber Limits.Pullback BlakersMassey.Set Universe Minimization ToSet.(** * Homotopy Cofibers *)(** ** Definition *)(** Homotopy cofibers or mapping cones are spaces constructed from a map [f : X -> Y] by contracting the image of [f] inside [Y] to a point. They can be thought of as a kind of coimage or quotient. *)DefinitionCofiber {XY : Type} (f : X -> Y)
:= Pushout f (const_tt X).(** *** Constructors *)(** Any element of [Y] can be included in the cofiber. *)Definitioncofib {XY : Type} (f : X -> Y) : Y -> Cofiber f
:= pushl.(** We have a distinguished point in the cofiber, where the image of [f] is contracted to. *)Definitioncf_apex {XY : Type} (f : X -> Y) : Cofiber f
:= pushr tt.(** Given an element [x : X], we have the path [cfglue f x] from the [f x] to the [cf_apex]. *)Definitioncfglue {XY : Type} (f : X -> Y) (x : X) : cofib f (f x) = cf_apex f
:= pglue _.(** *** Induction and recursion principles *)(** The recursion principle for the cofiber of [f : X -> Y] requires a function [g : Y -> Z] such that [g o f] is null homotopic, i.e. constant. *)
X, Y, Z: Type f: X -> Y g: Y -> Z null: NullHomotopy (g o f)
Cofiber f -> Z
X, Y, Z: Type f: X -> Y g: Y -> Z null: NullHomotopy (g o f)
Cofiber f -> Z
X, Y, Z: Type f: X -> Y g: Y -> Z null: NullHomotopy (g o f)
Y -> Z
X, Y, Z: Type f: X -> Y g: Y -> Z null: NullHomotopy (g o f)
Unit -> Z
X, Y, Z: Type f: X -> Y g: Y -> Z null: NullHomotopy (g o f)
foralla : X, ?pushb (f a) = ?pushc (const_tt X a)
X, Y, Z: Type f: X -> Y g: Y -> Z null: NullHomotopy (g o f)
Y -> Z
exact g.
X, Y, Z: Type f: X -> Y g: Y -> Z null: NullHomotopy (g o f)
Unit -> Z
intros; exact null.1.
X, Y, Z: Type f: X -> Y g: Y -> Z null: NullHomotopy (g o f)
foralla : X, g (f a) = unit_name null.1 (const_tt X a)
X, Y, Z: Type f: X -> Y g: Y -> Z null: NullHomotopy (g o f) a: X
g (f a) = unit_name null.1 (const_tt X a)
exact (null.2 a).Defined.(** The induction principle is similar, although requires a dependent form of null homotopy. *)
X, Y: Type f: X -> Y P: Cofiber f -> Type g: forally : Y, P (cofib f y) null: {b : P (cf_apex f) & forallx : X, transport P (cfglue f x) (g (f x)) = b}
forallx : Cofiber f, P x
X, Y: Type f: X -> Y P: Cofiber f -> Type g: forally : Y, P (cofib f y) null: {b : P (cf_apex f) & forallx : X, transport P (cfglue f x) (g (f x)) = b}
forallx : Cofiber f, P x
X, Y: Type f: X -> Y P: Cofiber f -> Type g: forally : Y, P (cofib f y) null: {b : P (cf_apex f) & forallx : X, transport P (cfglue f x) (g (f x)) = b}
forallb : Y, P (pushl b)
X, Y: Type f: X -> Y P: Cofiber f -> Type g: forally : Y, P (cofib f y) null: {b : P (cf_apex f) & forallx : X, transport P (cfglue f x) (g (f x)) = b}
forallc : Unit, P (pushr c)
X, Y: Type f: X -> Y P: Cofiber f -> Type g: forally : Y, P (cofib f y) null: {b : P (cf_apex f) & forallx : X, transport P (cfglue f x) (g (f x)) = b}
foralla : X, transport P (pglue a) (?pushb (f a)) = ?pushc (const_tt X a)
X, Y: Type f: X -> Y P: Cofiber f -> Type g: forally : Y, P (cofib f y) null: {b : P (cf_apex f) & forallx : X, transport P (cfglue f x) (g (f x)) = b}
forallb : Y, P (pushl b)
intros y; apply g.
X, Y: Type f: X -> Y P: Cofiber f -> Type g: forally : Y, P (cofib f y) null: {b : P (cf_apex f) & forallx : X, transport P (cfglue f x) (g (f x)) = b}
forallc : Unit, P (pushr c)
intros []; exact null.1.
X, Y: Type f: X -> Y P: Cofiber f -> Type g: forally : Y, P (cofib f y) null: {b : P (cf_apex f) & forallx : X, transport P (cfglue f x) (g (f x)) = b}
foralla : X,
transport P (pglue a) ((funy : Y => g y) (f a)) =
(func : Unit => match c as u return (P (pushr u)) with
| tt => null.1end)
(const_tt X a)
exact null.2.Defined.(** ** Functoriality *)LocalClose Scope trunc_scope.(** The homotopy cofiber can be thought of as a functor from the category of arrows in [Type] to [Type]. *)(** 1-functorial action. *)Definitionfunctor_cofiber {XYX'Y' : Type} {f : X -> Y} {f' : X' -> Y'}
(g : X -> X') (h : Y -> Y') (p : h o f == f' o g)
: Cofiber f -> Cofiber f'
:= functor_pushout g h idmap p (fun_ => idpath).(** 2-functorial action. *)
X, Y, X', Y': Type f: X -> Y f': X' -> Y' g, g': X -> X' h, h': Y -> Y' p: h o f == f' o g p': h' o f == f' o g' u: g == g' v: h == h' r: forallx : X, p x @ ap f' (u x) = v (f x) @ p' x
functor_cofiber g h p == functor_cofiber g' h' p'
X, Y, X', Y': Type f: X -> Y f': X' -> Y' g, g': X -> X' h, h': Y -> Y' p: h o f == f' o g p': h' o f == f' o g' u: g == g' v: h == h' r: forallx : X, p x @ ap f' (u x) = v (f x) @ p' x
functor_cofiber g h p == functor_cofiber g' h' p'
X, Y, X', Y': Type f: X -> Y f': X' -> Y' g, g': X -> X' h, h': Y -> Y' p: h o f == f' o g p': h' o f == f' o g' u: g == g' v: h == h' r: forallx : X, p x @ ap f' (u x) = v (f x) @ p' x
foralla : X,
(funx : X => 1) a @ ap (const_tt X') (u a) =
(funx : Unit => 1) (const_tt X a) @ (funx : X => 1) a
intro x; exact (concat_1p _ @ ap_const _ _).Defined.(** The cofiber functor preserves the identity map. *)Definitionfunctor_cofiber_idmap {XY : Type} (f : X -> Y)
: functor_cofiber (f:=f) idmap idmap (fun_ => 1) == idmap
:= functor_pushout_idmap.(** The cofiber functor preserves composition of squares. (When mapping parallel edges). *)Definitionfunctor_cofiber_compose {XYX'Y'X''Y'' : Type}
{f : X -> Y} {f' : X' -> Y'} {f'' : X'' -> Y''}
{g : X -> X'} {g' : X' -> X''} {h : Y -> Y'} {h' : Y' -> Y''}
(p : h o f == f' o g) (p' : h' o f' == f'' o g')
: functor_cofiber (g' o g) (h' o h) (funx => ap h' (p x) @ p' (g x))
== functor_cofiber g' h' p' o functor_cofiber g h p
:= functor_pushout_compose g h idmap g' h' idmap p (fun_ => 1) p' (fun_ => 1).LocalOpen Scope trunc_scope.(** ** Connectivity of cofibers *)(** The cofiber of an [n]-connected map is [n.+1]-connected. *)
n: trunc_index X, Y: Type f: X -> Y fc: IsConnMap (Tr n) f
IsConnected (Tr n.+1) (Cofiber f)
n: trunc_index X, Y: Type f: X -> Y fc: IsConnMap (Tr n) f
IsConnected (Tr n.+1) (Cofiber f)
n: trunc_index X, Y: Type f: X -> Y fc: IsConnMap (Tr n) f
forallC : Type,
In (Tr n.+1) C -> forallf0 : Cofiber f -> C, NullHomotopy f0
n: trunc_index X, Y: Type f: X -> Y fc: IsConnMap (Tr n) f C: Type H': In (Tr n.+1) C g: Cofiber f -> C
NullHomotopy g
n: trunc_index X, Y: Type f: X -> Y fc: IsConnMap (Tr n) f C: Type H': In (Tr n.+1) C g: Cofiber f -> C
forallx : Cofiber f, g x = g (cf_apex f)
n: trunc_index X, Y: Type f: X -> Y fc: IsConnMap (Tr n) f C: Type H': In (Tr n.+1) C g: Cofiber f -> C
forally : Y, g (cofib f y) = g (cf_apex f)
n: trunc_index X, Y: Type f: X -> Y fc: IsConnMap (Tr n) f C: Type H': In (Tr n.+1) C g: Cofiber f -> C
{b : g (cf_apex f) = g (cf_apex f) &
forallx : X,
transport (funx0 : Cofiber f => g x0 = g (cf_apex f))
(cfglue f x) (?Goal (f x)) =
b}
n: trunc_index X, Y: Type f: X -> Y fc: IsConnMap (Tr n) f C: Type H': In (Tr n.+1) C g: Cofiber f -> C
forally : Y, g (cofib f y) = g (cf_apex f)
n: trunc_index X, Y: Type f: X -> Y fc: IsConnMap (Tr n) f C: Type H': In (Tr n.+1) C g: Cofiber f -> C
foralla : X, g (cofib f (f a)) = g (cf_apex f)
n: trunc_index X, Y: Type f: X -> Y fc: IsConnMap (Tr n) f C: Type H': In (Tr n.+1) C g: Cofiber f -> C x: X
g (cofib f (f x)) = g (cf_apex f)
exact (ap g (cfglue f x)).
n: trunc_index X, Y: Type f: X -> Y fc: IsConnMap (Tr n) f C: Type H': In (Tr n.+1) C g: Cofiber f -> C
{b : g (cf_apex f) = g (cf_apex f) &
forallx : X,
transport (funx0 : Cofiber f => g x0 = g (cf_apex f))
(cfglue f x)
(conn_map_elim (Tr n) f (funb0 : Y => g (cofib f b0) = g (cf_apex f))
(funx0 : X => ap g (cfglue f x0)) (f x)) =
b}
n: trunc_index X, Y: Type f: X -> Y fc: IsConnMap (Tr n) f C: Type H': In (Tr n.+1) C g: Cofiber f -> C
forallx : X,
transport (funx0 : Cofiber f => g x0 = g (cf_apex f))
(cfglue f x)
(conn_map_elim (Tr n) f (funb : Y => g (cofib f b) = g (cf_apex f))
(funx0 : X => ap g (cfglue f x0)) (f x)) =
1
n: trunc_index X, Y: Type f: X -> Y fc: IsConnMap (Tr n) f C: Type H': In (Tr n.+1) C g: Cofiber f -> C x: X
transport (funx0 : Cofiber f => g x0 = g (cf_apex f))
(cfglue f x)
(conn_map_elim (Tr n) f (funb : Y => g (cofib f b) = g (cf_apex f))
(funx0 : X => ap g (cfglue f x0)) (f x)) =
1
n: trunc_index X, Y: Type f: X -> Y fc: IsConnMap (Tr n) f C: Type H': In (Tr n.+1) C g: Cofiber f -> C x: X
conn_map_elim (Tr n) f (funb : Y => g (cofib f b) = g (cf_apex f))
(funx0 : X => ap g (cfglue f x0)) (f x) =
ap g (cfglue f x) @ 1
n: trunc_index X, Y: Type f: X -> Y fc: IsConnMap (Tr n) f C: Type H': In (Tr n.+1) C g: Cofiber f -> C x: X
conn_map_elim (Tr n) f (funb : Y => g (cofib f b) = g (cf_apex f))
(funx0 : X => ap g (cfglue f x0)) (f x) =
ap g (cfglue f x)
napply conn_map_comp.Defined.(** ** Comparison of fibers and cofibers *)
X, Y: Type f: X -> Y y: Y
hfiber f y -> cofib f y = cf_apex f
X, Y: Type f: X -> Y y: Y
hfiber f y -> cofib f y = cf_apex f
X, Y: Type f: X -> Y y: Y x: X p: f x = y
cofib f y = cf_apex f
X, Y: Type f: X -> Y y: Y x: X p: f x = y
cofib f (f x) = cf_apex f
apply cfglue.Defined.(** Blakers-Massey implies that the comparison map is highly connected. Here we assume that [X] is merely inhabited. There is a variant that instead assumes that [f] is surjective, with the same proof except that [blakers_massey_po] is used. *)
H: Univalence n, m: trunc_index X, Y: Type ac: IsConnected (Tr m.+1) X f: X -> Y fc: IsConnMap (Tr n) f y: Y
IsConnMap (Tr (m +2+ n).-1) (fiber_to_path_cofiber f y)
H: Univalence n, m: trunc_index X, Y: Type ac: IsConnected (Tr m.+1) X f: X -> Y fc: IsConnMap (Tr n) f y: Y
IsConnMap (Tr (m +2+ n).-1) (fiber_to_path_cofiber f y)
(* It's enough to check the connectivity of [functor_sigma idmap (fiber_to_path_cofiber f)]. *)
H: Univalence n, m: trunc_index X, Y: Type ac: IsConnected (Tr m.+1) X f: X -> Y fc: IsConnMap (Tr n) f
(* We precompose with the equivalence [X <~> { y : Y & hfiber f y }]. *)
H: Univalence n, m: trunc_index X, Y: Type ac: IsConnected (Tr m.+1) X f: X -> Y fc: IsConnMap (Tr n) f
IsConnMap (Tr (m +2+ n).-1)
(funx : X =>
functor_sigma idmap (fiber_to_path_cofiber f)
(equiv_fibration_replacement f x))
(* The Sigma-type [{ y : Y & cofib f y = cf_apex f}] in the codomain is the fiber of the map [cofib f], and so it is equivalent to the pullback of the cospan in the pushout square defining [Cofiber f]. We postcompose with this equivalence. *)
H: Univalence n, m: trunc_index X, Y: Type ac: IsConnected (Tr m.+1) X f: X -> Y fc: IsConnMap (Tr n) f
IsConnMap (Tr (m +2+ n).-1)
((equiv_pullback_unit_hfiber (cofib f) pushr)^-1%equiv
o (funx : X =>
functor_sigma idmap (fiber_to_path_cofiber f)
(equiv_fibration_replacement f x)))
(* The composite is homotopic to the map from [blakers_massey_po], with the only difference being an extra [1 @ _]. *)
H: Univalence n, m: trunc_index X, Y: Type ac: IsConnected (Tr m.+1) X f: X -> Y fc: IsConnMap (Tr n) f
X -> Pullback (cofib f) pushr
H: Univalence n, m: trunc_index X, Y: Type ac: IsConnected (Tr m.+1) X f: X -> Y fc: IsConnMap (Tr n) f
?f ==
(funx : X =>
(equiv_pullback_unit_hfiber (cofib f) pushr)^-1%equiv
((funx0 : X =>
functor_sigma idmap (fiber_to_path_cofiber f)
(equiv_fibration_replacement f x0))
x))
H: Univalence n, m: trunc_index X, Y: Type ac: IsConnected (Tr m.+1) X f: X -> Y fc: IsConnMap (Tr n) f
IsConnMap (Tr (m +2+ n).-1) ?f
H: Univalence n, m: trunc_index X, Y: Type ac: IsConnected (Tr m.+1) X f: X -> Y fc: IsConnMap (Tr n) f
pullback_corec pglue ==
(funx : X =>
(equiv_pullback_unit_hfiber (cofib f) pushr)^-1%equiv
((funx0 : X =>
functor_sigma idmap (fiber_to_path_cofiber f)
(equiv_fibration_replacement f x0))
x))
(* Use [compute.] to see the details of the goal. *)
H: Univalence n, m: trunc_index X, Y: Type ac: IsConnected (Tr m.+1) X f: X -> Y fc: IsConnMap (Tr n) f x: X
pullback_corec pglue x =
(equiv_pullback_unit_hfiber (cofib f) pushr)^-1%equiv
(functor_sigma idmap (fiber_to_path_cofiber f)
(equiv_fibration_replacement f x))
H: Univalence n, m: trunc_index X, Y: Type ac: IsConnected (Tr m.+1) X f: X -> Y fc: IsConnMap (Tr n) f x: X
pglue x =
transport (funx0 : Y => cofib f x0 = pushr tt)
(eisretr 1%equiv
(functor_sigma idmap (fiber_to_path_cofiber f)
(equiv_fibration_replacement f x)).1)^
(functor_sigma idmap (fiber_to_path_cofiber f)
(equiv_fibration_replacement f x)).2
H: Univalence n, m: trunc_index X, Y: Type ac: IsConnected (Tr m.+1) X f: X -> Y fc: IsConnMap (Tr n) f x: X
pglue x = 1 @ cfglue f x
symmetry; apply concat_1p.Defined.(** This lets us prove a converse to [isconnected_cofiber] when [X] is 1-connected. *)
H: Univalence n: trunc_index X, Y: Type H0: IsConnected (Tr 1) X f: X -> Y H1: IsConnected (Tr n.+1) (Cofiber f)
IsConnMap (Tr n) f
H: Univalence n: trunc_index X, Y: Type H0: IsConnected (Tr 1) X f: X -> Y H1: IsConnected (Tr n.+1) (Cofiber f)
IsConnMap (Tr n) f
H: Univalence X, Y: Type H0: IsConnected (Tr 1) X f: X -> Y
IsConnected (Tr (-1)) (Cofiber f) -> IsConnMap (Tr (-2)) f
H: Univalence X, Y: Type H0: IsConnected (Tr 1) X f: X -> Y n: trunc_index IHn: IsConnected (Tr n.+1) (Cofiber f) -> IsConnMap (Tr n) f
IsConnected (Tr n.+2) (Cofiber f) -> IsConnMap (Tr n.+1) f
H: Univalence X, Y: Type H0: IsConnected (Tr 1) X f: X -> Y
IsConnected (Tr (-1)) (Cofiber f) -> IsConnMap (Tr (-2)) f
exact _.
H: Univalence X, Y: Type H0: IsConnected (Tr 1) X f: X -> Y n: trunc_index IHn: IsConnected (Tr n.+1) (Cofiber f) -> IsConnMap (Tr n) f
IsConnected (Tr n.+2) (Cofiber f) -> IsConnMap (Tr n.+1) f
H: Univalence X, Y: Type H0: IsConnected (Tr 1) X f: X -> Y n: trunc_index IHn: IsConnected (Tr n.+1) (Cofiber f) -> IsConnMap (Tr n) f conn_cof: IsConnected (Tr n.+2) (Cofiber f) y: Y
IsConnected (Tr n.+1) (hfiber f y)
H: Univalence X, Y: Type H0: IsConnected (Tr 1) X f: X -> Y n: trunc_index IHn: IsConnected (Tr n.+1) (Cofiber f) -> IsConnMap (Tr n) f conn_cof: IsConnected (Tr n.+2) (Cofiber f) y: Y
IsConnMap (Tr n.+1) (fiber_to_path_cofiber f y)
rapply (isconnected_fiber_to_cofiber n 0).Defined.