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.
[Loading ML file number_string_notation_plugin.cmxs (using legacy method) ... done]
Require Import Types.Paths Types.Prod.Require Import DPath.Declare Scope square_scope.Delimit Scope square_scope with square.Local Unset Elimination Schemes.(* Homogeneous squares *)(* x00 ----pi0---- x01 | | | | p0i ==> p1i | | | | x01-----pi1-----x11 *)(** Contents: * Definition of [PathSquare] * Degenerate [PathSquare]s as paths between paths * Flipping squares horizontally and vertically * [PathSquare] transpose * [PathSquare] inverse * [PathSquare] rotations * Edge rewriting * Concatenation * Kan fillers * natural squares from [ap]*)(** Definition of [PathSquare] *)(** [PathSquare] left right up down *)CumulativeInductivePathSquare {A} : foralla00 {a10a01a11 : A},
a00 = a10 -> a01 = a11 -> a00 = a01 -> a10 = a11 -> Type
:= sq_id : forall {x : A},
PathSquare x 1111.Arguments sq_id {A x}.Arguments PathSquare {A _ _ _ _}.Notation"1" := sq_id : square_scope.SchemePathSquare_ind := Induction for PathSquare SortType.Arguments PathSquare_ind {A} P f {_ _ _ _ _ _ _ _} _.SchemePathSquare_rec := Minimality for PathSquare SortType.Arguments PathSquare_rec {A} P f {_ _ _ _ _ _ _ _} _.(** [PathSquare_ind] is an equivalence, similar to how [paths_ind] is *)
H: Funext A: Type P: forall (a00a10a01a11 : A) (p : a00 = a10)
(p0 : a01 = a11) (p1 : a00 = a01)
(p2 : a10 = a11), PathSquare p p0 p1 p2 -> Type
IsEquiv (PathSquare_ind P)
H: Funext A: Type P: forall (a00a10a01a11 : A) (p : a00 = a10)
(p0 : a01 = a11) (p1 : a00 = a01)
(p2 : a10 = a11), PathSquare p p0 p1 p2 -> Type
IsEquiv (PathSquare_ind P)
H: Funext A: Type P: forall (a00a10a01a11 : A) (p : a00 = a10)
(p0 : a01 = a11) (p1 : a00 = a01)
(p2 : a10 = a11), PathSquare p p0 p1 p2 -> Type
(forall (a00a10a01a11 : A) (p : a00 = a10)
(p0 : a01 = a11) (p1 : a00 = a01) (p2 : a10 = a11)
(p3 : PathSquare p p0 p1 p2),
P a00 a10 a01 a11 p p0 p1 p2 p3) ->
forallx : A, P x x x x 11111%square
H: Funext A: Type P: forall (a00a10a01a11 : A) (p : a00 = a10)
(p0 : a01 = a11) (p1 : a00 = a01)
(p2 : a10 = a11), PathSquare p p0 p1 p2 -> Type
PathSquare_ind P o ?g == idmap
H: Funext A: Type P: forall (a00a10a01a11 : A) (p : a00 = a10)
(p0 : a01 = a11) (p1 : a00 = a01)
(p2 : a10 = a11), PathSquare p p0 p1 p2 -> Type
?g o PathSquare_ind P == idmap
H: Funext A: Type P: forall (a00a10a01a11 : A) (p : a00 = a10)
(p0 : a01 = a11) (p1 : a00 = a01)
(p2 : a10 = a11), PathSquare p p0 p1 p2 -> Type
PathSquare_ind P
o (fun
(X : forall (a00a10a01a11 : A) (p : a00 = a10)
(p0 : a01 = a11) (p1 : a00 = a01)
(p2 : a10 = a11)
(p3 : PathSquare p p0 p1 p2),
P a00 a10 a01 a11 p p0 p1 p2 p3) (x : A) =>
X x x x x 11111%square) == idmap
H: Funext A: Type P: forall (a00a10a01a11 : A) (p : a00 = a10)
(p0 : a01 = a11) (p1 : a00 = a01)
(p2 : a10 = a11), PathSquare p p0 p1 p2 -> Type
(fun
(X : forall (a00a10a01a11 : A) (p : a00 = a10)
(p0 : a01 = a11) (p1 : a00 = a01)
(p2 : a10 = a11) (p3 : PathSquare p p0 p1 p2),
P a00 a10 a01 a11 p p0 p1 p2 p3) (x : A) =>
X x x x x 11111%square) o PathSquare_ind P ==
idmap
H: Funext A: Type P: forall (a00a10a01a11 : A) (p : a00 = a10)
(p0 : a01 = a11) (p1 : a00 = a01)
(p2 : a10 = a11), PathSquare p p0 p1 p2 -> Type
PathSquare_ind P
o (fun
(X : forall (a00a10a01a11 : A) (p : a00 = a10)
(p0 : a01 = a11) (p1 : a00 = a01)
(p2 : a10 = a11)
(p3 : PathSquare p p0 p1 p2),
P a00 a10 a01 a11 p p0 p1 p2 p3) (x : A) =>
X x x x x 11111%square) == idmap
H: Funext A: Type P: forall (a00a10a01a11 : A) (p : a00 = a10)
(p0 : a01 = a11) (p1 : a00 = a01)
(p2 : a10 = a11), PathSquare p p0 p1 p2 -> Type x: forall (a00a10a01a11 : A) (p : a00 = a10)
(p0 : a01 = a11) (p1 : a00 = a01) (p2 : a10 = a11)
(p3 : PathSquare p p0 p1 p2),
P a00 a10 a01 a11 p p0 p1 p2 p3
@PathSquare_ind A P
(funx0 : A => x x0 x0 x0 x0 11111%square) = x
IsEquiv
(match
p0x as p in (_ = a)
return
(forallpx1 : a = a11,
px0 @ p1x = p @ px1 ->
PathSquare px0 px1 p p1x)
with
| 1 =>
funpx1 : a00 = a11 =>
match
p1x as p in (_ = a)
return
(forallpx2 : a00 = a,
px0 @ p = 1 @ px2 ->
PathSquare px0 px2 1 p)
with
| 1 =>
fun (px2 : a00 = a10)
(e : px0 @ 1 = 1 @ px2) =>
(fune' : px0 @ 1 = px2 =>
match
e' in (_ = p)
return
(px0 @ 1 = 1 @ p ->
PathSquare px0 p 11)
with
| 1 =>
fune0 : px0 @ 1 = 1 @ (px0 @ 1) =>
match
px0 as p in (_ = a)
return
(p @ 1 = 1 @ (...) ->
PathSquare p (p @ 1) 11)
with
| 1 =>
fun_ : 1 @ 1 = 1 @ (1 @ 1) =>
1%square
end e0
end e) (e @ concat_1p px2)
end px1
end px1)
(funX : PathSquare px0 px1 p0x p1x =>
match
X in (@PathSquare _ a00 a10 a01 a11 p p0 p1 p2)
return (p @ p2 = p1 @ p0)
with
| @sq_id _ x => (funx0 : A => 1) x
end)
o match
p0x as p in (_ = a)
return
(forallpx1 : a = a11,
px0 @ p1x = p @ px1 -> PathSquare px0 px1 p p1x)
with
| 1 =>
funpx1 : a00 = a11 =>
match
p1x as p in (_ = a)
return
(forallpx2 : a00 = a,
px0 @ p = 1 @ px2 -> PathSquare px0 px2 1 p)
with
| 1 =>
fun (px2 : a00 = a10)
(e : px0 @ 1 = 1 @ px2) =>
(fune' : px0 @ 1 = px2 =>
match
e' in (_ = p)
return
(px0 @ 1 = 1 @ p ->
PathSquare px0 p 11)
with
| 1 =>
fune0 : px0 @ 1 = 1 @ (px0 @ 1) =>
match
px0 as p in (_ = a)
return
(p @ 1 = 1 @ (...) ->
PathSquare p (p @ 1) 11)
with
| 1 =>
fun_ : 1 @ 1 = 1 @ (1 @ 1) =>
1%square
end e0
end e) (e @ concat_1p px2)
end px1
end px1 == idmap
A: Type a00, a10: A px0, px1: a00 = a10
(funx : px0 @ 1 = 1 @ px1 =>
matchmatch
x @ concat_1p px1 in (_ = p)
return (px0 @ 1 = 1 @ p -> PathSquare px0 p 11)
with
| 1 =>
fune : px0 @ 1 = 1 @ (px0 @ 1) =>
match
px0 as p in (_ = a)
return
(p @ 1 = 1 @ (p @ 1) ->
PathSquare p (p @ 1) 11)
with
| 1 => fun_ : 1 @ 1 = 1 @ (1 @ 1) => 1%square
end e
end x in (@PathSquare _ a00 a10 a01 a11 p p0 p1 p2)
return (p @ p2 = p1 @ p0)
with
| @sq_id _ x0 => 1end) == idmap
A: Type a00, a10: A px0, px1: a00 = a10 e: px0 @ 1 = 1 @ px1
matchmatch
e @ concat_1p px1 in (_ = p)
return (px0 @ 1 = 1 @ p -> PathSquare px0 p 11)
with
| 1 =>
fune : px0 @ 1 = 1 @ (px0 @ 1) =>
match
px0 as p in (_ = a)
return
(p @ 1 = 1 @ (p @ 1) ->
PathSquare p (p @ 1) 11)
with
| 1 => fun_ : 1 @ 1 = 1 @ (1 @ 1) => 1%square
end e
end e in (@PathSquare _ a00 a10 a01 a11 p p0 p1 p2)
return (p @ p2 = p1 @ p0)
with
| @sq_id _ x => 1end = e
A: Type a00, a10: A px0, px1: a00 = a10 e: px0 @ 1 = 1 @ px1
(funp : px0 @ 1 = 1 @ px1 =>
matchmatch
p @ concat_1p px1 in (_ = p0)
return
(px0 @ 1 = 1 @ p0 -> PathSquare px0 p0 11)
with
| 1 =>
fune : px0 @ 1 = 1 @ (px0 @ 1) =>
match
px0 as p0 in (_ = a)
return
(p0 @ 1 = 1 @ (p0 @ 1) ->
PathSquare p0 (p0 @ 1) 11)
with
| 1 => fun_ : 1 @ 1 = 1 @ (1 @ 1) => 1%square
end e
end p in
(@PathSquare _ a00 a10 a01 a11 p0 p1 p2 p3)
return (p0 @ p3 = p2 @ p1)
with
| @sq_id _ x => 1end = p) e
A: Type a00, a10: A px0, px1: a00 = a10 e: px0 @ 1 = 1 @ px1 e':= e @ concat_1p px1: px0 @ 1 = px1
(funp : px0 @ 1 = 1 @ px1 =>
matchmatch
p @ concat_1p px1 in (_ = p0)
return
(px0 @ 1 = 1 @ p0 -> PathSquare px0 p0 11)
with
| 1 =>
fune : px0 @ 1 = 1 @ (px0 @ 1) =>
match
px0 as p0 in (_ = a)
return
(p0 @ 1 = 1 @ (p0 @ 1) ->
PathSquare p0 (p0 @ 1) 11)
with
| 1 => fun_ : 1 @ 1 = 1 @ (1 @ 1) => 1%square
end e
end p in
(@PathSquare _ a00 a10 a01 a11 p0 p1 p2 p3)
return (p0 @ p3 = p2 @ p1)
with
| @sq_id _ x => 1end = p) e
A: Type a00, a10: A px0, px1: a00 = a10 e: px0 @ 1 = 1 @ px1 e':= e @ concat_1p px1: px0 @ 1 = px1 e'':= e' @ (concat_1p px1)^: px0 @ 1 = 1 @ px1
(funp : px0 @ 1 = 1 @ px1 =>
matchmatch
p @ concat_1p px1 in (_ = p0)
return
(px0 @ 1 = 1 @ p0 -> PathSquare px0 p0 11)
with
| 1 =>
fune : px0 @ 1 = 1 @ (px0 @ 1) =>
match
px0 as p0 in (_ = a)
return
(p0 @ 1 = 1 @ (p0 @ 1) ->
PathSquare p0 (p0 @ 1) 11)
with
| 1 => fun_ : 1 @ 1 = 1 @ (1 @ 1) => 1%square
end e
end p in
(@PathSquare _ a00 a10 a01 a11 p0 p1 p2 p3)
return (p0 @ p3 = p2 @ p1)
with
| @sq_id _ x => 1end = p) e
A: Type a00, a10: A px0, px1: a00 = a10 e: px0 @ 1 = 1 @ px1 e':= e @ concat_1p px1: px0 @ 1 = px1 e'':= e' @ (concat_1p px1)^: px0 @ 1 = 1 @ px1
e'' = e
A: Type a00, a10: A px0, px1: a00 = a10 e: px0 @ 1 = 1 @ px1 e':= e @ concat_1p px1: px0 @ 1 = px1 e'':= e' @ (concat_1p px1)^: px0 @ 1 = 1 @ px1
matchmatch
e'' @ concat_1p px1 in (_ = p)
return (px0 @ 1 = 1 @ p -> PathSquare px0 p 11)
with
| 1 =>
fune : px0 @ 1 = 1 @ (px0 @ 1) =>
match
px0 as p in (_ = a)
return
(p @ 1 = 1 @ (p @ 1) ->
PathSquare p (p @ 1) 11)
with
| 1 => fun_ : 1 @ 1 = 1 @ (1 @ 1) => 1%square
end e
end e'' in
(@PathSquare _ a00 a10 a01 a11 p p0 p1 p2)
return (p @ p2 = p1 @ p0)
with
| @sq_id _ x => 1end = e''
A: Type a00, a10: A px0, px1: a00 = a10 e: px0 @ 1 = 1 @ px1 e':= e @ concat_1p px1: px0 @ 1 = px1 e'':= e' @ (concat_1p px1)^: px0 @ 1 = 1 @ px1
e'' = e
subst e' e''; hott_simpl.
A: Type a00, a10: A px0, px1: a00 = a10 e: px0 @ 1 = 1 @ px1 e':= e @ concat_1p px1: px0 @ 1 = px1 e'':= e' @ (concat_1p px1)^: px0 @ 1 = 1 @ px1
matchmatch
e'' @ concat_1p px1 in (_ = p)
return (px0 @ 1 = 1 @ p -> PathSquare px0 p 11)
with
| 1 =>
fune : px0 @ 1 = 1 @ (px0 @ 1) =>
match
px0 as p in (_ = a)
return
(p @ 1 = 1 @ (p @ 1) ->
PathSquare p (p @ 1) 11)
with
| 1 => fun_ : 1 @ 1 = 1 @ (1 @ 1) => 1%square
end e
end e'' in
(@PathSquare _ a00 a10 a01 a11 p p0 p1 p2)
return (p @ p2 = p1 @ p0)
with
| @sq_id _ x => 1end = e''
A: Type a00, a10: A px0, px1: a00 = a10 e': px0 @ 1 = px1 e'':= e' @ (concat_1p px1)^: px0 @ 1 = 1 @ px1
matchmatch
e'' @ concat_1p px1 in (_ = p)
return (px0 @ 1 = 1 @ p -> PathSquare px0 p 11)
with
| 1 =>
fune : px0 @ 1 = 1 @ (px0 @ 1) =>
match
px0 as p in (_ = a)
return
(p @ 1 = 1 @ (p @ 1) ->
PathSquare p (p @ 1) 11)
with
| 1 => fun_ : 1 @ 1 = 1 @ (1 @ 1) => 1%square
end e
end e'' in
(@PathSquare _ a00 a10 a01 a11 p p0 p1 p2)
return (p @ p2 = p1 @ p0)
with
| @sq_id _ x => 1end = e''
A: Type a00: A e'':= 1 @ (concat_1p (1 @ 1))^: 1 @ 1 = 1 @ (1 @ 1)
matchmatch
e'' @ concat_1p (1 @ 1) in (_ = p)
return (1 @ 1 = 1 @ p -> PathSquare 1 p 11)
with
| 1 => fun_ : 1 @ 1 = 1 @ (1 @ 1) => 1%square
end e'' in
(@PathSquare _ a00 a10 a01 a11 p p0 p1 p2)
return (p @ p2 = p1 @ p0)
with
| @sq_id _ x => 1end = e''
reflexivity.Defined.Notationsq_path := equiv_sq_path.(** Squares in (n+2)-truncated types are n-truncated *)
n: trunc_index A: Type IsTrunc0: IsTrunc n.+2 A a00, a10, a01, a11: A px0: a00 = a10 px1: a01 = a11 p0x: a00 = a01 p1x: a10 = a11
IsTrunc n (PathSquare px0 px1 p0x p1x)
n: trunc_index A: Type IsTrunc0: IsTrunc n.+2 A a00, a10, a01, a11: A px0: a00 = a10 px1: a01 = a11 p0x: a00 = a01 p1x: a10 = a11
IsTrunc n (PathSquare px0 px1 p0x p1x)
exact (istrunc_equiv_istrunc _ sq_path).Defined.(* We can give degenerate squares *)SectionPathSquaresFromPaths.Context
{A : Type} {a00a10a01 : A}
{pp' : a00 = a10} {qq' : a00 = a01}.Definitionequiv_sq_G1 : p = p' <~> PathSquare p p' 11
:= sq_path oE equiv_p1_1q.Definitionequiv_sq_1G : q = q' <~> PathSquare 11 q q'
:= sq_path oE equiv_1p_q1 oE equiv_path_inverse _ _.EndPathSquaresFromPaths.Notationsq_G1 := equiv_sq_G1.Notationsq_1G := equiv_sq_1G.LocalOpen Scope equiv_scope.LocalOpen Scope path_scope.(** [PathSquare] horizontal reflexivity *)Definitionsq_refl_h {A} {a0a1 : A} (p : a0 = a1)
: PathSquare p p 11 := sq_G1 1.(** [PathSquare] vertical reflexivity *)Definitionsq_refl_v {A} {a0a1 : A} (p : a0 = a1)
: PathSquare 11 p p := sq_1G 1.(** Horizontal flip *)
1,2: byintros [].Defined.Notationsq_tr := equiv_sq_tr.(* NOTE: sq_tr ought to be some sort of involution but it obviously isn't since it is not of the form A -> A. Perhaps there is a more general "involution" but between equivalent types? But then that very equivalence is given by sq_tr so it seems a bit circular... *)
exact sq_path^-1.Defined.EndPathSquareOps.Notationsq_V := equiv_sq_V.Notationsq_rot_l:= equiv_sq_rot_l.Notationsq_rot_r := equiv_sq_rot_r.(* Lemmas for rewriting sides of squares *)SectionPathSquareRewriting.Context {A : Type}
{a00a10a01a11 : A}
{px0 : a00 = a10} {px1 : a01 = a11}
{p0x : a00 = a01} {p1x : a10 = a11}.(* These are all special cases of the following "rewrite all sides" lemma which we prove is an equivalence giving us all special cases as equivalences too *)
bydestruct qx0, qx1, q0x, q1x.Defined.Context {px0'px1'p0x'p1x'}
(qx0 : px0 = px0') (qx1 : px1 = px1')
(q0x : p0x = p0x') (q1x : p1x = p1x').Definitionequiv_sq_Gccc := equiv_sq_GGGG qx0 111.Definitionequiv_sq_cGcc := equiv_sq_GGGG 1 qx1 11.Definitionequiv_sq_ccGc := equiv_sq_GGGG 11 q0x 1.Definitionequiv_sq_cccG := equiv_sq_GGGG 111 q1x.Definitionequiv_sq_GGcc := equiv_sq_GGGG qx0 qx1 11.Definitionequiv_sq_GcGc := equiv_sq_GGGG qx0 1 q0x 1.Definitionequiv_sq_GccG := equiv_sq_GGGG qx0 11 q1x.Definitionequiv_sq_cGGc := equiv_sq_GGGG 1 qx1 q0x 1.Definitionequiv_sq_cGcG := equiv_sq_GGGG 1 qx1 1 q1x.Definitionequiv_sq_ccGG := equiv_sq_GGGG 11 q0x q1x.Definitionequiv_sq_GGGc := equiv_sq_GGGG qx0 qx1 q0x 1.Definitionequiv_sq_cGGG := equiv_sq_GGGG 1 qx1 q0x q1x.EndPathSquareRewriting.Notationsq_GGGG := equiv_sq_GGGG.Notationsq_Gccc := equiv_sq_Gccc.Notationsq_cGcc := equiv_sq_cGcc.Notationsq_ccGc := equiv_sq_ccGc.Notationsq_cccG := equiv_sq_cccG.Notationsq_GGcc := equiv_sq_GGcc.Notationsq_GcGc := equiv_sq_GcGc.Notationsq_GccG := equiv_sq_GccG.Notationsq_cGGc := equiv_sq_cGGc.Notationsq_cGcG := equiv_sq_cGcG.Notationsq_ccGG := equiv_sq_ccGG.Notationsq_GGGc := equiv_sq_GGGc.Notationsq_cGGG := equiv_sq_cGGG.SectionMovePaths.Context {A : Type} {xx00x20x02x22 : A}
{f10 : x00 = x20} {f12 : x02 = x22} {f01 : x00 = x02} {f21 : x20 = x22}.(** Operations to move paths around a square. We define all these operations immediately as equivalences. The naming first number indicates in which argument the path that moves is on the left of the equivalence, and the second number where it is on the right. The equivalences are all set up so that on the right, there is no path inversion. For the [24] and [13] equivalences there is a path inverse on the left. The corresponding equivalences [42] and [31] are the symmetric versions of these, but the path inverse is in another place. *)
A: Type x, x00, x20, x02, x22: A f10: x00 = x20 f12: x02 = x22 f01: x00 = x02 f21: x20 = x22 f12'': x02 = x f12': x = x22
sq_concat_h (sq_concat_h s t) u =
sq_ccGG (concat_p_pp p0x p0y p0z)
(concat_p_pp p1x p1y p1z)
(sq_concat_h s (sq_concat_h t u))
bydestruct s, u, (sq_1G^-1 t), p0y.Defined.EndGroupoidLawsH.(** [PathSquare] Kan fillers ~ Every open box has a lid *)SectionKan.(* These can be used to prove groupoid laws about paths *)Context {A : Type} {a00a10a01a11 : A}.
A: Type a00, a10, a01, a11: A px1: a01 = a11 p0x: a00 = a01 p1x: a10 = a11
{px0 : a00 = a10 & PathSquare px0 px1 p0x p1x}
A: Type a00, a10, a01, a11: A px1: a01 = a11 p0x: a00 = a01 p1x: a10 = a11
{px0 : a00 = a10 & PathSquare px0 px1 p0x p1x}
A: Type a00, a10, a01, a11: A px1: a01 = a11 p0x: a00 = a01 p1x: a10 = a11
exact sq_path.Defined.Notationsq_prod := equiv_sq_prod.(** The natural square from an [ap] *)
A, B: Type f, f': A -> B h: f == f' x, y: A p: x = y
PathSquare (ap f p) (ap f' p) (h x) (h y)
A, B: Type f, f': A -> B h: f == f' x, y: A p: x = y
PathSquare (ap f p) (ap f' p) (h x) (h y)
bydestruct p; apply sq_1G.Defined.(** The transpose of the natural square *)
A, B: Type f, f': A -> B h: f == f' x, y: A p: x = y
PathSquare (h x) (h y) (ap f p) (ap f' p)
A, B: Type f, f': A -> B h: f == f' x, y: A p: x = y
PathSquare (h x) (h y) (ap f p) (ap f' p)
bydestruct p; apply sq_G1.Defined.(** [ap_compose] fits naturally into a square *)Definitionap_compose_sq {ABC} (f : A -> B) (g : B -> C) {xy : A} (p : x = y)
: PathSquare (ap (g o f) p) (ap g (ap f p)) 11 := sq_G1 (ap_compose f g p).Definitionap_idmap_sq {A} {xy : A} (p : x = y) : PathSquare (ap idmap p) p 11
:= sq_G1 (ap_idmap p).(** A [DPath] of a certain form can be turned into a square *)
A, B: Type f, g: A -> B a1, a2: A p: a1 = a2 q1: f a1 = g a1 q2: f a2 = g a2
DPath (funx : A => f x = g x) p q1 q2 <~>
PathSquare q1 q2 (ap f p) (ap g p)
A, B: Type f, g: A -> B a1, a2: A p: a1 = a2 q1: f a1 = g a1 q2: f a2 = g a2
DPath (funx : A => f x = g x) p q1 q2 <~>
PathSquare q1 q2 (ap f p) (ap g p)
A, B: Type f, g: A -> B a1: A q1, q2: f a1 = g a1
DPath (funx : A => f x = g x) 1 q1 q2 <~>
PathSquare q1 q2 (ap f 1) (ap g 1)
exact sq_G1.Defined.Notationsq_dp := equiv_sq_dp.(** [ap011] fits into a square *)
A, B, C: Type f: A -> B -> C a, a': A p: a = a' b, b': B q: b = b'
PathSquare (ap (funx : A => f x b) p)
(ap (funx : A => f x b') p) (ap (f a) q)
(ap (f a') q)
A, B, C: Type f: A -> B -> C a, a': A p: a = a' b, b': B q: b = b'
PathSquare (ap (funx : A => f x b) p)
(ap (funx : A => f x b') p) (ap (f a) q)
(ap (f a') q)
A, B, C: Type f: A -> B -> C a, a': A p: a = a' b, b': B q: b = b'
DPath (funx : B => f a x = f a' x) q
(ap (funx : A => f x b) p)
(ap (funx : A => f x b') p)
exact (apD (funy => ap (funx => f x y) p) q).Defined.