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.
(** * Kan extensions of type families *)(** This is part of the formalization of section 4 of the paper: Injective Types in Univalent Mathematics by Martín Escardó. Many proofs are guided by Martín Escardó's original Agda formalization of this paper which can be found at: https://www.cs.bham.ac.uk/~mhe/TypeTopology/InjectiveTypes.Article.html. *)
[Loading ML file number_string_notation_plugin.cmxs (using legacy method) ... done]
Require Import Types.Sigma Types.Unit Types.Arrow Types.Forall Types.Empty Types.UniverseTypes.Equiv Types.Paths.Require Import HFiber.Require Import Truncations.Core.Require Import Modalities.ReflectiveSubuniverse Modalities.Modality.(** We are careful about universe variables for these first few definitions because they are used in the rest of the paper. We use [u], [v], [w], etc. as our typical universe variables. Our convention for the max of two universes [u] and [v] is [uv]. *)SectionUniverseStructure.Universes u v w uv uw vw uvw.Constraintu <= uv, v <= uv, u <= uw, w <= uw, v <= vw, w <= vw,
uv <= uvw, uw <= uvw, vw <= uvw.DefinitionLeftKanFam@{} {X : Type@{u}} {Y : Type@{v}} (P : X -> Type@{w}) (j : X -> Y)
: Y -> Type@{uvw}
:= funy => sig@{uv w} (fun (w : hfiber j y) => P (w.1)).DefinitionRightKanFam@{} {X : Type@{u}} {Y : Type@{v}} (P : X -> Type@{w}) (j : X -> Y)
: Y -> Type@{uvw}
:= funy => forall (w : hfiber j y), P (w.1).(** Below we will introduce notations [P <| j] and [P |> j] for these Kan extensions. *)(** If [j] is an embedding, then [P <| j] and [P |> j] are extensions in the following sense: [(P <| j o j) x <~> P x <~> (P |> j o j) x]. So, with univalence, we get that they are extensions. *)
X, Y: Type P: X -> Type j: X -> Y isem: IsEmbedding j x: X
LeftKanFam P j (j x) <~> P x
X, Y: Type P: X -> Type j: X -> Y isem: IsEmbedding j x: X
H: Funext X, Y: Type P: X -> Type j: X -> Y isem: IsEmbedding j x: X
RightKanFam P j (j x) <~> P x
H: Funext X, Y: Type P: X -> Type j: X -> Y isem: IsEmbedding j x: X
RightKanFam P j (j x) <~> P x
exact (@equiv_contr_forall _ (hfiber j (j x)) _ _).Defined.Definitionisext_leftkanfam@{suvw | uvw < suvw} `{Univalence} {X : Type@{u}} {Y : Type@{v}}
(P : X -> Type@{w}) (j : X -> Y) (isem : IsEmbedding@{u v uv} j) (x : X)
: @paths@{suvw} Type@{uvw} (LeftKanFam@{} P j (j x)) (P x)
:= path_universe_uncurried (isext_equiv_leftkanfam _ _ _ _).Definitionisext_rightkanfam@{suvw | uvw < suvw} `{Univalence} {X : Type@{u}} {Y : Type@{v}}
(P : X -> Type@{w}) (j : X -> Y) (isem : IsEmbedding@{u v uv} j) (x : X)
: @paths@{suvw} Type@{uvw} (RightKanFam@{} P j (j x)) (P x)
:= path_universe_uncurried (isext_equiv_rightkanfam _ _ _ _).EndUniverseStructure.Notation"P <| j" := (LeftKanFam P j) : function_scope.Notation"P |> j" := (RightKanFam P j) : function_scope.(** For [y : Y] not in the image of [j], [(P <| j) y] is empty and [(P |> j) y] is contractible. *)Definitionisempty_leftkanfam {X : Type} {Y : Type}
(P : X -> Type) (j : X -> Y) (y : Y) (ynin : forallx : X, j x <> y)
: (P <| j) y -> Empty
:= fun '((x; p); _) => ynin x p.
H: Funext X, Y: Type P: X -> Type j: X -> Y y: Y ynin: forallx : X, j x <> y
Contr ((P |> j) y)
H: Funext X, Y: Type P: X -> Type j: X -> Y y: Y ynin: forallx : X, j x <> y
Contr ((P |> j) y)
H: Funext X, Y: Type P: X -> Type j: X -> Y y: Y ynin: forallx : X, j x <> y
foralla : hfiber j y,
Contr ((funa0 : hfiber j y => P a0.1) a)
H: Funext X, Y: Type P: X -> Type j: X -> Y y: Y ynin: forallx : X, j x <> y x: X p: j x = y
Contr (P (x; p).1)
apply (Empty_rec (ynin x p)).Defined.(** The following equivalences tell us that [{ y : Y & (P <| j) y}] and [forall y : Y, (P |> j) y] can be thought of as just different notation for the sum and product of a type family. *)
X, Y: Type P: X -> Type j: X -> Y
{x : X & P x} <~> {y : Y & (P <| j) y}
X, Y: Type P: X -> Type j: X -> Y
{x : X & P x} <~> {y : Y & (P <| j) y}
X, Y: Type P: X -> Type j: X -> Y
{x : X & P x} -> {y : Y & (P <| j) y}
X, Y: Type P: X -> Type j: X -> Y
{y : Y & (P <| j) y} -> {x : X & P x}
X, Y: Type P: X -> Type j: X -> Y
?f o ?g == idmap
X, Y: Type P: X -> Type j: X -> Y
?g o ?f == idmap
X, Y: Type P: X -> Type j: X -> Y
{x : X & P x} -> {y : Y & (P <| j) y}
exact (funw : {x : X & P x} => (j w.1; (w.1; idpath); w.2)).
(funw : {x : X & P x} => (j w.1; (w.1; 1); w.2))
o (funpat : {y : Y & (P <| j) y} =>
letx := pat inlety := x.1inletproj2 := x.2inletproj3 := proj2 inletproj1 := proj3.1inlety' := proj3.2in
(letproj4 := proj1 inletx0 := proj4.1inletp := proj4.2infuny'0 : P (x0; p).1 => (x0; y'0)) y') == idmap
byintros [y [[x []] y']].
X, Y: Type P: X -> Type j: X -> Y
(funpat : {y : Y & (P <| j) y} =>
letx := pat inlety := x.1inletproj2 := x.2inletproj3 := proj2 inletproj1 := proj3.1inlety' := proj3.2in
(letproj4 := proj1 inletx0 := proj4.1inletp := proj4.2infuny'0 : P (x0; p).1 => (x0; y'0)) y')
o (funw : {x : X & P x} => (j w.1; (w.1; 1); w.2)) ==
idmap
reflexivity.Defined.
H: Funext X, Y: Type P: X -> Type j: X -> Y
(forallx : X, P x) <~> (forally : Y, (P |> j) y)
H: Funext X, Y: Type P: X -> Type j: X -> Y
(forallx : X, P x) <~> (forally : Y, (P |> j) y)
H: Funext X, Y: Type P: X -> Type j: X -> Y
(forallx : X, P x) -> forally : Y, (P |> j) y
H: Funext X, Y: Type P: X -> Type j: X -> Y
(forally : Y, (P |> j) y) -> forallx : X, P x
H: Funext X, Y: Type P: X -> Type j: X -> Y
?f o ?g == idmap
H: Funext X, Y: Type P: X -> Type j: X -> Y
?g o ?f == idmap
H: Funext X, Y: Type P: X -> Type j: X -> Y
(forallx : X, P x) -> forally : Y, (P |> j) y
H: Funext X, Y: Type P: X -> Type j: X -> Y g: forallx : X, P x y: Y w: hfiber j y
P w.1
exact (g w.1).
H: Funext X, Y: Type P: X -> Type j: X -> Y
(forally : Y, (P |> j) y) -> forallx : X, P x
exact (funhx => h (j x) (x; idpath)).
H: Funext X, Y: Type P: X -> Type j: X -> Y
(fun (g : forallx : X, P x) (y : Y) =>
(funw : hfiber j y => g w.1) : (P |> j) y)
o (fun (h : forally : Y, (P |> j) y) (x : X) =>
h (j x) (x; 1)) == idmap
H: Funext X, Y: Type P: X -> Type j: X -> Y h: forally : Y, (P |> j) y
(fun (y : Y) (w : hfiber j y) => h (j w.1) (w.1; 1)) =
h
by funext y [x []].
H: Funext X, Y: Type P: X -> Type j: X -> Y
(fun (h : forally : Y, (P |> j) y) (x : X) =>
h (j x) (x; 1))
o (fun (g : forallx : X, P x) (y : Y) =>
(funw : hfiber j y => g w.1) : (P |> j) y) ==
idmap
H: Funext X, Y: Type P: X -> Type j: X -> Y g: forallx : X, P x
(funx : X => g (x; 1).1) = g
byapply path_forall.Defined.(** Here we are taking the perspective of a type family [P : X -> Type] as an oo-presheaf, considering the interpretation of [X] as an oo-groupoid and [Type] as a universe of spaces i.e. an appropriate generalization of the category of sets. It is easy to see that a type family [P] is functorial if we define its action on paths with [transport]. Functoriality then reduces to known lemmas about the [transport] function. *)(** With this in mind, we define the type of transformations between two type families. [concat_Ap] says that these transformations are automatically natural. *)DefinitionMapFam {X : Type} (P : X -> Type) (R : X -> Type)
:= forallx, P x -> R x.Notation"P >=> R" := (MapFam P R) : function_scope.(** Composition of transformations. *)Definitioncompose_mapfam {X} {PRQ : X -> Type} (b : R >=> Q) (a : P >=> R)
: P >=> Q
:= funx => (b x) o (a x).(** If [j] is an embedding then [(P <| j) =< (P |> j)]. *)
X, Y: Type P: X -> Type j: X -> Y isem: IsEmbedding j
P <| j >=> P |> j
X, Y: Type P: X -> Type j: X -> Y isem: IsEmbedding j
P <| j >=> P |> j
X, Y: Type P: X -> Type j: X -> Y isem: IsEmbedding j y: Y w': hfiber j y z: P w'.1 w: hfiber j y
P w.1
X, Y: Type P: X -> Type j: X -> Y isem: IsEmbedding j y: Y w': hfiber j y z: P w'.1 w: hfiber j y
w' = w
srapply path_ishprop.Defined.(** Under this interpretation, we can think of the maps [P <| j] and [P |> j] as left and right Kan extensions of [P : X -> Type] along [j : X -> Y]. To see this we can construct the (co)unit transformations of our extensions. *)Definitionunit_leftkanfam {XY : Type} (P : X -> Type) (j : X -> Y)
: P >=> ((P <| j) o j)
:= funxA => ((x; idpath); A).Definitioncounit_rightkanfam {XY : Type} (P : X -> Type) (j : X -> Y)
: ((P |> j) o j) >=> P
:= funxA => A (x; idpath).
X, Y: Type R: Y -> Type j: X -> Y
(R o j) <| j >=> R
X, Y: Type R: Y -> Type j: X -> Y
(R o j) <| j >=> R
X, Y: Type R: Y -> Type j: X -> Y y: Y x: X p: j x = y C: R (j (x; p).1)
R y
exact (transport R p C).Defined.
X, Y: Type R: Y -> Type j: X -> Y
R >=> (R o j) |> j
X, Y: Type R: Y -> Type j: X -> Y
R >=> (R o j) |> j
X, Y: Type R: Y -> Type j: X -> Y y: Y C: R y x: X p: j x = y
R (j (x; p).1)
exact (transport R p^ C).Defined.(** Universal property of the Kan extensions. *)
X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j
{b : P <| j >=> R &
compose_mapfam (b o j) (unit_leftkanfam P j) == a}
X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j
{b : P <| j >=> R &
compose_mapfam (b o j) (unit_leftkanfam P j) == a}
X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j
P <| j >=> R
X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j
(funb : P <| j >=> R =>
compose_mapfam (b o j) (unit_leftkanfam P j) == a)
?proj1
X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j
P <| j >=> R
X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j y: Y x: X p: j x = y A: P (x; p).1
R y
exact (p # a x A).
X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j
(funb : P <| j >=> R =>
compose_mapfam (b o j) (unit_leftkanfam P j) == a)
((fun (y : Y) (X0 : (P <| j) y) =>
(funproj1 : hfiber j y =>
(fun (x : X) (p : j x = y) (A : P (x; p).1) =>
transport R p (a x A)) proj1.1 proj1.2) X0.1
X0.2)
:
P <| j >=> R)
X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j x: X
compose_mapfam
(fun (x : X) (X0 : (P <| j) (j x)) =>
transport R (X0.1).2 (a (X0.1).1 X0.2))
(unit_leftkanfam P j) x = a x
reflexivity.Defined.
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j
Contr
{b : P <| j >=> R &
compose_mapfam (b o j) (unit_leftkanfam P j) == a}
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j
Contr
{b : P <| j >=> R &
compose_mapfam (b o j) (unit_leftkanfam P j) == a}
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j
forally : {b : P <| j >=> R &
compose_mapfam (funx : X => b (j x))
(unit_leftkanfam P j) == a},
univ_property_leftkanfam a = y
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j b: P <| j >=> R F: compose_mapfam (funx : X => b (j x))
(unit_leftkanfam P j) == a
univ_property_leftkanfam a = (b; F)
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j b: P <| j >=> R F: compose_mapfam (funx : X => b (j x))
(unit_leftkanfam P j) == a
(b; F) = univ_property_leftkanfam a
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j b: P <| j >=> R F: compose_mapfam (funx : X => b (j x))
(unit_leftkanfam P j) == a
(b; F).1 = (univ_property_leftkanfam a).1
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j b: P <| j >=> R F: compose_mapfam (funx : X => b (j x))
(unit_leftkanfam P j) == a
transport
(funb : P <| j >=> R =>
compose_mapfam (funx : X => b (j x))
(unit_leftkanfam P j) == a) ?p (b; F).2 =
(univ_property_leftkanfam a).2
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j b: P <| j >=> R F: compose_mapfam (funx : X => b (j x))
(unit_leftkanfam P j) == a
(b; F).1 = (univ_property_leftkanfam a).1
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j b: P <| j >=> R F: compose_mapfam (funx : X => b (j x))
(unit_leftkanfam P j) == a y: Y
(b; F).1 y = (univ_property_leftkanfam a).1 y
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j b: P <| j >=> R F: compose_mapfam (funx : X => b (j x))
(unit_leftkanfam P j) == a y: Y w: X c: P (w; 1).1
(b; F).1 (j w) ((w; 1); c) =
(univ_property_leftkanfam a).1 (j w) ((w; 1); c)
srefine (ap10 (F w) c).
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j b: P <| j >=> R F: compose_mapfam (funx : X => b (j x))
(unit_leftkanfam P j) == a
transport
(funb : P <| j >=> R =>
compose_mapfam (funx : X => b (j x))
(unit_leftkanfam P j) == a)
(path_forall (b; F).1 (univ_property_leftkanfam a).1
((funy : Y =>
path_forall ((b; F).1 y)
((univ_property_leftkanfam a).1 y)
((funx : (P <| j) y =>
(funproj1 : hfiber j y =>
(fun (w : X) (proj2 : j w = y) =>
match
proj2 as p in (_ = y0)
return
(forallproj3 : P ....1,
....1 y0 ... = ....1 y0 ...)
with
| 1 => func : P (w; 1).1 => ap10 (F w) c
end) proj1.1 proj1.2) x.1 x.2)
:
(b; F).1 y ==
(univ_property_leftkanfam a).1 y))
:
(b; F).1 == (univ_property_leftkanfam a).1))
(b; F).2 = (univ_property_leftkanfam a).2
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j b: P <| j >=> R F: compose_mapfam (funx : X => b (j x))
(unit_leftkanfam P j) == a
transport
(funb : P <| j >=> R =>
compose_mapfam (funx : X => b (j x))
(unit_leftkanfam P j) == a)
(path_forall b
(fun (y : Y) (X0 : (P <| j) y) =>
transport R (X0.1).2 (a (X0.1).1 X0.2))
(funy : Y =>
path_forall (b y)
(funX0 : (P <| j) y =>
transport R (X0.1).2 (a (X0.1).1 X0.2))
(funx : (P <| j) y =>
match
(x.1).2as p in (_ = y0)
return
(forallproj2 : P (x.1).1,
b y0 (((x.1).1; p); proj2) =
transport R p (a (x.1).1 proj2))
with
| 1 =>
func : P (x.1).1 => ap10 (F (x.1).1) c
end x.2))) F = (funx : X => 1)
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j b: P <| j >=> R F: compose_mapfam (funx : X => b (j x))
(unit_leftkanfam P j) == a x: X
transport
(funb : P <| j >=> R =>
compose_mapfam (funx : X => b (j x))
(unit_leftkanfam P j) == a)
(path_forall b
(fun (y : Y) (X0 : (P <| j) y) =>
transport R (X0.1).2 (a (X0.1).1 X0.2))
(funy : Y =>
path_forall (b y)
(funX0 : (P <| j) y =>
transport R (X0.1).2 (a (X0.1).1 X0.2))
(funx : (P <| j) y =>
match
(x.1).2as p in (_ = y0)
return
(forallproj2 : P (x.1).1,
b y0 (((x.1).1; p); proj2) =
transport R p (a (x.1).1 proj2))
with
| 1 =>
func : P (x.1).1 => ap10 (F (x.1).1) c
end x.2))) F x = 1
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j b: P <| j >=> R F: compose_mapfam (funx : X => b (j x))
(unit_leftkanfam P j) == a x: X
transport
(funx0 : P <| j >=> R =>
compose_mapfam (funx : X => x0 (j x))
(unit_leftkanfam P j) x = a x)
(path_forall b
(fun (y : Y) (X0 : (P <| j) y) =>
transport R (X0.1).2 (a (X0.1).1 X0.2))
(funy : Y =>
path_forall (b y)
(funX0 : (P <| j) y =>
transport R (X0.1).2 (a (X0.1).1 X0.2))
(funx : (P <| j) y =>
match
(x.1).2as p in (_ = y0)
return
(forallproj2 : P (x.1).1,
b y0 (((x.1).1; p); proj2) =
transport R p (a (x.1).1 proj2))
with
| 1 =>
func : P (x.1).1 => ap10 (F (x.1).1) c
end x.2))) (F x) = 1
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j b: P <| j >=> R F: compose_mapfam (funx : X => b (j x))
(unit_leftkanfam P j) == a x: X
(ap
(funx0 : P <| j >=> R =>
compose_mapfam (funx : X => x0 (j x))
(unit_leftkanfam P j) x)
(path_forall b
(fun (y : Y) (X0 : (P <| j) y) =>
transport R (X0.1).2 (a (X0.1).1 X0.2))
(funy : Y =>
path_forall (b y)
(funX0 : (P <| j) y =>
transport R (X0.1).2 (a (X0.1).1 X0.2))
(funx : (P <| j) y =>
match
(x.1).2as p in (_ = y0)
return
(forallproj2 : P (x.1).1,
b y0 (((x.1).1; p); proj2) =
transport R p (a (x.1).1 proj2))
with
| 1 =>
func : P (x.1).1 => ap10 (F (x.1).1) c
end x.2))))^ @ F x = 1
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j b: P <| j >=> R F: compose_mapfam (funx : X => b (j x))
(unit_leftkanfam P j) == a x: X
F x =
ap
(funx0 : P <| j >=> R =>
compose_mapfam (funx : X => x0 (j x))
(unit_leftkanfam P j) x)
(path_forall b
(fun (y : Y) (X0 : (P <| j) y) =>
transport R (X0.1).2 (a (X0.1).1 X0.2))
(funy : Y =>
path_forall (b y)
(funX0 : (P <| j) y =>
transport R (X0.1).2 (a (X0.1).1 X0.2))
(funx : (P <| j) y =>
match
(x.1).2as p in (_ = y0)
return
(forallproj2 : P (x.1).1,
b y0 (((x.1).1; p); proj2) =
transport R p (a (x.1).1 proj2))
with
| 1 =>
func : P (x.1).1 => ap10 (F (x.1).1) c
end x.2))) @ 1
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j b: P <| j >=> R F: compose_mapfam (funx : X => b (j x))
(unit_leftkanfam P j) == a x: X
F x =
ap
(funx0 : P <| j >=> R =>
compose_mapfam (funx : X => x0 (j x))
(unit_leftkanfam P j) x)
(path_forall b
(fun (y : Y) (X0 : (P <| j) y) =>
transport R (X0.1).2 (a (X0.1).1 X0.2))
(funy : Y =>
path_forall (b y)
(funX0 : (P <| j) y =>
transport R (X0.1).2 (a (X0.1).1 X0.2))
(funx : (P <| j) y =>
match
(x.1).2as p in (_ = y0)
return
(forallproj2 : P (x.1).1,
b y0 (((x.1).1; p); proj2) =
transport R p (a (x.1).1 proj2))
with
| 1 =>
func : P (x.1).1 => ap10 (F (x.1).1) c
end x.2)))
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j b: P <| j >=> R F: compose_mapfam (funx : X => b (j x))
(unit_leftkanfam P j) == a x: X
F x =
ap
(fun (x0 : P <| j >=> R) (x1 : P x) =>
x0 (j x) ((x; 1); x1))
(path_forall b
(fun (y : Y) (X0 : (P <| j) y) =>
transport R (X0.1).2 (a (X0.1).1 X0.2))
(funy : Y =>
path_forall (b y)
(funX0 : (P <| j) y =>
transport R (X0.1).2 (a (X0.1).1 X0.2))
(funx : (P <| j) y =>
match
(x.1).2as p in (_ = y0)
return
(forallproj2 : P (x.1).1,
b y0 (((x.1).1; p); proj2) =
transport R p (a (x.1).1 proj2))
with
| 1 =>
func : P (x.1).1 => ap10 (F (x.1).1) c
end x.2)))
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j b: P <| j >=> R F: compose_mapfam (funx : X => b (j x))
(unit_leftkanfam P j) == a x: X
ap
(fun (x0 : P <| j >=> R) (x1 : P x) =>
x0 (j x) ((x; 1); x1))
(path_forall b
(fun (y : Y) (X0 : (P <| j) y) =>
transport R (X0.1).2 (a (X0.1).1 X0.2))
(funy : Y =>
path_forall (b y)
(funX0 : (P <| j) y =>
transport R (X0.1).2 (a (X0.1).1 X0.2))
(funx : (P <| j) y =>
match
(x.1).2as p in (_ = y0)
return
(forallproj2 : P (x.1).1,
b y0 (((x.1).1; p); proj2) =
transport R p (a (x.1).1 proj2))
with
| 1 =>
func : P (x.1).1 => ap10 (F (x.1).1) c
end x.2))) = F x
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j b: P <| j >=> R F: compose_mapfam (funx : X => b (j x))
(unit_leftkanfam P j) == a x: X i:= funpx : P x => ((x; 1); px) : (P <| j) (j x): P x -> (P <| j) (j x)
ap
(fun (x0 : P <| j >=> R) (x1 : P x) =>
x0 (j x) ((x; 1); x1))
(path_forall b
(fun (y : Y) (X0 : (P <| j) y) =>
transport R (X0.1).2 (a (X0.1).1 X0.2))
(funy : Y =>
path_forall (b y)
(funX0 : (P <| j) y =>
transport R (X0.1).2 (a (X0.1).1 X0.2))
(funx : (P <| j) y =>
match
(x.1).2as p in (_ = y0)
return
(forallproj2 : P (x.1).1,
b y0 (((x.1).1; p); proj2) =
transport R p (a (x.1).1 proj2))
with
| 1 =>
func : P (x.1).1 => ap10 (F (x.1).1) c
end x.2))) = F x
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j b: P <| j >=> R F: compose_mapfam (funx : X => b (j x))
(unit_leftkanfam P j) == a x: X i:= funpx : P x => ((x; 1); px) : (P <| j) (j x): P x -> (P <| j) (j x)
ap
(fun (ka : (P <| j) (j x) -> R (j x)) (x : P x) =>
ka (i x))
(ap (funk : P <| j >=> R => k (j x))
(path_forall b
(fun (y : Y) (X0 : (P <| j) y) =>
transport R (X0.1).2 (a (X0.1).1 X0.2))
(funy : Y =>
path_forall (b y)
(funX0 : (P <| j) y =>
transport R (X0.1).2 (a (X0.1).1 X0.2))
(funx : (P <| j) y =>
match
(x.1).2as p in (_ = y0)
return
(forallproj2 : P (x.1).1,
b y0 (((x.1).1; p); proj2) =
transport R p (a (x.1).1 proj2))
with
| 1 =>
func : P (x.1).1 =>
ap10 (F (x.1).1) c
end x.2)))) = F x
(* [ap (fun k => k (j x))] is exactly [apD10], so it cancels the first [path_forall]. *)
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j b: P <| j >=> R F: compose_mapfam (funx : X => b (j x))
(unit_leftkanfam P j) == a x: X i:= funpx : P x => ((x; 1); px) : (P <| j) (j x): P x -> (P <| j) (j x)
ap
(fun (ka : (P <| j) (j x) -> R (j x)) (x : P x) =>
ka (i x))
(path_forall (b (j x))
(funX0 : (P <| j) (j x) =>
transport R (X0.1).2 (a (X0.1).1 X0.2))
(funx : (P <| j) (j x) =>
match
(x.1).2as p in (_ = y)
return
(forallproj2 : P (x.1).1,
b y (((x.1).1; p); proj2) =
transport R p (a (x.1).1 proj2))
with
| 1 => func : P (x.1).1 => ap10 (F (x.1).1) c
end x.2)) = F x
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j b: P <| j >=> R F: compose_mapfam (funx : X => b (j x))
(unit_leftkanfam P j) == a x: X i:= funpx : P x => ((x; 1); px) : (P <| j) (j x): P x -> (P <| j) (j x)
path_arrow (funx0 : P x => b (j x) (i x0))
(funx0 : P x =>
transport R ((i x0).1).2 (a ((i x0).1).1 (i x0).2))
(funx0 : P x =>
ap10
(path_forall (b (j x))
(funX0 : (P <| j) (j x) =>
transport R (X0.1).2 (a (X0.1).1 X0.2))
(funx : (P <| j) (j x) =>
match
(x.1).2as p in (_ = y)
return
(forallproj2 : P (x.1).1,
b y (((x.1).1; p); proj2) =
transport R p (a (x.1).1 proj2))
with
| 1 =>
func : P (x.1).1 => ap10 (F (x.1).1) c
end x.2)) (i x0)) = F x
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j b: P <| j >=> R F: compose_mapfam (funx : X => b (j x))
(unit_leftkanfam P j) == a x: X i:= funpx : P x => ((x; 1); px) : (P <| j) (j x): P x -> (P <| j) (j x)
path_arrow (funx0 : P x => b (j x) (i x0))
(funx0 : P x =>
transport R ((i x0).1).2 (a ((i x0).1).1 (i x0).2))
(funx0 : P x =>
apD10
(apD10^-1
(funx : (P <| j) (j x) =>
match
(x.1).2as p in (_ = y)
return
(forallproj2 : P (x.1).1,
b y (((x.1).1; p); proj2) =
transport R p (a (x.1).1 proj2))
with
| 1 =>
func : P (x.1).1 => apD10 (F (x.1).1) c
end x.2)) (i x0)) = F x
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: P >=> R o j b: P <| j >=> R F: compose_mapfam (funx : X => b (j x))
(unit_leftkanfam P j) == a x: X i:= funpx : P x => ((x; 1); px) : (P <| j) (j x): P x -> (P <| j) (j x)
path_arrow (funx0 : P x => b (j x) (i x0))
(funx0 : P x => a x x0)
(funx0 : P x => apD10 (F x) x0) = F x
apply eissect.Defined.
X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P
{b : R >=> P |> j &
compose_mapfam (counit_rightkanfam P j) (b o j) == a}
X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P
{b : R >=> P |> j &
compose_mapfam (counit_rightkanfam P j) (b o j) == a}
X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P
R >=> P |> j
X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P
(funb : R >=> P |> j =>
compose_mapfam (counit_rightkanfam P j) (b o j) == a)
?proj1
X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P
R >=> P |> j
X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P y: Y A: R y x: X p: j x = y
P (x; p).1
exact (a x (p^ # A)).
X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P
(funb : R >=> P |> j =>
compose_mapfam (counit_rightkanfam P j) (b o j) == a)
((fun (y : Y) (A : R y) =>
(funw : hfiber j y =>
(fun (x : X) (p : j x = y) =>
a x (transport R p^ A)) w.1 w.2)
:
(P |> j) y)
:
R >=> P |> j)
X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P x: X
compose_mapfam (counit_rightkanfam P j)
(fun (x : X) (A : R (j x)) (w : hfiber j (j x)) =>
a w.1 (transport R (w.2)^ A)) x = a x
reflexivity.Defined.
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P
Contr
{b : R >=> P |> j &
compose_mapfam (counit_rightkanfam P j) (b o j) == a}
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P
Contr
{b : R >=> P |> j &
compose_mapfam (counit_rightkanfam P j) (b o j) == a}
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P
forally : {b : R >=> P |> j &
compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a},
univ_property_rightkanfam a = y
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P b: R >=> P |> j F: compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a
univ_property_rightkanfam a = (b; F)
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P b: R >=> P |> j F: compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a
(b; F) = univ_property_rightkanfam a
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P b: R >=> P |> j F: compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a
(b; F).1 = (univ_property_rightkanfam a).1
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P b: R >=> P |> j F: compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a
transport
(funb : R >=> P |> j =>
compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a) ?p (b; F).2 =
(univ_property_rightkanfam a).2
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P b: R >=> P |> j F: compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a
(b; F).1 = (univ_property_rightkanfam a).1
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P b: R >=> P |> j F: compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a y: Y
(b; F).1 y = (univ_property_rightkanfam a).1 y
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P b: R >=> P |> j F: compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a y: Y C: R y
(b; F).1 y C = (univ_property_rightkanfam a).1 y C
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P b: R >=> P |> j F: compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a y: Y C: R y x: X p: j x = y
(b; F).1 y C (x; p) =
(univ_property_rightkanfam a).1 y C (x; p)
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P b: R >=> P |> j F: compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a x: X C: R (j x)
(b; F).1 (j x) C (x; 1) =
(univ_property_rightkanfam a).1 (j x) C (x; 1)
srefine (ap10 (F x) C).
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P b: R >=> P |> j F: compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a
transport
(funb : R >=> P |> j =>
compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a)
(path_forall (b; F).1
(univ_property_rightkanfam a).1
((funy : Y =>
path_forall ((b; F).1 y)
((univ_property_rightkanfam a).1 y)
((funC : R y =>
path_forall ((b; F).1 y C)
((univ_property_rightkanfam a).1 y C)
((funx0 : hfiber j y =>
(fun (x : X) (p : j x = y) =>
match
p as p0 in (...) return (...)
with
| 1 => funC0 : ... => ap10 (...) C0
end C) x0.1 x0.2)
:
(b; F).1 y C ==
(univ_property_rightkanfam a).1 y C))
:
(b; F).1 y ==
(univ_property_rightkanfam a).1 y))
:
(b; F).1 == (univ_property_rightkanfam a).1))
(b; F).2 = (univ_property_rightkanfam a).2
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P b: R >=> P |> j F: compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a
transport
(funb : R >=> P |> j =>
compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a)
(path_forall b
(fun (y : Y) (A : R y) (w : hfiber j y) =>
a w.1 (transport R (w.2)^ A))
(funy : Y =>
path_forall (b y)
(fun (A : R y) (w : hfiber j y) =>
a w.1 (transport R (w.2)^ A))
(funC : R y =>
path_forall (b y C)
(funw : hfiber j y =>
a w.1 (transport R (w.2)^ C))
(funx0 : hfiber j y =>
match
x0.2as p in (_ = y0)
return
(forallC0 : R y0,
b y0 C0 (x0.1; p) =
a x0.1 (transport R p^ C0))
with
| 1 =>
funC0 : R (j x0.1) =>
ap10 (F x0.1) C0
end C)))) F = (funx : X => 1)
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P b: R >=> P |> j F: compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a x: X
transport
(funb : R >=> P |> j =>
compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a)
(path_forall b
(fun (y : Y) (A : R y) (w : hfiber j y) =>
a w.1 (transport R (w.2)^ A))
(funy : Y =>
path_forall (b y)
(fun (A : R y) (w : hfiber j y) =>
a w.1 (transport R (w.2)^ A))
(funC : R y =>
path_forall (b y C)
(funw : hfiber j y =>
a w.1 (transport R (w.2)^ C))
(funx0 : hfiber j y =>
match
x0.2as p in (_ = y0)
return
(forallC0 : R y0,
b y0 C0 (x0.1; p) =
a x0.1 (transport R p^ C0))
with
| 1 =>
funC0 : R (j x0.1) =>
ap10 (F x0.1) C0
end C)))) F x = 1
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P b: R >=> P |> j F: compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a x: X
transport
(funx0 : R >=> P |> j =>
compose_mapfam (counit_rightkanfam P j)
(funx : X => x0 (j x)) x = a x)
(path_forall b
(fun (y : Y) (A : R y) (w : hfiber j y) =>
a w.1 (transport R (w.2)^ A))
(funy : Y =>
path_forall (b y)
(fun (A : R y) (w : hfiber j y) =>
a w.1 (transport R (w.2)^ A))
(funC : R y =>
path_forall (b y C)
(funw : hfiber j y =>
a w.1 (transport R (w.2)^ C))
(funx0 : hfiber j y =>
match
x0.2as p in (_ = y0)
return
(forallC0 : R y0,
b y0 C0 (x0.1; p) =
a x0.1 (transport R p^ C0))
with
| 1 =>
funC0 : R (j x0.1) =>
ap10 (F x0.1) C0
end C)))) (F x) = 1
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P b: R >=> P |> j F: compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a x: X
(ap
(funx0 : R >=> P |> j =>
compose_mapfam (counit_rightkanfam P j)
(funx : X => x0 (j x)) x)
(path_forall b
(fun (y : Y) (A : R y) (w : hfiber j y) =>
a w.1 (transport R (w.2)^ A))
(funy : Y =>
path_forall (b y)
(fun (A : R y) (w : hfiber j y) =>
a w.1 (transport R (w.2)^ A))
(funC : R y =>
path_forall (b y C)
(funw : hfiber j y =>
a w.1 (transport R (w.2)^ C))
(funx0 : hfiber j y =>
match
x0.2as p in (_ = y0)
return
(forallC0 : R y0,
b y0 C0 (x0.1; p) =
a x0.1 (transport R p^ C0))
with
| 1 =>
funC0 : R (j x0.1) =>
ap10 (F x0.1) C0
end C)))))^ @ F x = 1
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P b: R >=> P |> j F: compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a x: X
F x =
ap
(funx0 : R >=> P |> j =>
compose_mapfam (counit_rightkanfam P j)
(funx : X => x0 (j x)) x)
(path_forall b
(fun (y : Y) (A : R y) (w : hfiber j y) =>
a w.1 (transport R (w.2)^ A))
(funy : Y =>
path_forall (b y)
(fun (A : R y) (w : hfiber j y) =>
a w.1 (transport R (w.2)^ A))
(funC : R y =>
path_forall (b y C)
(funw : hfiber j y =>
a w.1 (transport R (w.2)^ C))
(funx0 : hfiber j y =>
match
x0.2as p in (_ = y0)
return
(forallC0 : R y0,
b y0 C0 (x0.1; p) =
a x0.1 (transport R p^ C0))
with
| 1 =>
funC0 : R (j x0.1) =>
ap10 (F x0.1) C0
end C)))) @ 1
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P b: R >=> P |> j F: compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a x: X
ap
(funx0 : R >=> P |> j =>
compose_mapfam (counit_rightkanfam P j)
(funx : X => x0 (j x)) x)
(path_forall b
(fun (y : Y) (A : R y) (w : hfiber j y) =>
a w.1 (transport R (w.2)^ A))
(funy : Y =>
path_forall (b y)
(fun (A : R y) (w : hfiber j y) =>
a w.1 (transport R (w.2)^ A))
(funC : R y =>
path_forall (b y C)
(funw : hfiber j y =>
a w.1 (transport R (w.2)^ C))
(funx0 : hfiber j y =>
match
x0.2as p in (_ = y0)
return
(forallC0 : R y0,
b y0 C0 (x0.1; p) =
a x0.1 (transport R p^ C0))
with
| 1 =>
funC0 : R (j x0.1) =>
ap10 (F x0.1) C0
end C)))) @ 1 = F x
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P b: R >=> P |> j F: compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a x: X
ap
(funx0 : R >=> P |> j =>
compose_mapfam (counit_rightkanfam P j)
(funx : X => x0 (j x)) x)
(path_forall b
(fun (y : Y) (A : R y) (w : hfiber j y) =>
a w.1 (transport R (w.2)^ A))
(funy : Y =>
path_forall (b y)
(fun (A : R y) (w : hfiber j y) =>
a w.1 (transport R (w.2)^ A))
(funC : R y =>
path_forall (b y C)
(funw : hfiber j y =>
a w.1 (transport R (w.2)^ C))
(funx0 : hfiber j y =>
match
x0.2as p in (_ = y0)
return
(forallC0 : R y0,
b y0 C0 (x0.1; p) =
a x0.1 (transport R p^ C0))
with
| 1 =>
funC0 : R (j x0.1) =>
ap10 (F x0.1) C0
end C)))) = F x
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P b: R >=> P |> j F: compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a x: X
ap
(fun (x0 : R >=> P |> j) (x1 : R (j x)) =>
counit_rightkanfam P j x (x0 (j x) x1))
(path_forall b
(fun (y : Y) (A : R y) (w : hfiber j y) =>
a w.1 (transport R (w.2)^ A))
(funy : Y =>
path_forall (b y)
(fun (A : R y) (w : hfiber j y) =>
a w.1 (transport R (w.2)^ A))
(funC : R y =>
path_forall (b y C)
(funw : hfiber j y =>
a w.1 (transport R (w.2)^ C))
(funx0 : hfiber j y =>
match
x0.2as p in (_ = y0)
return
(forallC0 : R y0,
b y0 C0 (x0.1; p) =
a x0.1 (transport R p^ C0))
with
| 1 =>
funC0 : R (j x0.1) =>
ap10 (F x0.1) C0
end C)))) = F x
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P b: R >=> P |> j F: compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a x: X
ap
(fun (ka : R (j x) -> (P |> j) (j x)) (x0 : R (j x))
=> counit_rightkanfam P j x (ka x0))
(ap (funk : R >=> P |> j => k (j x))
(path_forall b
(fun (y : Y) (A : R y) (w : hfiber j y) =>
a w.1 (transport R (w.2)^ A))
(funy : Y =>
path_forall (b y)
(fun (A : R y) (w : hfiber j y) =>
a w.1 (transport R (w.2)^ A))
(funC : R y =>
path_forall (b y C)
(funw : hfiber j y =>
a w.1 (transport R (w.2)^ C))
(funx0 : hfiber j y =>
match
x0.2as p in (_ = y0)
return
(forallC0 : R y0,
b y0 C0 (x0.1; p) =
a x0.1 (transport R p^ C0))
with
| 1 =>
funC0 : R (j x0.1) =>
ap10 (F x0.1) C0
end C))))) = F x
(* [ap (fun k => k (j x))] is exactly [apD10], so it cancels the first [path_forall]. *)
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P b: R >=> P |> j F: compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a x: X
ap
(fun (ka : R (j x) -> (P |> j) (j x)) (x0 : R (j x))
=> counit_rightkanfam P j x (ka x0))
(path_forall (b (j x))
(fun (A : R (j x)) (w : hfiber j (j x)) =>
a w.1 (transport R (w.2)^ A))
(funC : R (j x) =>
path_forall (b (j x) C)
(funw : hfiber j (j x) =>
a w.1 (transport R (w.2)^ C))
(funx0 : hfiber j (j x) =>
match
x0.2as p in (_ = y)
return
(forallC0 : R y,
b y C0 (x0.1; p) =
a x0.1 (transport R p^ C0))
with
| 1 =>
funC0 : R (j x0.1) => ap10 (F x0.1) C0
end C))) = F x
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P b: R >=> P |> j F: compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a x: X
path_arrow
(funx0 : R (j x) =>
counit_rightkanfam P j x (b (j x) x0))
(funx0 : R (j x) =>
counit_rightkanfam P j x
(funw : hfiber j (j x) =>
a w.1 (transport R (w.2)^ x0)))
(funq : R (j x) =>
ap (counit_rightkanfam P j x)
(ap10
(path_forall (b (j x))
(fun (A : R (j x)) (w : hfiber j (j x)) =>
a w.1 (transport R (w.2)^ A))
(funC : R (j x) =>
path_forall (b (j x) C)
(funw : hfiber j (j x) =>
a w.1 (transport R (w.2)^ C))
(funx0 : hfiber j (j x) =>
match
x0.2as p in (_ = y)
return
(forallC0 : R y,
b y C0 (x0.1; p) =
a x0.1 (transport R p^ C0))
with
| 1 =>
funC0 : R (j x0.1) =>
ap10 (F x0.1) C0
end C))) q)) = F x
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P b: R >=> P |> j F: compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a x: X
path_arrow
(funx0 : R (j x) =>
counit_rightkanfam P j x (b (j x) x0))
(funx0 : R (j x) =>
counit_rightkanfam P j x
(funw : hfiber j (j x) =>
a w.1 (transport R (w.2)^ x0)))
(funq : R (j x) =>
ap (counit_rightkanfam P j x)
(apD10
(apD10^-1
(funC : R (j x) =>
apD10^-1
(funx0 : hfiber j (j x) =>
match
x0.2as p in (_ = y)
return
(forallC0 : R y,
b y C0 (x0.1; p) =
a x0.1 (transport R p^ C0))
with
| 1 =>
funC0 : R (j x0.1) =>
apD10 (F x0.1) C0
end C))) q)) = F x
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P b: R >=> P |> j F: compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a x: X
path_arrow
(funx0 : R (j x) =>
counit_rightkanfam P j x (b (j x) x0))
(funx0 : R (j x) =>
counit_rightkanfam P j x
(funw : hfiber j (j x) =>
a w.1 (transport R (w.2)^ x0)))
(funq : R (j x) =>
ap (counit_rightkanfam P j x)
(apD10^-1
(funx0 : hfiber j (j x) =>
match
x0.2as p in (_ = y)
return
(forallC : R y,
b y C (x0.1; p) =
a x0.1 (transport R p^ C))
with
| 1 => funC : R (j x0.1) => apD10 (F x0.1) C
end q))) = F x
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P b: R >=> P |> j F: compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a x: X
path_arrow
(funx0 : R (j x) =>
counit_rightkanfam P j x (b (j x) x0))
(funx0 : R (j x) =>
counit_rightkanfam P j x
(funw : hfiber j (j x) =>
a w.1 (transport R (w.2)^ x0)))
(funq : R (j x) =>
apD10
(apD10^-1
(funx0 : hfiber j (j x) =>
match
x0.2as p in (_ = y)
return
(forallC : R y,
b y C (x0.1; p) =
a x0.1 (transport R p^ C))
with
| 1 => funC : R (j x0.1) => apD10 (F x0.1) C
end q)) (x; 1)) = F x
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P b: R >=> P |> j F: compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a x: X
(funq : R (j x) =>
apD10
(apD10^-1
(funx0 : hfiber j (j x) =>
match
x0.2as p in (_ = y)
return
(forallC : R y,
b y C (x0.1; p) =
a x0.1 (transport R p^ C))
with
| 1 => funC : R (j x0.1) => apD10 (F x0.1) C
end q)) (x; 1)) = apD10 (F x)
H: Funext X, Y: Type j: X -> Y P: X -> Type R: Y -> Type a: R o j >=> P b: R >=> P |> j F: compose_mapfam (counit_rightkanfam P j)
(funx : X => b (j x)) == a x: X r: R (j x)
apD10
(apD10^-1
(funx0 : hfiber j (j x) =>
match
x0.2as p in (_ = y)
return
(forallC : R y,
b y C (x0.1; p) = a x0.1 (transport R p^ C))
with
| 1 => funC : R (j x0.1) => apD10 (F x0.1) C
end r)) (x; 1) = apD10 (F x) r
exact (apD10_path_forall _ _ _ (x; _)).Defined.(** The above (co)unit constructions are special cases of the following, which tells us that these extensions are adjoint to restriction by [j] *)
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y
P <| j >=> R <~> P >=> R o j
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y
P <| j >=> R <~> P >=> R o j
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y
P <| j >=> R -> P >=> R o j
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y
P >=> R o j -> P <| j >=> R
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y
?f o ?g == idmap
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y
?g o ?f == idmap
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y
P <| j >=> R -> P >=> R o j
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y a: P <| j >=> R x: X B: P x
R (j x)
exact (a (j x) ((x; idpath); B)).
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y
P >=> R o j -> P <| j >=> R
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y b: P >=> R o j y: Y x: X p: j x = y C: P (x; p).1
R y
exact (p # (b x C)).
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y
(funa : P <| j >=> R =>
(fun (x : X) (B : P x) => a (j x) ((x; 1); B))
:
P >=> R o j)
o (funb : P >=> R o j =>
(fun (y : Y) (X0 : (P <| j) y) =>
(funproj1 : hfiber j y =>
(fun (x : X) (p : j x = y) (C : P (x; p).1) =>
transport R p (b x C)) proj1.1 proj1.2) X0.1
X0.2)
:
P <| j >=> R) == idmap
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y b: P >=> (funx : X => R (j x))
(fun (x : X) (B : P x) => transport R 1 (b x B)) = b
by funext x C.
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y
(funb : P >=> R o j =>
(fun (y : Y) (X0 : (P <| j) y) =>
(funproj1 : hfiber j y =>
(fun (x : X) (p : j x = y) (C : P (x; p).1) =>
transport R p (b x C)) proj1.1 proj1.2) X0.1 X0.2)
:
P <| j >=> R)
o (funa : P <| j >=> R =>
(fun (x : X) (B : P x) => a (j x) ((x; 1); B))
:
P >=> R o j) == idmap
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y a: P <| j >=> R
(fun (y : Y) (X0 : (P <| j) y) =>
transport R (X0.1).2
(a (j (X0.1).1) (((X0.1).1; 1); X0.2))) = a
by funext y [[x []] C].Defined.
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y
R >=> P |> j <~> R o j >=> P
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y
R >=> P |> j <~> R o j >=> P
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y
R >=> P |> j -> R o j >=> P
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y
R o j >=> P -> R >=> P |> j
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y
?f o ?g == idmap
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y
?g o ?f == idmap
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y
R >=> P |> j -> R o j >=> P
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y a: R >=> P |> j x: X C: R (j x)
P x
exact (a (j x) C (x; idpath)).
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y
R o j >=> P -> R >=> P |> j
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y a: R o j >=> P y: Y C: R y x: X p: j x = y
P (x; p).1
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y a: R o j >=> P y: Y C: R y x: X p: j x = y
R (j x)
exact (p^ # C).
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y
(funa : R >=> P |> j =>
(fun (x : X) (C : R (j x)) => a (j x) C (x; 1))
:
R o j >=> P)
o (funa : R o j >=> P =>
(fun (y : Y) (C : R y) =>
(funw : hfiber j y =>
(fun (x : X) (p : j x = y) =>
a x (transport R p^ C)) w.1 w.2)
:
(P |> j) y)
:
R >=> P |> j) == idmap
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y a: (funx : X => R (j x)) >=> P
(fun (x : X) (C : R (j x)) => a x (transport R 1^ C)) =
a
by funext x C.
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y
(funa : R o j >=> P =>
(fun (y : Y) (C : R y) =>
(funw : hfiber j y =>
(fun (x : X) (p : j x = y) =>
a x (transport R p^ C)) w.1 w.2)
:
(P |> j) y)
:
R >=> P |> j)
o (funa : R >=> P |> j =>
(fun (x : X) (C : R (j x)) => a (j x) C (x; 1))
:
R o j >=> P) == idmap
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y b: R >=> P |> j
(fun (y : Y) (C : R y) (w : hfiber j y) =>
b (j w.1) (transport R (w.2)^ C) (w.1; 1)) = b
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y b: R >=> P |> j y: Y C: R y x: X p: j x = y
b (j x) (transport R p^ C) (x; 1) = b y C (x; p)
H: Funext X, Y: Type P: X -> Type R: Y -> Type j: X -> Y b: R >=> P |> j x: X C: R (j x)
b (j x) C (x; 1) = b (j x) C (x; 1)
reflexivity.Defined.(** This section is all set up for the proof that the left Kan extension of an embedding is an embedding of type families. *)SectionEmbedProofLeft.Context `{Univalence} {X Y : Type} (j : X -> Y) (isem : IsEmbedding j).(** The counit transformation of a type family of the form [P <| j] has each of its components an equivalence. In other words, the type family [P <| j] is the left Kan extension of its restriction along [j]. *)
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j P: X -> Type y: Y
IsEquiv (counit_leftkanfam (P <| j) j y)
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j P: X -> Type y: Y
IsEquiv (counit_leftkanfam (P <| j) j y)
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j P: X -> Type y: Y
(P <| j) y -> ((P <| j o j) <| j) y
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j P: X -> Type y: Y
counit_leftkanfam (P <| j) j y o ?g == idmap
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j P: X -> Type y: Y
?g o counit_leftkanfam (P <| j) j y == idmap
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j P: X -> Type y: Y
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j P: X -> Type y: Y
counit_leftkanfam (P <| j) j y
o (funpat : (P <| j) y =>
letx := pat inletproj1 := x.1inletC := x.2in
(letproj2 := proj1 inletx0 := proj2.1inletp := proj2.2infunC0 : P (x0; p).1 => ((x0; p); (x0; 1); C0)) C) ==
idmap
byintros [[x []] C].
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j P: X -> Type y: Y
(funpat : (P <| j) y =>
letx := pat inletproj1 := x.1inletC := x.2in
(letproj2 := proj1 inletx0 := proj2.1inletp := proj2.2infunC0 : P (x0; p).1 => ((x0; p); (x0; 1); C0)) C)
o counit_leftkanfam (P <| j) j y == idmap
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j P: X -> Type y: Y x, x': X p': j x' = j x C: P x'
((x'; p'); (x'; 1); C) = ((x; 1); (x'; p'); C)
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j P: X -> Type y: Y x, x': X C: P x'
forallx0 : x' = x,
((x'; ap j x0); (x'; 1); C) =
((x; 1); (x'; ap j x0); C)
byintros [].Defined.(** We now use the above fact to show that type families over [X] are equivalent to type families over [Y] such that the counit map is a natural isomorphism. *)
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j P: X -> Type
{R : Y -> Type &
forally : Y, IsEquiv (counit_leftkanfam R j y)}
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j P: X -> Type
{R : Y -> Type &
forally : Y, IsEquiv (counit_leftkanfam R j y)}
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j P: X -> Type
forally : Y, IsEquiv (counit_leftkanfam (P <| j) j y)
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j
IsEquiv leftkanfam_counit_equiv
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j
IsEquiv leftkanfam_counit_equiv
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j
{R : Y -> Type &
forally : Y, IsEquiv (counit_leftkanfam R j y)} ->
X -> Type
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j
leftkanfam_counit_equiv o ?g == idmap
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j
?g o leftkanfam_counit_equiv == idmap
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j
{R : Y -> Type &
forally : Y, IsEquiv (counit_leftkanfam R j y)} ->
X -> Type
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j R: Y -> Type e: forally : Y, IsEquiv (counit_leftkanfam R j y)
X -> Type
exact (R o j).
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j
leftkanfam_counit_equiv
o (funX0 : {R : Y -> Type &
forally : Y,
IsEquiv (counit_leftkanfam R j y)} =>
(fun (R : Y -> Type)
(_ : forally : Y,
IsEquiv (counit_leftkanfam R j y)) => R o j)
X0.1 X0.2) == idmap
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j R: Y -> Type e: forally : Y, IsEquiv (counit_leftkanfam R j y)
leftkanfam_counit_equiv (funx : X => R (j x)) =
(R; e)
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j R: Y -> Type e: forally : Y, IsEquiv (counit_leftkanfam R j y)
(funx : X => R (j x)) <| j = R
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j R: Y -> Type e: forally : Y, IsEquiv (counit_leftkanfam R j y) y: Y
((funx : X => R (j x)) <| j) y = R y
exact (path_universe _ (feq:=e y)).
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j
(funX0 : {R : Y -> Type &
forally : Y,
IsEquiv (counit_leftkanfam R j y)} =>
(fun (R : Y -> Type)
(_ : forally : Y,
IsEquiv (counit_leftkanfam R j y)) => R o j)
X0.1 X0.2) o leftkanfam_counit_equiv == idmap
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j P: X -> Type
(funx : X => (leftkanfam_counit_equiv P).1 (j x)) = P
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j P: X -> Type x: X
(leftkanfam_counit_equiv P).1 (j x) = P x
rapply isext_leftkanfam.Defined.(** Using these facts we can show that the map [_ <| j] is an embedding if [j] is an embedding. *)Definitionisembed_leftkanfam_ext
: IsEmbedding (funP => P <| j)
:= mapinO_compose (O:=-1) leftkanfam_counit_equiv pr1.EndEmbedProofLeft.(** Dual proof for the right Kan extension. *)SectionEmbedProofRight.Context `{Univalence} {X Y : Type} (j : X -> Y) (isem : IsEmbedding j).
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j P: X -> Type y: Y
IsEquiv (unit_rightkanfam (P |> j) j y)
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j P: X -> Type y: Y
IsEquiv (unit_rightkanfam (P |> j) j y)
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j P: X -> Type y: Y
((P |> j o j) |> j) y -> (P |> j) y
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j P: X -> Type y: Y
unit_rightkanfam (P |> j) j y o ?g == idmap
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j P: X -> Type y: Y
?g o unit_rightkanfam (P |> j) j y == idmap
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j P: X -> Type y: Y
((P |> j o j) |> j) y -> (P |> j) y
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j P: X -> Type y: Y C: ((P |> j o j) |> j) y x: X p: j x = y
P (x; p).1
exact (C (x; p) (x; idpath)).
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j P: X -> Type y: Y
unit_rightkanfam (P |> j) j y
o (funC : ((P |> j o j) |> j) y =>
(funw : hfiber j y =>
(fun (x : X) (p : j x = y) => C (x; p) (x; 1)) w.1
w.2)
:
(P |> j) y) == idmap
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j P: X -> Type y: Y C: ((funx : X => (P |> j) (j x)) |> j) y
unit_rightkanfam (P |> j) j y
(funw : hfiber j y => C (w.1; w.2) (w.1; 1)) = C
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j P: X -> Type y: Y C: ((funx : X => (P |> j) (j x)) |> j) y x: X p: j x = y
unit_rightkanfam (P |> j) j y
(funw : hfiber j y => C (w.1; w.2) (w.1; 1)) (x; p) =
C (x; p)
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j P: X -> Type x: X C: ((funx : X => (P |> j) (j x)) |> j) (j x)
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j
IsEquiv rightkanfam_unit_equiv
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j
IsEquiv rightkanfam_unit_equiv
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j
{R : Y -> Type &
forally : Y, IsEquiv (unit_rightkanfam R j y)} ->
X -> Type
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j
rightkanfam_unit_equiv o ?g == idmap
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j
?g o rightkanfam_unit_equiv == idmap
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j
{R : Y -> Type &
forally : Y, IsEquiv (unit_rightkanfam R j y)} ->
X -> Type
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j R: Y -> Type e: forally : Y, IsEquiv (unit_rightkanfam R j y)
X -> Type
exact (R o j).
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j
rightkanfam_unit_equiv
o (funX0 : {R : Y -> Type &
forally : Y,
IsEquiv (unit_rightkanfam R j y)} =>
(fun (R : Y -> Type)
(_ : forally : Y,
IsEquiv (unit_rightkanfam R j y)) => R o j)
X0.1 X0.2) == idmap
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j R: Y -> Type e: forally : Y, IsEquiv (unit_rightkanfam R j y)
rightkanfam_unit_equiv (funx : X => R (j x)) = (R; e)
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j R: Y -> Type e: forally : Y, IsEquiv (unit_rightkanfam R j y)
(funx : X => R (j x)) |> j = R
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j R: Y -> Type e: forally : Y, IsEquiv (unit_rightkanfam R j y) y: Y
((funx : X => R (j x)) |> j) y = R y
symmetry; exact (path_universe _ (feq:=e y)).
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j
(funX0 : {R : Y -> Type &
forally : Y, IsEquiv (unit_rightkanfam R j y)}
=>
(fun (R : Y -> Type)
(_ : forally : Y,
IsEquiv (unit_rightkanfam R j y)) => R o j)
X0.1 X0.2) o rightkanfam_unit_equiv == idmap
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j P: X -> Type
(funx : X => (rightkanfam_unit_equiv P).1 (j x)) = P
H: Univalence X, Y: Type j: X -> Y isem: IsEmbedding j P: X -> Type x: X
(rightkanfam_unit_equiv P).1 (j x) = P x
rapply isext_rightkanfam.Defined.(** The map [_ |> j] is an embedding if [j] is an embedding. *)Definitionisembed_rightkanfam_ext
: IsEmbedding (funP => P |> j)
:= mapinO_compose (O:=-1) rightkanfam_unit_equiv pr1.EndEmbedProofRight.