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 HFiber Constant.Require Import Truncations.Core Modalities.Modality.Require Import Homotopy.IdentitySystems.LocalOpen Scope nat_scope.LocalOpen Scope path_scope.Local Set Universe Minimization ToSet.(** * Idempotents and their splittings *)(** ** Basic definitions *)(** *** Retracts *)(** A *retract* of a type [X] is a type [A] equipped with a pair of morphisms [r : X -> A] and [s : A -> X] such that the composite [r o s] is the identity of [A]. *)RecordRetractOf {X : Type} :=
{ retract_type : Type ;
retract_retr : X -> retract_type ;
retract_sect : retract_type -> X ;
retract_issect : retract_retr o retract_sect == idmap }.Arguments RetractOf X : clear implicits.Arguments retract_type / .Arguments retract_retr / .Arguments retract_sect / .Arguments retract_issect / .(** For example, here is the identity retraction. *)Definitionidmap_retractof (X : Type) : RetractOf X
:= Build_RetractOf X X idmap idmap (fun_ => 1).(** Retractions can be composed with equivalences on either side. *)
X, Y: Type f: X -> Y feq: IsEquiv f
RetractOf X -> RetractOf Y
X, Y: Type f: X -> Y feq: IsEquiv f
RetractOf X -> RetractOf Y
X, Y: Type f: X -> Y feq: IsEquiv f A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap x: A
r (f^-1 (f (s x))) = x
exact (ap r (eissect f (s x)) @ H x).Defined.Definitionretractof_equiv' {XY : Type} (f : X <~> Y)
: RetractOf X -> RetractOf Y
:= retractof_equiv f.
X: Type R: RetractOf X B: Type f: retract_type R -> B feq: IsEquiv f
RetractOf X
X: Type R: RetractOf X B: Type f: retract_type R -> B feq: IsEquiv f
RetractOf X
X, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap B: Type f: retract_type
{|
retract_type := A;
retract_retr := r;
retract_sect := s;
retract_issect := H
|} -> B feq: IsEquiv f x: B
f (r (s (f^-1 x))) = x
exact (ap f (H (f^-1 x)) @ eisretr f x).Defined.Definitionequiv_retractof' {X : Type} (R : RetractOf X)
{B : Type} (f : retract_type R <~> B)
: RetractOf X
:= equiv_retractof R f.(** A commuting retract of the domain of map induces a retract of its fibers. *)
X, Y: Type R: RetractOf X f: X -> Y g: retract_type R -> Y p: g o retract_retr R == f y: Y
RetractOf (hfiber f y)
X, Y: Type R: RetractOf X f: X -> Y g: retract_type R -> Y p: g o retract_retr R == f y: Y
RetractOf (hfiber f y)
X, Y, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap f: X -> Y g: A -> Y p: (funx : X => g (r x)) == f y: Y
RetractOf (hfiber f y)
X, Y, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap f: X -> Y g: A -> Y p: (funx : X => g (r x)) == f y: Y
hfiber f y -> hfiber g y
X, Y, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap f: X -> Y g: A -> Y p: (funx : X => g (r x)) == f y: Y
hfiber g y -> hfiber f y
X, Y, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap f: X -> Y g: A -> Y p: (funx : X => g (r x)) == f y: Y
?retract_retr o ?retract_sect == idmap
X, Y, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap f: X -> Y g: A -> Y p: (funx : X => g (r x)) == f y: Y
hfiber f y -> hfiber g y
X, Y, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap f: X -> Y g: A -> Y p: (funx : X => g (r x)) == f y: Y x: X q: f x = y
hfiber g y
X, Y, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap f: X -> Y g: A -> Y p: (funx : X => g (r x)) == f y: Y x: X q: f x = y
g (r x) = y
exact (p x @ q).
X, Y, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap f: X -> Y g: A -> Y p: (funx : X => g (r x)) == f y: Y
hfiber g y -> hfiber f y
X, Y, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap f: X -> Y g: A -> Y p: (funx : X => g (r x)) == f y: Y a: A q: g a = y
hfiber f y
X, Y, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap f: X -> Y g: A -> Y p: (funx : X => g (r x)) == f y: Y a: A q: g a = y
f (s a) = y
exact ((p (s a))^ @ ap g (H a) @ q).
X, Y, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap f: X -> Y g: A -> Y p: (funx : X => g (r x)) == f y: Y
(funX0 : hfiber f y =>
(fun (x : X) (q : f x = y) => (r x; p x @ q)) X0.1
X0.2)
o (funX0 : hfiber g y =>
(fun (a : A) (q : g a = y) =>
(s a; ((p (s a))^ @ ap g (H a)) @ q)) X0.1 X0.2) ==
idmap
X, Y, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap f: X -> Y g: A -> Y p: (funx : X => g (r x)) == f y: Y a: A q: g a = y
(r (s a); p (s a) @ (((p (s a))^ @ ap g (H a)) @ q)) =
(a; q)
X, Y, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap f: X -> Y g: A -> Y p: (funx : X => g (r x)) == f y: Y a: A q: g a = y
r (s a) = a
X, Y, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap f: X -> Y g: A -> Y p: (funx : X => g (r x)) == f y: Y a: A q: g a = y
transport (funx : A => g x = y) ?p
(p (s a) @ (((p (s a))^ @ ap g (H a)) @ q)) = q
X, Y, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap f: X -> Y g: A -> Y p: (funx : X => g (r x)) == f y: Y a: A q: g a = y
r (s a) = a
exact (H a).
X, Y, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap f: X -> Y g: A -> Y p: (funx : X => g (r x)) == f y: Y a: A q: g a = y
transport (funx : A => g x = y) (H a)
(p (s a) @ (((p (s a))^ @ ap g (H a)) @ q)) = q
abstract (
rewrite transport_paths_Fl, !concat_p_pp, concat_pp_V, concat_Vp, concat_1p;
reflexivity).Defined.(** Retraction preserves contractibility **)Definitioncontr_retracttype {X : Type} (R : RetractOf X ) (contra : Contr X) : Contr (retract_type R )
:= contr_retract (retract_retr R) (retract_sect R) (retract_issect R).(** Like any record type, [RetractOf X] is equivalent to a nested sigma-type. We use a product at one place in the middle, rather than a sigma, to simplify the next proof. *)
X: Type
{A : Type &
{r : X -> A & {s : A -> X & r o s == idmap}}} <~>
RetractOf X
X: Type
{A : Type &
{r : X -> A & {s : A -> X & r o s == idmap}}} <~>
RetractOf X
issig.Defined.(* Path spaces of types of retractions *)DefinitionPathRetractOf (X : Type) (R'R : RetractOf X)
:= { Ap : retract_type R' <~> retract_type R &
{ rp : Ap o retract_retr R' == retract_retr R &
{ sp : retract_sect R' o Ap^-1 == retract_sect R &
foralla, ap Ap (retract_issect R' (Ap^-1 a))
@ eisretr Ap a
= rp (retract_sect R' (Ap^-1 a))
@ ap (retract_retr R) (sp a)
@ retract_issect R a } } }.
ua: Univalence X: Type R', R: RetractOf X
PathRetractOf X R' R <~> R' = R
ua: Univalence X: Type R', R: RetractOf X
PathRetractOf X R' R <~> R' = R
ua: Univalence X: Type
forallb : {A : Type &
{r : X -> A &
{s : A -> X & (funx : A => r (s x)) == idmap}}},
PathRetractOf X (issig_retractof X b)
(issig_retractof X b)
ua: Univalence X: Type
forallb1 : {A : Type &
{r : X -> A &
{s : A -> X & (funx : A => r (s x)) == idmap}}},
Contr
{b2
: {A : Type &
{r : X -> A &
{s : A -> X & (funx : A => r (s x)) == idmap}}} &
PathRetractOf X (issig_retractof X b1)
(issig_retractof X b2)}
ua: Univalence X: Type
forallb : {A : Type &
{r : X -> A &
{s : A -> X & (funx : A => r (s x)) == idmap}}},
PathRetractOf X (issig_retractof X b)
(issig_retractof X b)
ua: Univalence X, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap
PathRetractOf X
{|
retract_type := A;
retract_retr := r;
retract_sect := s;
retract_issect := H
|}
{|
retract_type := A;
retract_retr := r;
retract_sect := s;
retract_issect := H
|}
ua: Univalence X, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap
ua: Univalence X, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap
foralla : retract_type
{|
retract_type := A;
retract_retr := r;
retract_sect := s;
retract_issect := H
|},
ap 1%equiv
(retract_issect
{|
retract_type := A;
retract_retr := r;
retract_sect := s;
retract_issect := H
|} ((1%equiv)^-1 a)) @ eisretr 1%equiv a =
(1 @
ap
(retract_retr
{|
retract_type := A;
retract_retr := r;
retract_sect := s;
retract_issect := H
|}) 1) @
retract_issect
{|
retract_type := A;
retract_retr := r;
retract_sect := s;
retract_issect := H
|} a
ua: Univalence X, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap
foralla : A, ap idmap (H a) @ 1 = 1 @ H a
exact (funa => equiv_p1_1q (ap_idmap (H a))).
ua: Univalence X: Type
forallb1 : {A : Type &
{r : X -> A &
{s : A -> X & (funx : A => r (s x)) == idmap}}},
Contr
{b2
: {A : Type &
{r : X -> A &
{s : A -> X & (funx : A => r (s x)) == idmap}}} &
PathRetractOf X (issig_retractof X b1)
(issig_retractof X b2)}
ua: Univalence X, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap
Contr
{b2
: {A : Type &
{r : X -> A &
{s : A -> X & (funx : A => r (s x)) == idmap}}} &
PathRetractOf X
{|
retract_type := A;
retract_retr := r;
retract_sect := s;
retract_issect := H
|}
{|
retract_type := b2.1;
retract_retr := (b2.2).1;
retract_sect := ((b2.2).2).1;
retract_issect := ((b2.2).2).2
|}}
ua: Univalence X, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap
ua: Univalence X, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap
Contr
{y
: {r : X -> A &
{s : A -> X & (funx : A => r (s x)) == idmap}} &
{rp : (funx : X => r x) == y.1 &
{sp : (funx : A => s x) == (y.2).1 &
foralla : A,
ap idmap (H a) @ 1 =
(rp (s a) @ ap y.1 (sp a)) @ (y.2).2 a}}}
ua: Univalence X, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap
Contr
{y : {s : A -> X & (funx : A => r (s x)) == idmap}
&
{sp : (funx : A => s x) == y.1 &
foralla : A,
ap idmap (H a) @ 1 = (1 @ ap r (sp a)) @ y.2 a}}
ua: Univalence X, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap
Contr
{y : (funx : A => r (s x)) == idmap &
foralla : A, ap idmap (H a) @ 1 = 1 @ y a}
ua: Univalence X, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap
{K : (funx : A => r (s x)) == idmap & H == K} <~>
{y : (funx : A => r (s x)) == idmap &
foralla : A, ap idmap (H a) @ 1 = 1 @ y a}
ua: Univalence X, A: Type r: X -> A s: A -> X H, K: (funx : A => r (s x)) == idmap
H == K <~>
(foralla : A, ap idmap (H a) @ 1 = 1 @ K a)
ua: Univalence X, A: Type r: X -> A s: A -> X H, K: (funx : A => r (s x)) == idmap a: A
H a = K a <~> ap idmap (H a) @ 1 = 1 @ K a
ua: Univalence X, A: Type r: X -> A s: A -> X H, K: (funx : A => r (s x)) == idmap a: A
ap idmap (H a) @ 1 = H a
ua: Univalence X, A: Type r: X -> A s: A -> X H, K: (funx : A => r (s x)) == idmap a: A
K a = 1 @ K a
ua: Univalence X, A: Type r: X -> A s: A -> X H, K: (funx : A => r (s x)) == idmap a: A
ap idmap (H a) @ 1 = H a
exact (concat_p1 _ @ ap_idmap (H a)).
ua: Univalence X, A: Type r: X -> A s: A -> X H, K: (funx : A => r (s x)) == idmap a: A
K a = 1 @ K a
symmetry; apply concat_1p.Defined.Definitionpath_retractof `{ua : Univalence} {X : Type} {R' R : RetractOf X}
Ap rp sp Hp
: R' = R
:= equiv_path_retractof R' R (Ap;rp;sp;Hp).(** *** Splittings *)(** If an endomap [f : X -> X] arises from a retract as [s o r], we say that that retract is a *splitting* of [f]. *)Definitionretract_idem {X : Type} (R : RetractOf X)
: (X -> X)
:= retract_sect R o retract_retr R.Arguments retract_idem {_} _ / x .DefinitionSplitting {X : Type} (f : X -> X)
:= { R : RetractOf X & retract_idem R == f}.(** For example, here is the canonical splitting of the identity. *)Definitionsplitting_idmap (X : Type) : @Splitting X idmap
:= (idmap_retractof X ; fun_ => 1).(** *** Pre-idempotents *)(** An "idempotent" is a map that at least "ought" to be splittable. The naive definition of idempotent, which is correct in set-level mathematics, is a morphism [f : X -> X] such that [forall x, f (f x) = f x]. We will call this a "pre-idempotent". *)ClassIsPreIdempotent {X : Type} (f : X -> X)
:= isidem : forallx, f (f x) = f x.Arguments isidem {X} f {_} x.
X: Type f: X -> X H: IsPreIdempotent f g: X -> X p: f == g
IsPreIdempotent g
X: Type f: X -> X H: IsPreIdempotent f g: X -> X p: f == g
IsPreIdempotent g
X: Type f: X -> X H: IsPreIdempotent f g: X -> X p: f == g x: X
g (g x) = f (f x)
X: Type f: X -> X H: IsPreIdempotent f g: X -> X p: f == g x: X
g (g x) = g (f x)
apply ap; symmetry; apply p.Defined.Arguments ispreidem_homotopic / .DefinitionPreIdempotent (X : Type) := { f : X -> X & IsPreIdempotent f }.Definitionpreidempotent_pr1 {X : Type} : PreIdempotent X -> X -> X := pr1.Coercionpreidempotent_pr1 : PreIdempotent >-> Funclass.Instanceispreidem_preidem {X : Type} (f : PreIdempotent X)
: IsPreIdempotent f
:= f.2.(** The identity function has a canonical structure of a pre-idempotent. *)Instanceispreidem_idmap (X : Type) : @IsPreIdempotent X idmap
:= fun_ => 1.
X: Type
PreIdempotent X
X: Type
PreIdempotent X
existsidmap; exact _.Defined.(** Any pre-idempotent on a set splits. *)
X: Type IsHSet0: IsHSet X f: PreIdempotent X
Splitting f
X: Type IsHSet0: IsHSet X f: PreIdempotent X
Splitting f
X: Type IsHSet0: IsHSet X f: PreIdempotent X
(funx : X => (f x; isidem f x)) o pr1 == idmap
X: Type IsHSet0: IsHSet X f: PreIdempotent X
(funR : RetractOf X => retract_idem R == f)
{|
retract_type := {x : X & f x = x};
retract_retr := funx : X => (f x; isidem f x);
retract_sect := pr1;
retract_issect := ?retract_issect
|}
X: Type IsHSet0: IsHSet X f: PreIdempotent X
(funx : X => (f x; isidem f x)) o pr1 == idmap
X: Type IsHSet0: IsHSet X f: PreIdempotent X x: X p: f x = x
(f x; isidem f x) = (x; p)
X: Type IsHSet0: IsHSet X f: PreIdempotent X x: X p: f x = x
transport (funx : X => f x = x) p (isidem f x) = p
apply path_ishprop.
X: Type IsHSet0: IsHSet X f: PreIdempotent X
(funR : RetractOf X => retract_idem R == f)
{|
retract_type := {x : X & f x = x};
retract_retr := funx : X => (f x; isidem f x);
retract_sect := pr1;
retract_issect :=
(funx0 : {x : X & f x = x} =>
(fun (x : X) (p : f x = x) =>
path_sigma (funx1 : X => f x1 = x1)
(f x; isidem f x) (x; p) p
(path_ishprop
(transport (funx1 : X => f x1 = x1) p
(isidem f x)) p
:
transport (funx1 : X => f x1 = x1) p
(f x; isidem f x).2 = (x; p).2)
:
(f (x; p).1; isidem f (x; p).1) = (x; p)) x0.1
x0.2)
:
(funx : X => (f x; isidem f x)) o pr1 == idmap
|}
X: Type IsHSet0: IsHSet X f: PreIdempotent X
(funx : X => f x) == f
intros x; reflexivity.Defined.(** Any weakly constant pre-idempotent splits (Escardó) *)
X: Type f: PreIdempotent X H: WeaklyConstant f
Splitting f
X: Type f: PreIdempotent X H: WeaklyConstant f
Splitting f
X: Type f: PreIdempotent X H: WeaklyConstant f
(funx : X => (f x; isidem f x)) o pr1 == idmap
X: Type f: PreIdempotent X H: WeaklyConstant f
(funR : RetractOf X => retract_idem R == f)
{|
retract_type := FixedBy f;
retract_retr := funx : X => (f x; isidem f x);
retract_sect := pr1;
retract_issect := ?retract_issect
|}
X: Type f: PreIdempotent X H: WeaklyConstant f
(funx : X => (f x; isidem f x)) o pr1 == idmap
intros x; apply path_ishprop.
X: Type f: PreIdempotent X H: WeaklyConstant f
(funR : RetractOf X => retract_idem R == f)
{|
retract_type := FixedBy f;
retract_retr := funx : X => (f x; isidem f x);
retract_sect := pr1;
retract_issect :=
(funx : FixedBy f =>
path_ishprop (f x.1; isidem f x.1) x)
:
(funx : X => (f x; isidem f x)) o pr1 == idmap
|}
X: Type f: PreIdempotent X H: WeaklyConstant f
(funx : X => f x) == f
intros x; reflexivity.Defined.(** If [f] is pre-idempotent and [f x = x] is collapsible for all [x], then [f] splits (Escardó). *)
X: Type f: PreIdempotent X ss: forallx : X, Collapsible (f x = x)
Splitting f
X: Type f: PreIdempotent X ss: forallx : X, Collapsible (f x = x)
Splitting f
X: Type f: PreIdempotent X ss: forallx : X, Collapsible (f x = x)
X -> {x : X & FixedBy collapse}
X: Type f: PreIdempotent X ss: forallx : X, Collapsible (f x = x)
?retract_retr o pr1 == idmap
X: Type f: PreIdempotent X ss: forallx : X, Collapsible (f x = x)
(funR : RetractOf X => retract_idem R == f)
{|
retract_type := {x : X & FixedBy collapse};
retract_retr := ?retract_retr;
retract_sect := pr1;
retract_issect := ?retract_issect
|}
X: Type f: PreIdempotent X ss: forallx : X, Collapsible (f x = x)
X -> {x : X & FixedBy collapse}
X: Type f: PreIdempotent X ss: forallx : X, Collapsible (f x = x) x: X
{x0 : f (f x) = f x & collapse x0 = x0}
X: Type f: PreIdempotent X ss: forallx : X, Collapsible (f x = x) x: X
collapse (collapse (isidem f x)) =
collapse (isidem f x)
apply wconst.
X: Type f: PreIdempotent X ss: forallx : X, Collapsible (f x = x)
(funx : X =>
(f x;
(collapse (isidem f x);
wconst (collapse (isidem f x)) (isidem f x))
:
FixedBy collapse)) o pr1 == idmap
X: Type f: PreIdempotent X ss: forallx : X, Collapsible (f x = x) x: X p: f x = x q: collapse p = p
(f x; collapse (isidem f x);
wconst (collapse (isidem f x)) (isidem f x)) =
(x; p; q)
X: Type f: PreIdempotent X ss: forallx : X, Collapsible (f x = x) x: X p: f x = x q: collapse p = p
transport (funx : X => FixedBy collapse) p
(f x; collapse (isidem f x);
wconst (collapse (isidem f x)) (isidem f x)).2 =
(x; p; q).2
apply path_ishprop.
X: Type f: PreIdempotent X ss: forallx : X, Collapsible (f x = x)
(funR : RetractOf X => retract_idem R == f)
{|
retract_type := {x : X & FixedBy collapse};
retract_retr :=
funx : X =>
(f x;
(collapse (isidem f x);
wconst (collapse (isidem f x)) (isidem f x))
:
FixedBy collapse);
retract_sect := pr1;
retract_issect :=
(funx0 : {x : X & FixedBy collapse} =>
(fun (x : X) (proj2 : FixedBy collapse) =>
(fun (p : f x = x) (q : collapse p = p) =>
path_sigma (funx1 : X => FixedBy collapse)
(f x; collapse (isidem f x);
wconst (collapse (isidem f x)) (isidem f x))
(x; p; q) p
(path_ishprop
(transport
(funx1 : X => FixedBy collapse) p
(f x; collapse (isidem f x);
wconst (collapse (isidem f x))
(isidem f x)).2) (x; p; q).2)
:
(f (x; p; q).1;
collapse (isidem f (x; p; q).1);
wconst (collapse (isidem f (x; p; q).1))
(isidem f (x; p; q).1)) = (x; p; q))
proj2.1 proj2.2) x0.1 x0.2)
:
(funx : X =>
(f x;
(collapse (isidem f x);
wconst (collapse (isidem f x)) (isidem f x))
:
FixedBy collapse)) o pr1 == idmap
|}
X: Type f: PreIdempotent X ss: forallx : X, Collapsible (f x = x)
(funx : X => f x) == f
intros x; reflexivity.Defined.(** Moreover, in this case the section is an embedding. *)
X: Type f: PreIdempotent X ss: forallx : X, Collapsible (f x = x)
IsEmbedding
(retract_sect (split_preidem_splitsupp X f ss).1)
X: Type f: PreIdempotent X ss: forallx : X, Collapsible (f x = x)
IsEmbedding
(retract_sect (split_preidem_splitsupp X f ss).1)
apply istruncmap_mapinO_tr; exact _.Defined.(** Conversely, if [f] splits with a section that is an embedding, then (it is pre-idempotent and) [f x = x] is collapsible for all [x] (Escardó). *)
X: Type f: X -> X S: Splitting f IsEmbedding0: IsEmbedding (retract_sect S.1)
forallx : X, Collapsible (f x = x)
X: Type f: X -> X S: Splitting f IsEmbedding0: IsEmbedding (retract_sect S.1)
forallx : X, Collapsible (f x = x)
X: Type f: X -> X S: Splitting f IsEmbedding0: IsEmbedding (retract_sect S.1) x: X
Collapsible (f x = x)
X: Type f: X -> X A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap K: (funx : X => s (r x)) == f IsEmbedding0: IsEmbedding s x: X
Collapsible (f x = x)
X: Type f: X -> X A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap K: (funx : X => s (r x)) == f IsEmbedding0: IsEmbedding s x: X
f x = x -> {a : A & s a = x}
X: Type f: X -> X A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap K: (funx : X => s (r x)) == f IsEmbedding0: IsEmbedding s x: X c1: f x = x -> {a : A & s a = x}
Collapsible (f x = x)
X: Type f: X -> X A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap K: (funx : X => s (r x)) == f IsEmbedding0: IsEmbedding s x: X
f x = x -> {a : A & s a = x}
X: Type f: X -> X A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap K: (funx : X => s (r x)) == f IsEmbedding0: IsEmbedding s x: X p: f x = x
s (r x) = x
exact (K x @ p).
X: Type f: X -> X A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap K: (funx : X => s (r x)) == f IsEmbedding0: IsEmbedding s x: X c1: f x = x -> {a : A & s a = x}
Collapsible (f x = x)
X: Type f: X -> X A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap K: (funx : X => s (r x)) == f IsEmbedding0: IsEmbedding s x: X c1: f x = x -> {a : A & s a = x}
{a : A & s a = x} -> f x = x
X: Type f: X -> X A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap K: (funx : X => s (r x)) == f IsEmbedding0: IsEmbedding s x: X c1: f x = x -> {a : A & s a = x} c2: {a : A & s a = x} -> f x = x
Collapsible (f x = x)
X: Type f: X -> X A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap K: (funx : X => s (r x)) == f IsEmbedding0: IsEmbedding s x: X c1: f x = x -> {a : A & s a = x}
{a : A & s a = x} -> f x = x
X: Type f: X -> X A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap K: (funx : X => s (r x)) == f IsEmbedding0: IsEmbedding s x: X c1: f x = x -> {a : A & s a = x} a: A q: s a = x
f x = x
exact ((K x)^ @ ap (s o r) q^ @ ap s (H a) @ q).
X: Type f: X -> X A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap K: (funx : X => s (r x)) == f IsEmbedding0: IsEmbedding s x: X c1: f x = x -> {a : A & s a = x} c2: {a : A & s a = x} -> f x = x
Collapsible (f x = x)
X: Type f: X -> X A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap K: (funx : X => s (r x)) == f IsEmbedding0: IsEmbedding s x: X c1: f x = x -> {a : A & s a = x} c2: {a : A & s a = x} -> f x = x
WeaklyConstant (funx : f x = x => c2 (c1 x))
apply wconst_through_hprop.Defined.(** *** Quasi-idempotents *)(** However, homotopically we may naturally expect to need some coherence on the witness [isidem] of idempotency. And indeed, in homotopy theory there are pre-idempotents which do not split; we will see an example later on. We expect a "coherent idempotent" to involve infinitely many data. However, Lemma 7.3.5.14 of *Higher Algebra* suggests that for an idempotent to admit *some* coherentification, hence also a splitting, it suffices to have *one* additional datum. By modifying the construction given there, we can show similarly in type theory that any idempotent satisfying an additional coherence datum splits. We will call a pre-idempotent with this one additional datum a "quasi-idempotent", since it is related to a fully coherent idempotent similarly to the way having a "quasi-inverse" is related to being a coherent equivalence. *)ClassIsQuasiIdempotent {X : Type} (f : X -> X) `{IsPreIdempotent _ f}
:= isidem2 : forallx, ap f (isidem f x) = isidem f (f x).Arguments isidem2 {X} f {_ _} x.
X: Type f: X -> X H: IsPreIdempotent f H0: IsQuasiIdempotent f g: X -> X p: f == g
IsQuasiIdempotent g
X: Type f: X -> X H: IsPreIdempotent f H0: IsQuasiIdempotent f g: X -> X p: f == g
IsQuasiIdempotent g
X: Type f: X -> X H: IsPreIdempotent f H0: IsQuasiIdempotent f g: X -> X p: f == g x: X
ap g (((ap g (p x)^ @ (p (f x))^) @ isidem f x) @ p x) =
((ap g (p (g x))^ @ (p (f (g x)))^) @ isidem f (g x)) @
p (g x)
X: Type f: X -> X H: IsPreIdempotent f H0: IsQuasiIdempotent f g: X -> X p: f == g x: X
ap g (ap g (p x)^
@' (p (f x))^
@' isidem f x
@' p x) =
ap g (p (g x))^
@' (p (f (g x)))^
@' isidem f (g x)
@' p (g x)
X: Type f: X -> X H: IsPreIdempotent f H0: IsQuasiIdempotent f g: X -> X p: f == g x: X
ap g ((p (g x))^
@' ap f (p x)^
@' isidem f x
@' p x) =
ap g (p (g x))^
@' (p (f (g x)))^
@' isidem f (g x)
@' p (g x)
X: Type f: X -> X H: IsPreIdempotent f H0: IsQuasiIdempotent f g: X -> X p: f == g x: X
ap g (ap f (p x)^)
@' (ap g (isidem f x)
@' ap g (p x)) =
(p (f (g x)))^
@' (isidem f (g x)
@' p (g x))
X: Type f: X -> X H: IsPreIdempotent f H0: IsQuasiIdempotent f g: X -> X p: f == g x: X
ap g (ap f (p x)^)
@' ap g (isidem f x)
@' ap g (p x)
@' (p (g x))^ = (p (f (g x)))^
@' isidem f (g x)
X: Type f: X -> X H: IsPreIdempotent f H0: IsQuasiIdempotent f g: X -> X p: f == g x: X
ap g (ap f (p x)^)
@' ap g (isidem f x)
@' (p (f x))^
@' ap f (p x) = (p (f (g x)))^
@' isidem f (g x)
X: Type f: X -> X H: IsPreIdempotent f H0: IsQuasiIdempotent f g: X -> X p: f == g x: X
ap g (ap f (p x)^)
@' (p (f (f x)))^
@' ap f (isidem f x)
@' ap f (p x) = (p (f (g x)))^
@' isidem f (g x)
X: Type f: X -> X H: IsPreIdempotent f H0: IsQuasiIdempotent f g: X -> X p: f == g x: X
(p (f (g x)))^
@' ap f (ap f (p x)^)
@' ap f (isidem f x)
@' ap f (p x) = (p (f (g x)))^
@' isidem f (g x)
X: Type f: X -> X H: IsPreIdempotent f H0: IsQuasiIdempotent f g: X -> X p: f == g x: X
ap f (ap f (p x)^)
@' (ap f (isidem f x)
@' ap f (p x)) = isidem f (g x)
X: Type f: X -> X H: IsPreIdempotent f H0: IsQuasiIdempotent f g: X -> X p: f == g x: X
ap f (isidem f x)
@' ap f (p x) = ap f (ap f (p x))
@' isidem f (g x)
X: Type f: X -> X H: IsPreIdempotent f H0: IsQuasiIdempotent f g: X -> X p: f == g x: X
ap f (isidem f x)
@' ap f (p x) =
ap (funx : X => f (f x)) (p x)
@' isidem f (g x)
X: Type f: X -> X H: IsPreIdempotent f H0: IsQuasiIdempotent f g: X -> X p: f == g x: X
isidem f (f x)
@' ap f (p x) =
ap (funx : X => f (f x)) (p x)
@' isidem f (g x)
symmetry; exact (concat_Ap (isidem f) (p x)).Close Scope long_path_scope.Qed.DefinitionQuasiIdempotent (X : Type) := { f : PreIdempotent X & IsQuasiIdempotent f }.Definitionquasiidempotent_pr1 {X : Type} : QuasiIdempotent X -> X -> X := pr1.Coercionquasiidempotent_pr1 : QuasiIdempotent >-> Funclass.Instanceisqidem_qidem {X : Type} (f : QuasiIdempotent X)
: IsQuasiIdempotent f
:= f.2.(** The identity function has a canonical structure of a quasi-idempotent. *)Instanceisqidem_idmap (X : Type) : @IsQuasiIdempotent X idmap _
:= fun_ => 1.
X: Type
QuasiIdempotent X
X: Type
QuasiIdempotent X
exists (preidem_idmapX); exact _.Defined.(** We have made [IsPreIdempotent] and [IsQuasiIdempotent] typeclasses as an experiment. It could be that they should revert back to [Definitions]. *)(** ** Split morphisms are quasi-idempotent *)(** First we show that given a retract, the composite [s o r] is quasi-idempotent. *)
X: Type R: RetractOf X
IsPreIdempotent (retract_idem R)
X: Type R: RetractOf X
IsPreIdempotent (retract_idem R)
exact (funx => ap (retract_sect R) (retract_issect R (retract_retr R x))).Defined.Definitionpreidem_retract {X : Type} (R : RetractOf X)
: PreIdempotent X
:= (retract_idem R ; ispreidem_retract R).Arguments ispreidem_retract / .Arguments preidem_retract / .
X: Type R: RetractOf X
IsQuasiIdempotent (retract_idem R)
X: Type R: RetractOf X
IsQuasiIdempotent (retract_idem R)
X, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap x: X
ap (funx : X => s (r x)) (ap s (H (r x))) =
ap s (H (r (s (r x))))
X, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap x: X
ap s (ap r (ap s (H (r x)))) = ap s (H (r (s (r x))))
X, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap x: X
ap r (ap s (H (r x))) = H (r (s (r x)))
X, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap x: X
ap (funx : A => r (s x)) (H (r x)) = H (r (s (r x)))
X, A: Type r: X -> A s: A -> X H: (funx : A => r (s x)) == idmap x: X
ap (funx : A => r (s x)) (H (r x)) @ H (r x) =
H (r (s (r x))) @ H (r x)
refine (concat_A1p H (H (r x))).Defined.Definitionqidem_retract {X : Type} (R : RetractOf X)
: QuasiIdempotent X
:= (preidem_retract R ; isqidem_retract R).(** In particular, it follows that any split function is quasi-idempotent. *)
X: Type f: X -> X S: Splitting f
IsPreIdempotent f
X: Type f: X -> X S: Splitting f
IsPreIdempotent f
X: Type f: X -> X R: RetractOf X p: retract_idem R == f
X: Type f: X -> X R: RetractOf X p: retract_idem R == f
IsQuasiIdempotent f
exact (isqidem_homotopic _ p).Defined.Arguments isqidem_split / .(** ** Quasi-idempotents split *)(** We now show the converse, that every quasi-idempotent splits. *)SectionSplitting.(** We need funext because our construction will involve a sequential limit. We could probably also use a HIT sequential colimit, which is more like what Lurie does. (Note that, like an interval type, HIT sequential colimits probably imply funext, so our construction uses strictly weaker hypotheses.) *)Context `{Funext}.Context {X : Type} (f : X -> X).Context `{IsQuasiIdempotent _ f}.LetI := isidem f.LetJ : forallx, ap f (I x) = I (f x)
:= isidem2 f.(** The splitting will be the sequential limit of the sequence [... -> X -> X -> X]. *)Definitionsplit_idem : Type
:= { a : nat -> X & foralln, f (a n.+1) = a n }.Definitionsplit_idem_pr1 : split_idem -> (nat -> X)
:= pr1.Coercionsplit_idem_pr1 : split_idem >-> Funclass.Arguments split_idem_pr1 / .(** The section, retraction, and the fact that the composite in one direction is [f] are easy. *)Definitionsplit_idem_sect : split_idem -> X
:= funa => a 0.Arguments split_idem_sect / .
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x)
X -> split_idem
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x)
X -> split_idem
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) x: X
split_idem
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) x: X
nat -> f (f x) = f x
exact (funn => I x).Defined.Arguments split_idem_retr / .Definitionsplit_idem_splits (x : X)
: split_idem_sect (split_idem_retr x) = f x
:= 1.(** What remains is to show that the composite in the other direction is the identity. We begin by showing how to construct paths in [split_idem]. *)
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a, a': split_idem p: a.1 == a'.1 q: foralln : nat,
a.2 n @ p n = ap f (p n.+1) @ a'.2 n
a = a'
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a, a': split_idem p: a.1 == a'.1 q: foralln : nat,
a.2 n @ p n = ap f (p n.+1) @ a'.2 n
a = a'
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a, a': split_idem p: a.1 == a'.1 q: foralln : nat,
a.2 n @ p n = ap f (p n.+1) @ a'.2 n
a.1 = a'.1
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a, a': split_idem p: a.1 == a'.1 q: foralln : nat,
a.2 n @ p n = ap f (p n.+1) @ a'.2 n
transport
(funa : nat -> X =>
foralln : nat, f (a n.+1) = a n) ?p a.2 = a'.2
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a, a': split_idem p: a.1 == a'.1 q: foralln : nat,
a.2 n @ p n = ap f (p n.+1) @ a'.2 n
a.1 = a'.1
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a, a': split_idem p: a.1 == a'.1 q: foralln : nat,
a.2 n @ p n = ap f (p n.+1) @ a'.2 n n: nat
a.1 n = a'.1 n
exact (p n).
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a, a': split_idem p: a.1 == a'.1 q: foralln : nat,
a.2 n @ p n = ap f (p n.+1) @ a'.2 n
transport
(funa : nat -> X =>
foralln : nat, f (a n.+1) = a n)
(path_arrow a.1 a'.1
((funn : nat => p n) : a.1 == a'.1)) a.2 = a'.2
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a, a': split_idem p: a.1 == a'.1 q: foralln : nat,
a.2 n @ p n = ap f (p n.+1) @ a'.2 n n: nat
transport
(funa : nat -> X =>
foralln : nat, f (a n.+1) = a n)
(path_arrow a.1 a'.1 (funn : nat => p n)) a.2 n =
a'.2 n
abstract (
rewrite transport_forall_constant;
rewrite transport_paths_FlFr;
rewrite ap_apply_l, ap10_path_arrow;
rewrite (ap_compose (funb => b n.+1) (funx => f x) _);
rewrite ap_apply_l, ap10_path_arrow;
rewrite concat_pp_p;
apply moveR_Vp; bysymmetry ).Defined.(** And we verify how those paths compute under [split_idem_sect]. *)
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a, a': split_idem p: a.1 == a'.1 q: foralln : nat,
a.2 n @ p n = ap f (p n.+1) @ a'.2 n
ap split_idem_sect (path_split_idem p q) = p 0
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a, a': split_idem p: a.1 == a'.1 q: foralln : nat,
a.2 n @ p n = ap f (p n.+1) @ a'.2 n
ap split_idem_sect (path_split_idem p q) = p 0
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a, a': split_idem p: a.1 == a'.1 q: foralln : nat,
a.2 n @ p n = ap f (p n.+1) @ a'.2 n
ap ((funb : nat -> X => b 0) o pr1)
(path_split_idem p q) = p 0
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a, a': split_idem p: a.1 == a'.1 q: foralln : nat,
a.2 n @ p n = ap f (p n.+1) @ a'.2 n
ap (funb : nat -> X => b 0)
(ap pr1 (path_split_idem p q)) = p 0
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a, a': split_idem p: a.1 == a'.1 q: foralln : nat,
a.2 n @ p n = ap f (p n.+1) @ a'.2 n
ap (funb : nat -> X => b 0)
(path_arrow a.1 a'.1 (funn : nat => p n)) = p 0
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a, a': split_idem p: a.1 == a'.1 q: foralln : nat,
a.2 n @ p n = ap f (p n.+1) @ a'.2 n
ap10 (path_arrow a.1 a'.1 (funn : nat => p n)) 0 =
p 0
apply ap10_path_arrow.Defined.(** Next we show that every element of [split_idem] can be nudged to an equivalent one in which all the elements of [X] occurring are double applications of [f]. *)
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem
split_idem
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem
split_idem
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem
foralln : nat, f (f (f (a n.+2))) = f (f (a n.+1))
exact (funn => ap f (ap f (a.2 n.+1))).Defined.
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem
nudge a = a
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem
nudge a = a
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem
split_idem
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem a':= ?Goal: split_idem
nudge a = a
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem
split_idem
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem
foralln : nat, f (f (a n.+2)) = f (a n.+1)
exact (funn => ap f (a.2 n.+1)).
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem a':= (funn : nat => f (a n.+1);
funn : nat => ap f (a.2 n.+1)): split_idem
nudge a = a
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem a':= (funn : nat => f (a n.+1);
funn : nat => ap f (a.2 n.+1)): split_idem n: nat
f (f (a.1 n.+1)) = f (a.1 n.+1)
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem a':= (funn : nat => f (a n.+1);
funn : nat => ap f (a.2 n.+1)): split_idem n: nat
ap f (ap f (a.2 n.+1)) @ ?Goal =
ap f ?Goal@{n:=n.+1} @ ap f (a.2 n.+1)
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem a':= (funn : nat => f (a n.+1);
funn : nat => ap f (a.2 n.+1)): split_idem n: nat
f (a.1 n.+1) = a.1 n
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem a':= (funn : nat => f (a n.+1);
funn : nat => ap f (a.2 n.+1)): split_idem n: nat
ap f (a.2 n.+1) @ ?Goal1 =
ap f ?Goal1@{n:=n.+1} @ a.2 n
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem a':= (funn : nat => f (a n.+1);
funn : nat => ap f (a.2 n.+1)): split_idem n: nat
f (f (a.1 n.+1)) = f (a.1 n.+1)
exact (I (a n.+1)).
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem a':= (funn : nat => f (a n.+1);
funn : nat => ap f (a.2 n.+1)): split_idem n: nat
ap f (ap f (a.2 n.+1)) @ I (a n.+1) =
ap f (I (a n.+2)) @ ap f (a.2 n.+1)
exact ((ap_compose f f _ @@ 1)^
@ concat_Ap I (a.2 n.+1)
@ (J _ @@ 1)^).
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem a':= (funn : nat => f (a n.+1);
funn : nat => ap f (a.2 n.+1)): split_idem n: nat
f (a.1 n.+1) = a.1 n
exact (a.2 n).
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem a':= (funn : nat => f (a n.+1);
funn : nat => ap f (a.2 n.+1)): split_idem n: nat
ap f (a.2 n.+1) @ a.2 n = ap f (a.2 n.+1) @ a.2 n
reflexivity.Defined.(** Now we're ready to prove the final condition. We prove the two arguments of [path_split_idem] separately, in order to make the first one transparent and the second opaque. *)
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem n: nat
f (f (a n.+1)) = f (a 0)
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem n: nat
f (f (a n.+1)) = f (a 0)
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem
f (f (a 1)) = f (a 0)
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem n: nat IH: f (f (a n.+1)) = f (a 0)
f (f (a n.+2)) = f (a 0)
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem
f (f (a 1)) = f (a 0)
exact (ap f (a.20)).
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem n: nat IH: f (f (a n.+1)) = f (a 0)
f (f (a n.+2)) = f (a 0)
exact (ap f (a.2 n.+1) @ (I (a n.+1))^ @ IH).Defined.
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem n: nat
ap f (ap f (a.2 n.+1)) @ split_idem_issect_part1 a n =
ap f
((ap f (a.2 n.+1) @ (I (a.1 n.+1))^) @
split_idem_issect_part1 a n) @ I (a.10)
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem n: nat
ap f (ap f (a.2 n.+1)) @ split_idem_issect_part1 a n =
ap f
((ap f (a.2 n.+1) @ (I (a.1 n.+1))^) @
split_idem_issect_part1 a n) @ I (a.10)
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem
ap f (ap f (a.21)) @ ap f (a.20) =
ap f ((ap f (a.21) @ (I (a.11))^) @ ap f (a.20)) @
I (a.10)
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem n: nat IH: ap f (ap f (a.2 n.+1)) @
split_idem_issect_part1 a n =
ap f
((ap f (a.2 n.+1) @ (I (a.1 n.+1))^) @
split_idem_issect_part1 a n) @ I (a.10)
ap f (ap f (a.2 n.+2)) @
((ap f (a.2 n.+1) @ (I (a.1 n.+1))^) @
split_idem_issect_part1 a n) =
ap f
((ap f (a.2 n.+2) @ (I (a.1 n.+2))^) @
((ap f (a.2 n.+1) @ (I (a.1 n.+1))^) @
split_idem_issect_part1 a n)) @ I (a.10)
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem
ap f (ap f (a.21))
@' ap f (a.20) =
ap f (ap f (a.21)
@' (I (a.11))^
@' ap f (a.20))
@' I (a.10)
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem n: nat IH: ap f (ap f (a.2 n.+1))
@' split_idem_issect_part1 a n =
ap f
(ap f (a.2 n.+1)
@' (I (a.1 n.+1))^
@' split_idem_issect_part1 a n)
@' I (a.10)
ap f (ap f (a.2 n.+2))
@' (ap f (a.2 n.+1)
@' (I (a.1 n.+1))^
@' split_idem_issect_part1 a n) =
ap f
(ap f (a.2 n.+2)
@' (I (a.1 n.+2))^
@' (ap f (a.2 n.+1)
@' (I (a.1 n.+1))^
@' split_idem_issect_part1 a n))
@' I (a.10)
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem
ap f (ap f (a.21))
@' ap f (a.20) =
ap f (ap f (a.21)
@' (I (a.11))^
@' ap f (a.20))
@' I (a.10)
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem
ap f (ap f (a.21))
@' ap f (a.20) =
ap f (ap f (a.21))
@' ((ap f (I (a.11)))^
@' (ap f (ap f (a.20))
@' I (a.10)))
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem
ap f (I (a.11))
@' ap f (a.20) = ap f (ap f (a.20))
@' I (a.10)
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem
I (f (a.11))
@' ap f (a.20) = ap f (ap f (a.20))
@' I (a.10)
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem n: nat IH: ap f (ap f (a.2 n.+1))
@' split_idem_issect_part1 a n =
ap f
(ap f (a.2 n.+1)
@' (I (a.1 n.+1))^
@' split_idem_issect_part1 a n)
@' I (a.10)
ap f (ap f (a.2 n.+2))
@' (ap f (a.2 n.+1)
@' (I (a.1 n.+1))^
@' split_idem_issect_part1 a n) =
ap f
(ap f (a.2 n.+2)
@' (I (a.1 n.+2))^
@' (ap f (a.2 n.+1)
@' (I (a.1 n.+1))^
@' split_idem_issect_part1 a n))
@' I (a.10)
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem n: nat IH: ap f (ap f (a.2 n.+1))
@' split_idem_issect_part1 a n =
ap f
(ap f (a.2 n.+1)
@' (I (a.1 n.+1))^
@' split_idem_issect_part1 a n)
@' I (a.10)
ap f (ap f (a.2 n.+2))
@' (ap f (a.2 n.+1)
@' (I (a.1 n.+1))^
@' split_idem_issect_part1 a n) =
ap f (ap f (a.2 n.+2)
@' (I (a.1 n.+2))^)
@' ap f
(ap f (a.2 n.+1)
@' (I (a.1 n.+1))^
@' split_idem_issect_part1 a n)
@' I (a.10)
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem n: nat IH: ap f (ap f (a.2 n.+1))
@' split_idem_issect_part1 a n =
ap f
(ap f (a.2 n.+1)
@' (I (a.1 n.+1))^
@' split_idem_issect_part1 a n)
@' I (a.10)
ap f (ap f (a.2 n.+2))
@' (ap f (a.2 n.+1)
@' (I (a.1 n.+1))^
@' split_idem_issect_part1 a n) =
ap f (ap f (a.2 n.+2)
@' (I (a.1 n.+2))^)
@' (ap f (ap f (a.2 n.+1))
@' split_idem_issect_part1 a n)
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem n: nat IH: ap f (ap f (a.2 n.+1))
@' split_idem_issect_part1 a n =
ap f
(ap f (a.2 n.+1)
@' (I (a.1 n.+1))^
@' split_idem_issect_part1 a n)
@' I (a.10)
ap f (ap f (a.2 n.+2))
@' ap f (a.2 n.+1)
@' (I (a.1 n.+1))^
@' split_idem_issect_part1 a n =
ap f (ap f (a.2 n.+2))
@' (ap f (I (a.1 n.+2)))^
@' ap f (ap f (a.2 n.+1))
@' split_idem_issect_part1 a n
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem n: nat IH: ap f (ap f (a.2 n.+1))
@' split_idem_issect_part1 a n =
ap f
(ap f (a.2 n.+1)
@' (I (a.1 n.+1))^
@' split_idem_issect_part1 a n)
@' I (a.10)
ap f (ap f (a.2 n.+2))
@' ap f (a.2 n.+1)
@' (I (a.1 n.+1))^
@' split_idem_issect_part1 a n =
ap f (ap f (a.2 n.+2))
@' (I (f (a.1 n.+2)))^
@' ap f (ap f (a.2 n.+1))
@' split_idem_issect_part1 a n
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem n: nat IH: ap f (ap f (a.2 n.+1))
@' split_idem_issect_part1 a n =
ap f
(ap f (a.2 n.+1)
@' (I (a.1 n.+1))^
@' split_idem_issect_part1 a n)
@' I (a.10)
ap (funx : X => f (f x)) (a.2 n.+2)
@' ap f (a.2 n.+1)
@' (I (a.1 n.+1))^
@' split_idem_issect_part1 a n =
ap (funx : X => f (f x)) (a.2 n.+2)
@' (I (f (a.1 n.+2)))^
@' ap (funx : X => f (f x)) (a.2 n.+1)
@' split_idem_issect_part1 a n
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem
split_idem_retr (split_idem_sect a) = a
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem
split_idem_retr (split_idem_sect a) = a
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem
nudge a = split_idem_retr (split_idem_sect a)
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem
foralln : nat,
(nudge a).2 n @ ?p n =
ap f (?p n.+1) @
(split_idem_retr (split_idem_sect a)).2 n
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) a: split_idem
foralln : nat,
(nudge a).2 n @ split_idem_issect_part1 a n =
ap f (split_idem_issect_part1 a n.+1) @
(split_idem_retr (split_idem_sect a)).2 n
exact (split_idem_issect_part2 a).Defined.Definitionsplit_idem_retract : RetractOf X
:= Build_RetractOf
X split_idem split_idem_retr split_idem_sect split_idem_issect.Definitionsplit_idem_split : Splitting f
:= (split_idem_retract ; split_idem_splits).(** We end this section by showing that we can recover the witness [I] of pre-idempotence from the splitting. *)
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) x: X
ap split_idem_sect
(split_idem_issect (split_idem_retr x)) = I x
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) x: X
ap split_idem_sect
(split_idem_issect (split_idem_retr x)) = I x
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) x: X
ap split_idem_sect
((path_split_idem
(split_idem_issect_part1 (split_idem_retr x))
(split_idem_issect_part2 (split_idem_retr x)))^ @
(path_split_idem
(funn : nat => I (split_idem_retr x n.+1))
(funn : nat =>
((ap_compose f f ((split_idem_retr x).2 n.+1) @@
1)^ @
concat_Ap I ((split_idem_retr x).2 n.+1)) @
(J ((split_idem_retr x).1 n.+2) @@ 1)^) @
path_split_idem
(funn : nat => (split_idem_retr x).2 n)
(funn : nat => 1))) = I x
H: Funext X: Type f: X -> X H0: IsPreIdempotent f H1: IsQuasiIdempotent f I:= isidem f: forallx : X, f (f x) = f x J:= isidem2 f: forallx : X, ap f (I x) = I (f x) x: X
(ap f (I x))^ @ (I (f x) @ I x) = I x
apply moveR_Vp, whiskerR; symmetry; apply J.Qed.(** However, the particular witness [J] of quasi-idempotence can *not* in general be recovered from the splitting; we will mention a counterexample below. This is analogous to how [eissect] and [eisretr] cannot both be recovered after [isequiv_adjointify]; one of them has to be modified. *)EndSplitting.Definitionsplit_idem_retract' `{fs : Funext} {X : Type}
: QuasiIdempotent X -> RetractOf X
:= funf => split_idem_retract f.Definitionsplit_idem_split' `{fs : Funext} {X : Type}
(f : QuasiIdempotent X)
: Splitting f
:= split_idem_split f.(** ** Splitting already-split idempotents *)(** In the other direction, suppose we are given a retract, we deduce from this a quasi-idempotent, and then split it by the above construction. We will show that the resulting retract is equivalent to the original one, so that [RetractOf X] is itelf a retract of [QuasiIdempotent X]. *)SectionAlreadySplit.Context `{fs : Funext}.Context {X : Type} (R : RetractOf X).LetA := retract_type R.Letr := retract_retr R.Lets := retract_sect R.LetH := retract_issect R.(** We begin by constructing an equivalence between [split_idem (s o r)] and [A]. We want to make this equivalence transparent so that we can reason about it later. In fact, we want to reason not only about the equivalence function and its inverse, but the section and retraction homotopies! Therefore, instead of using [equiv_adjointify] we will give the coherence proof explicitly, so that we can control these homotopies. However, we can (and should) make the coherence proof itself opaque. Thus, we prove it first, and end it with [Qed]. *)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: split_idem (s o r)
H (r (s (r (split_idem_sect (s o r) a)))) @
H (r (split_idem_sect (s o r) a)) =
ap (r o split_idem_sect (s o r))
(ap (split_idem_retr (s o r))
(1 @
ap (split_idem_sect (s o r))
(split_idem_issect (s o r) a)) @
split_idem_issect (s o r) a)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: split_idem (s o r)
H (r (s (r (split_idem_sect (s o r) a)))) @
H (r (split_idem_sect (s o r) a)) =
ap (r o split_idem_sect (s o r))
(ap (split_idem_retr (s o r))
(1 @
ap (split_idem_sect (s o r))
(split_idem_issect (s o r) a)) @
split_idem_issect (s o r) a)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: split_idem (s o r)
H
(r
(s (r (split_idem_sect (funx : X => s (r x)) a)))) @
H (r (split_idem_sect (funx : X => s (r x)) a)) =
ap
(funx : split_idem (funx : X => s (r x)) =>
r (split_idem_sect (funx0 : X => s (r x0)) x))
(ap (split_idem_retr (funx : X => s (r x)))
(1 @
ap (split_idem_sect (funx : X => s (r x)))
(split_idem_issect (funx : X => s (r x)) a))) @
ap
(funx : split_idem (funx : X => s (r x)) =>
r (split_idem_sect (funx0 : X => s (r x0)) x))
(split_idem_issect (funx : X => s (r x)) a)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: split_idem (s o r)
H
(r
(s (r (split_idem_sect (funx : X => s (r x)) a)))) @
H (r (split_idem_sect (funx : X => s (r x)) a)) =
ap (funx : X => r (s (r x)))
(1 @
ap (split_idem_sect (funx : X => s (r x)))
(split_idem_issect (funx : X => s (r x)) a)) @
ap
(funx : split_idem (funx : X => s (r x)) =>
r (split_idem_sect (funx0 : X => s (r x0)) x))
(split_idem_issect (funx : X => s (r x)) a)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: split_idem (s o r)
H
(r
(s (r (split_idem_sect (funx : X => s (r x)) a)))) @
H (r (split_idem_sect (funx : X => s (r x)) a)) =
ap (funx : X => r (s (r x)))
(ap (split_idem_sect (funx : X => s (r x)))
(split_idem_issect (funx : X => s (r x)) a)) @
ap
(funx : split_idem (funx : X => s (r x)) =>
r (split_idem_sect (funx0 : X => s (r x0)) x))
(split_idem_issect (funx : X => s (r x)) a)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: split_idem (s o r)
H
(r
(s (r (split_idem_sect (funx : X => s (r x)) a)))) @
H (r (split_idem_sect (funx : X => s (r x)) a)) =
ap
(funx : split_idem (funx : X => s (r x)) =>
r
(s
(r
(split_idem_sect (funx0 : X => s (r x0)) x))))
(split_idem_issect (funx : X => s (r x)) a) @
ap
(funx : split_idem (funx : X => s (r x)) =>
r (split_idem_sect (funx0 : X => s (r x0)) x))
(split_idem_issect (funx : X => s (r x)) a)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: split_idem (s o r)
H
(r
(s (r (split_idem_sect (funx : X => s (r x)) a)))) @
H (r (split_idem_sect (funx : X => s (r x)) a)) =
ap (funx : X => r (s (r x)))
(ap (split_idem_sect (funx : X => s (r x)))
(split_idem_issect (funx : X => s (r x)) a)) @
ap
(funx : split_idem (funx : X => s (r x)) =>
r (split_idem_sect (funx0 : X => s (r x0)) x))
(split_idem_issect (funx : X => s (r x)) a)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: split_idem (s o r)
H
(r
(s (r (split_idem_sect (funx : X => s (r x)) a)))) @
H (r (split_idem_sect (funx : X => s (r x)) a)) =
ap (funx : X => r (s (r x)))
(ap (split_idem_sect (funx : X => s (r x)))
(split_idem_issect (funx : X => s (r x)) a)) @
ap r
(ap (split_idem_sect (funx : X => s (r x)))
(split_idem_issect (funx : X => s (r x)) a))
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: split_idem (s o r)
H
(r
(s (r (split_idem_sect (funx : X => s (r x)) a)))) @
H (r (split_idem_sect (funx : X => s (r x)) a)) =
((ap (funx : X => r (s (r x)))
(ap (funx : X => s (r x)) (a.20)))^ @
(ap (funx : X => r (s (r x)))
(isidem (funx : X => s (r x)) (a 1)) @
ap (funx : X => r (s (r x))) (a.20))) @
((ap r (ap (funx : X => s (r x)) (a.20)))^ @
(ap r (isidem (funx : X => s (r x)) (a 1)) @
ap r (a.20)))
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: split_idem (s o r)
H
(r
(s (r (split_idem_sect (funx : X => s (r x)) a)))) @
H (r (split_idem_sect (funx : X => s (r x)) a)) =
((ap (funx : X => r (s (r x)))
(ap (funx : X => s (r x)) (a.20)))^ @
(ap (funx : X => r (s (r x))) (ap s (H (r (a 1)))) @
ap (funx : X => r (s (r x))) (a.20))) @
((ap r (ap (funx : X => s (r x)) (a.20)))^ @
(ap r (ap s (H (r (a 1)))) @ ap r (a.20)))
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: split_idem (s o r)
H
(r
(s (r (split_idem_sect (funx : X => s (r x)) a)))) @
H (r (split_idem_sect (funx : X => s (r x)) a)) =
(ap (funx : X => r (s (r x)))
(ap (funx : X => s (r x)) (a.20)))^ @
(ap (funx : X => r (s (r x))) (ap s (H (r (a 1)))) @
(ap (funx : X => r (s (r x))) (a.20) @
((ap r (ap (funx : X => s (r x)) (a.20)))^ @
(ap r (ap s (H (r (a 1)))) @ ap r (a.20)))))
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: split_idem (s o r)
H
(r
(s (r (split_idem_sect (funx : X => s (r x)) a)))) @
H (r (split_idem_sect (funx : X => s (r x)) a)) =
(ap (funx : X => r (s (r x)))
(ap (funx : X => s (r x)) (a.20)))^ @
(ap (funx : retract_type R => r (s (r (s x))))
(H (r (a 1))) @
(ap (funx : X => r (s (r x))) (a.20) @
((ap r (ap (funx : X => s (r x)) (a.20)))^ @
(ap (funx : retract_type R => r (s x))
(H (r (a 1))) @ ap r (a.20)))))
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: split_idem (s o r)
H
(r
(s (r (split_idem_sect (funx : X => s (r x)) a)))) @
H (r (split_idem_sect (funx : X => s (r x)) a)) =
(ap (funx : X => r (s (r x)))
(ap (funx : X => s (r x)) (a.20)))^ @
(ap (funx : retract_type R => r (s (r (s x))))
(H (r (a 1))) @
(ap (funx : X => r (s (r x))) (a.20) @
((ap (funx : X => r (s (r x))) (a.20))^ @
(ap (funx : retract_type R => r (s x))
(H (r (a 1))) @ ap r (a.20)))))
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: split_idem (s o r)
H
(r
(s (r (split_idem_sect (funx : X => s (r x)) a)))) @
H (r (split_idem_sect (funx : X => s (r x)) a)) =
(ap (funx : X => r (s (r (s (r x))))) (a.20))^ @
(ap (funx : retract_type R => r (s (r (s x))))
(H (r (a 1))) @
(ap (funx : X => r (s (r x))) (a.20) @
((ap (funx : X => r (s (r x))) (a.20))^ @
(ap (funx : retract_type R => r (s x))
(H (r (a 1))) @ ap r (a.20)))))
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: split_idem (s o r)
H
(r
(s (r (split_idem_sect (funx : X => s (r x)) a)))) @
H (r (split_idem_sect (funx : X => s (r x)) a)) =
(ap (funx : X => r (s (r (s (r x))))) (a.20))^ @
(ap (funx : retract_type R => r (s (r (s x))))
(H (r (a 1))) @
(ap (funx : retract_type R => r (s x)) (H (r (a 1))) @
ap r (a.20)))
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: split_idem (s o r)
(ap (funx : X => r (s (r (s (r x))))) (a.20) @
H
(r
(s
(r (split_idem_sect (funx : X => s (r x)) a))))) @
H (r (split_idem_sect (funx : X => s (r x)) a)) =
(ap (funx : retract_type R => r (s (r (s x))))
(H (r (a 1))) @
ap (funx : retract_type R => r (s x)) (H (r (a 1)))) @
ap r (a.20)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: split_idem (s o r)
(ap (funx : retract_type R => r (s x))
(ap (funx : X => r (s (r x))) (a.20)) @
H
(r
(s
(r (split_idem_sect (funx : X => s (r x)) a))))) @
H (r (split_idem_sect (funx : X => s (r x)) a)) =
(ap (funx : retract_type R => r (s (r (s x))))
(H (r (a 1))) @
ap (funx : retract_type R => r (s x)) (H (r (a 1)))) @
ap r (a.20)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: split_idem (s o r)
(H (r (s (r (s (r (a.11)))))) @
ap (funx : X => r (s (r x))) (a.20)) @
H (r (split_idem_sect (funx : X => s (r x)) a)) =
(ap (funx : retract_type R => r (s (r (s x))))
(H (r (a 1))) @
ap (funx : retract_type R => r (s x)) (H (r (a 1)))) @
ap r (a.20)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: split_idem (s o r)
(H (r (s (r (s (r (a.11)))))) @
ap (funx : retract_type R => r (s x)) (ap r (a.20))) @
H (r (split_idem_sect (funx : X => s (r x)) a)) =
(ap (funx : retract_type R => r (s (r (s x))))
(H (r (a 1))) @
ap (funx : retract_type R => r (s x)) (H (r (a 1)))) @
ap r (a.20)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: split_idem (s o r)
(H (r (s (r (s (r (a.11)))))) @ H (r (s (r (a.11))))) @
ap r (a.20) =
(ap (funx : retract_type R => r (s (r (s x))))
(H (r (a 1))) @
ap (funx : retract_type R => r (s x)) (H (r (a 1)))) @
ap r (a.20)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: split_idem (s o r)
H (r (s (r (s (r (a.11)))))) @ H (r (s (r (a.11)))) =
ap (funx : retract_type R => r (s (r (s x))))
(H (r (a 1))) @
ap (funx : retract_type R => r (s x)) (H (r (a 1)))
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: split_idem (s o r)
(H (r (s (r (s (r (a.11)))))) @ H (r (s (r (a.11))))) @
H (r (a.11)) =
(ap (funx : retract_type R => r (s (r (s x))))
(H (r (a 1))) @
ap (funx : retract_type R => r (s x)) (H (r (a 1)))) @
H (r (a.11))
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: split_idem (s o r)
(H (r (s (r (s (r (a.11)))))) @ H (r (s (r (a.11))))) @
H (r (a.11)) =
(ap (funx : retract_type R => r (s (r (s x))))
(H (r (a 1))) @
H (retract_retr R (retract_sect R (r (a 1))))) @
H (r (a 1))
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: split_idem (s o r)
ap (funx : retract_type R => r (s (r (s x))))
(H (r (a 1))) @
(H (retract_retr R (retract_sect R (r (a 1)))) @
H (r (a 1))) =
(H (r (s (r (s (r (a.11)))))) @ H (r (s (r (a.11))))) @
H (r (a.11))
exact (concat_A1p (funx => H (r (s x)) @ H x) (H (r (a 1%nat)))).Qed.(** Now we can construct the desired equivalence. *)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap
split_idem (s o r) <~> A
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap
split_idem (s o r) <~> A
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap
(funx : split_idem (s o r) =>
r (split_idem_sect (s o r) x))
o (split_idem_retr (s o r) o s) == idmap
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap
split_idem_retr (s o r) o s
o (funx : split_idem (s o r) =>
r (split_idem_sect (s o r) x)) == idmap
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap
forallx : split_idem (s o r),
?eisretr
((funx0 : split_idem (s o r) =>
r (split_idem_sect (s o r) x0)) x) =
ap
(funx0 : split_idem (s o r) =>
r (split_idem_sect (s o r) x0)) (?eissect x)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap
(funx : split_idem (s o r) =>
r (split_idem_sect (s o r) x))
o (split_idem_retr (s o r) o s) == idmap
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: retract_type R
r (s (r (s a))) = a
exact (H _ @ H _).
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap
split_idem_retr (s o r) o s
o (funx : split_idem (s o r) =>
r (split_idem_sect (s o r) x)) == idmap
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: split_idem (funx : X => s (r x))
split_idem_retr (funx : X => s (r x))
(s (r (split_idem_sect (funx : X => s (r x)) a))) =
a
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: split_idem (funx : X => s (r x))
split_idem_retr (funx : X => s (r x))
(s (r (split_idem_sect (funx : X => s (r x)) a))) =
split_idem_retr (funx : X => s (r x))
(split_idem_sect (funx : X => s (r x)) a)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: split_idem (funx : X => s (r x))
s (r (split_idem_sect (funx : X => s (r x)) a)) =
split_idem_sect (funx : X => s (r x)) a
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: split_idem (funx : X => s (r x))
split_idem_sect (funx : X => s (r x))
(split_idem_retr (funx : X => s (r x))
(split_idem_sect (funx : X => s (r x)) a)) =
split_idem_sect (funx : X => s (r x)) a
apply ap, split_idem_issect; exact _.
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap
forallx : split_idem (s o r),
((funa : retract_type R =>
H (retract_retr R (retract_sect R a)) @ H a
:
r
(split_idem_sect (funx0 : X => s (r x0))
(split_idem_retr (funx0 : X => s (r x0)) (s a))) =
a)
:
(funx0 : split_idem (s o r) =>
r (split_idem_sect (s o r) x0))
o (split_idem_retr (s o r) o s) == idmap)
((funx0 : split_idem (s o r) =>
r (split_idem_sect (s o r) x0)) x) =
ap
(funx0 : split_idem (s o r) =>
r (split_idem_sect (s o r) x0))
(((funa : split_idem (funx0 : X => s (r x0)) =>
ap (split_idem_retr (funx0 : X => s (r x0)))
((split_idem_splits (s o r)
(split_idem_sect (funx0 : X => s (r x0)) a))^ @
ap (split_idem_sect (funx0 : X => s (r x0)))
(split_idem_issect (funx0 : X => s (r x0))
a)) @ split_idem_issect (s o r) a
:
split_idem_retr (funx0 : X => s (r x0))
(s
(r
(split_idem_sect (funx0 : X => s (r x0))
a))) = a)
:
split_idem_retr (s o r) o s
o (funx0 : split_idem (s o r) =>
r (split_idem_sect (s o r) x0)) == idmap) x)
intros a; simpl; apply equiv_split_idem_retract_isadj.Defined.(** It is easy to show that this equivalence respects the section and the retraction. *)Definitionequiv_split_idem_retract_retr (x : X)
: equiv_split_idem_retract (split_idem_retr (s o r) x) = r x
:= H (r x).Definitionequiv_split_idem_retract_sect (a : A)
: split_idem_sect (s o r) (equiv_split_idem_retract^-1 a) = s a
:= ap s (H a).(** Less trivial is to show that it respects the retract homotopy. *)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: A
ap equiv_split_idem_retract
(split_idem_issect (s o r)
(equiv_split_idem_retract^-1 a)) @
eisretr equiv_split_idem_retract a =
(equiv_split_idem_retract_retr
(split_idem_sect (s o r)
(equiv_split_idem_retract^-1 a)) @
ap r (equiv_split_idem_retract_sect a)) @ H a
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: A
ap equiv_split_idem_retract
(split_idem_issect (s o r)
(equiv_split_idem_retract^-1 a)) @
eisretr equiv_split_idem_retract a =
(equiv_split_idem_retract_retr
(split_idem_sect (s o r)
(equiv_split_idem_retract^-1 a)) @
ap r (equiv_split_idem_retract_sect a)) @ H a
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: A
ap
(funx : split_idem (funx : X => s (r x)) =>
r (split_idem_sect (funx0 : X => s (r x0)) x))
(split_idem_issect (funx : X => s (r x))
(split_idem_retr (funx : X => s (r x)) (s a))) @
(H (retract_retr R (retract_sect R a)) @ H a) =
(equiv_split_idem_retract_retr (s (r (s a))) @
ap r (equiv_split_idem_retract_sect a)) @ H a
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: A
ap
(funx : split_idem (funx : X => s (r x)) =>
r (split_idem_sect (funx0 : X => s (r x0)) x))
(split_idem_issect (funx : X => s (r x))
(split_idem_retr (funx : X => s (r x)) (s a))) @
(H (retract_retr R (retract_sect R a)) @ H a) =
(H (r (s (r (s a)))) @ ap r (ap s (H a))) @ H a
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: A
ap r
(ap (split_idem_sect (funx : X => s (r x)))
(split_idem_issect (funx : X => s (r x))
(split_idem_retr (funx : X => s (r x)) (s a)))) @
(H (retract_retr R (retract_sect R a)) @ H a) =
(H (r (s (r (s a)))) @ ap r (ap s (H a))) @ H a
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: A
ap r
(ap (split_idem_sect (funx : X => s (r x)))
((path_split_idem (funx : X => s (r x))
(split_idem_issect_part1
(funx : X => s (r x))
(split_idem_retr (funx : X => s (r x))
(s a)))
(split_idem_issect_part2
(funx : X => s (r x))
(split_idem_retr (funx : X => s (r x))
(s a))))^ @
(path_split_idem (funx : X => s (r x))
(funn : nat =>
isidem (funx : X => s (r x))
(split_idem_retr (funx : X => s (r x))
(s a) n.+1))
(funn : nat =>
((ap_compose (funx : X => s (r x))
(funx : X => s (r x))
((split_idem_retr (funx : X => s (r x))
(s a)).2 n.+1) @@ 1)^ @
concat_Ap (isidem (funx : X => s (r x)))
((split_idem_retr (funx : X => s (r x))
(s a)).2 n.+1)) @
(isidem2 (funx : X => s (r x))
((split_idem_retr (funx : X => s (r x))
(s a)).1 n.+2) @@ 1)^) @
path_split_idem (funx : X => s (r x))
(funn : nat =>
(split_idem_retr (funx : X => s (r x))
(s a)).2 n) (funn : nat => 1)))) @
(H (retract_retr R (retract_sect R a)) @ H a) =
(H (r (s (r (s a)))) @ ap r (ap s (H a))) @ H a
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: A
((ap r
(ap (funx : X => s (r x))
(isidem (funx : X => s (r x)) (s a))))^ @
(ap r (isidem (funx : X => s (r x)) (s (r (s a)))) @
ap r (isidem (funx : X => s (r x)) (s a)))) @
(H (retract_retr R (retract_sect R a)) @ H a) =
(H (r (s (r (s a)))) @ ap r (ap s (H a))) @ H a
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: A
((ap r
(ap (funx : X => s (r x)) (ap s (H (r (s a))))))^ @
(ap r (ap s (H (r (s (r (s a)))))) @
ap r (ap s (H (r (s a)))))) @ (H (r (s a)) @ H a) =
(H (r (s (r (s a)))) @ ap r (ap s (H a))) @ H a
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: A
(ap r (ap (funx : X => s (r x)) (ap s (H (r (s a))))))^
@' (ap r (ap s (H (r (s (r (s a))))))
@' ap r (ap s (H (r (s a)))))
@' (H (r (s a))
@' H a) =
H (r (s (r (s a))))
@' ap r (ap s (H a))
@' H a
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: A
ap r (ap s (H (r (s (r (s a))))))
@' ap r (ap s (H (r (s a))))
@' H (r (s a))
@' H a =
ap r (ap (funx : X => s (r x)) (ap s (H (r (s a)))))
@' H (r (s (r (s a))))
@' ap r (ap s (H a))
@' H a
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: A
ap (funx : A => r (s x)) (H (r (s (r (s a)))))
@' ap (funx : A => r (s x)) (H (r (s a)))
@' H (r (s a))
@' H a =
ap r (ap (funx : A => s (r (s x))) (H (r (s a))))
@' H (r (s (r (s a))))
@' ap (funx : A => r (s x)) (H a)
@' H a
(** For some reason this last one needs help. *)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: A
ap (funx : A => r (s x)) (H (r (s (r (s a)))))
@' ap (funx : A => r (s x)) (H (r (s a)))
@' H (r (s a))
@' H a =
ap (funx : retract_type R => r (s (r (s x))))
(H (r (s a)))
@' H (r (s (r (s a))))
@' ap (funx : A => r (s x)) (H a)
@' H a
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: A
ap (funx : retract_type R => r (s x))
(H (r (s (r (s a))))
@' H (r (s a)))
@' H (r (s a))
@' H a =
ap (funx : retract_type R => r (s (r (s x))))
(H (r (s a)))
@' H (r (s (r (s a))))
@' ap (funx : A => r (s x)) (H a)
@' H a
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: A
ap (funx : retract_type R => r (s x))
(ap
(funx : retract_type R =>
retract_retr R (retract_sect R x)) (H (r (s a)))
@' H (r (s a)))
@' H (r (s a))
@' H a =
ap (funx : retract_type R => r (s (r (s x))))
(H (r (s a)))
@' H (r (s (r (s a))))
@' ap (funx : A => r (s x)) (H a)
@' H a
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: A
ap (funx : retract_type R => r (s x))
(ap
(funx : retract_type R =>
retract_retr R (retract_sect R x)) (H (r (s a))))
@' ap (funx : retract_type R => r (s x))
(H (r (s a)))
@' H (r (s a))
@' H a =
ap (funx : retract_type R => r (s (r (s x))))
(H (r (s a)))
@' H (r (s (r (s a))))
@' ap (funx : A => r (s x)) (H a)
@' H a
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: A
ap (funx : retract_type R => r (s (r (s x))))
(H (r (s a)))
@' ap (funx : retract_type R => r (s x))
(H (r (s a)))
@' H (r (s a))
@' H a =
ap (funx : retract_type R => r (s (r (s x))))
(H (r (s a)))
@' H (r (s (r (s a))))
@' ap (funx : A => r (s x)) (H a)
@' H a
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: A
ap (funx : retract_type R => r (s x)) (H (r (s a)))
@' H (r (s a))
@' H a =
H (r (s (r (s a))))
@' ap (funx : A => r (s x)) (H a)
@' H a
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: A
H (retract_retr R (retract_sect R (r (s a))))
@' H (r (s a))
@' H a =
H (r (s (r (s a))))
@' ap (funx : A => r (s x)) (H a)
@' H a
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap a: A
H (r (s a))
@' H a = ap (funx : A => r (s x)) (H a)
@' H a
symmetry; refine (concat_A1p H (H a)).Close Scope long_path_scope.Qed.(** We will also show that it respects the homotopy to the split map. It's unclear whether this has any use. *)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap x: X
split_idem_splits (s o r) x =
(ap (split_idem_sect (s o r))
(eissect equiv_split_idem_retract
(split_idem_retr (s o r) x))^ @
equiv_split_idem_retract_sect
(equiv_split_idem_retract
(split_idem_retr (s o r) x))) @
ap s (equiv_split_idem_retract_retr x)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap x: X
split_idem_splits (s o r) x =
(ap (split_idem_sect (s o r))
(eissect equiv_split_idem_retract
(split_idem_retr (s o r) x))^ @
equiv_split_idem_retract_sect
(equiv_split_idem_retract
(split_idem_retr (s o r) x))) @
ap s (equiv_split_idem_retract_retr x)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap x: X
split_idem_splits (funx : X => s (r x)) x =
(ap (split_idem_sect (funx : X => s (r x)))
(ap (split_idem_retr (funx : X => s (r x)))
(1 @
ap (split_idem_sect (funx : X => s (r x)))
(split_idem_issect (funx : X => s (r x))
(split_idem_retr (funx : X => s (r x)) x))) @
split_idem_issect (funx : X => s (r x))
(split_idem_retr (funx : X => s (r x)) x))^ @
equiv_split_idem_retract_sect (r (s (r x)))) @
ap s (equiv_split_idem_retract_retr x)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap x: X
1 =
(ap (split_idem_sect (funx : X => s (r x)))
(ap (split_idem_retr (funx : X => s (r x)))
(1 @
ap (split_idem_sect (funx : X => s (r x)))
(split_idem_issect (funx : X => s (r x))
(split_idem_retr (funx : X => s (r x)) x))) @
split_idem_issect (funx : X => s (r x))
(split_idem_retr (funx : X => s (r x)) x))^ @
ap s (H (r (s (r x))))) @ ap s (H (r x))
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap x: X
ap (split_idem_sect (funx : X => s (r x)))
(ap (split_idem_retr (funx : X => s (r x)))
(ap (split_idem_sect (funx : X => s (r x)))
(split_idem_issect (funx : X => s (r x))
(split_idem_retr (funx : X => s (r x)) x))) @
split_idem_issect (funx : X => s (r x))
(split_idem_retr (funx : X => s (r x)) x)) =
ap s (H (r (s (r x)))) @ ap s (H (r x))
(** Brace yourself. *)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap x: X
ap (split_idem_sect (funx : X => s (r x)))
(ap (split_idem_retr (funx : X => s (r x)))
(ap (split_idem_sect (funx : X => s (r x)))
((path_split_idem (funx : X => s (r x))
(split_idem_issect_part1
(funx : X => s (r x))
(split_idem_retr (funx : X => s (r x))
x))
(split_idem_issect_part2
(funx : X => s (r x))
(split_idem_retr (funx : X => s (r x))
x)))^ @
(path_split_idem (funx : X => s (r x))
(funn : nat =>
isidem (funx : X => s (r x))
(split_idem_retr (funx : X => s (r x))
x n.+1))
(funn : nat =>
((ap_compose (funx : X => s (r x))
(funx : X => s (r x))
((split_idem_retr (fun ... => s ...)
x).2 n.+1) @@ 1)^ @
concat_Ap
(isidem (funx : X => s (r x)))
((split_idem_retr
(funx : X => s (r x)) x).2 n.+1)) @
(isidem2 (funx : X => s (r x))
((split_idem_retr
(funx : X => s (r x)) x).1 n.+2) @@
1)^) @
path_split_idem (funx : X => s (r x))
(funn : nat =>
(split_idem_retr (funx : X => s (r x)) x).2
n) (funn : nat => 1)))) @
((path_split_idem (funx : X => s (r x))
(split_idem_issect_part1 (funx : X => s (r x))
(split_idem_retr (funx : X => s (r x)) x))
(split_idem_issect_part2 (funx : X => s (r x))
(split_idem_retr (funx : X => s (r x)) x)))^ @
(path_split_idem (funx : X => s (r x))
(funn : nat =>
isidem (funx : X => s (r x))
(split_idem_retr (funx : X => s (r x)) x
n.+1))
(funn : nat =>
((ap_compose (funx : X => s (r x))
(funx : X => s (r x))
((split_idem_retr (funx : X => s (r x)) x).2
n.+1) @@ 1)^ @
concat_Ap (isidem (funx : X => s (r x)))
((split_idem_retr (funx : X => s (r x)) x).2
n.+1)) @
(isidem2 (funx : X => s (r x))
((split_idem_retr (funx : X => s (r x)) x).1
n.+2) @@ 1)^) @
path_split_idem (funx : X => s (r x))
(funn : nat =>
(split_idem_retr (funx : X => s (r x)) x).2 n)
(funn : nat => 1)))) =
ap s (H (r (s (r x)))) @ ap s (H (r x))
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap x: X
((ap (split_idem_sect (funx : X => s (r x)))
(ap (split_idem_retr (funx : X => s (r x)))
(ap (funx : X => s (r x))
(isidem (funx : X => s (r x)) x))))^ @
(ap (split_idem_sect (funx : X => s (r x)))
(ap (split_idem_retr (funx : X => s (r x)))
(isidem (funx : X => s (r x)) (s (r x)))) @
ap (split_idem_sect (funx : X => s (r x)))
(ap (split_idem_retr (funx : X => s (r x)))
(isidem (funx : X => s (r x)) x)))) @
((ap (funx : X => s (r x))
(isidem (funx : X => s (r x)) x))^ @
(isidem (funx : X => s (r x)) (s (r x)) @
isidem (funx : X => s (r x)) x)) =
ap s (H (r (s (r x)))) @ ap s (H (r x))
(** Whew, that's not so bad. *)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap x: X
((ap (split_idem_sect (funx : X => s (r x)))
(ap (split_idem_retr (funx : X => s (r x)))
(ap (funx : X => s (r x)) (ap s (H (r x))))))^ @
(ap (split_idem_sect (funx : X => s (r x)))
(ap (split_idem_retr (funx : X => s (r x)))
(ap s (H (r (s (r x)))))) @
ap (split_idem_sect (funx : X => s (r x)))
(ap (split_idem_retr (funx : X => s (r x)))
(ap s (H (r x)))))) @
((ap (funx : X => s (r x)) (ap s (H (r x))))^ @
(ap s (H (r (s (r x)))) @ ap s (H (r x)))) =
ap s (H (r (s (r x)))) @ ap s (H (r x))
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap x: X
(ap (split_idem_sect (funx : X => s (r x)))
(ap (split_idem_retr (funx : X => s (r x)))
(ap (funx : X => s (r x)) (ap s (H (r x))))))^
@' (ap (split_idem_sect (funx : X => s (r x)))
(ap (split_idem_retr (funx : X => s (r x)))
(ap s (H (r (s (r x))))))
@' ap (split_idem_sect (funx : X => s (r x)))
(ap (split_idem_retr (funx : X => s (r x)))
(ap s (H (r x)))))
@' ((ap (funx : X => s (r x)) (ap s (H (r x))))^
@' (ap s (H (r (s (r x))))
@' ap s (H (r x)))) =
ap s (H (r (s (r x))))
@' ap s (H (r x))
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap x: X
(ap (split_idem_sect (funx : X => s (r x)))
(ap (split_idem_retr (funx : X => s (r x)))
(ap (funx : X => s (r x)) (ap s (H (r x))))))^
@' ap (split_idem_sect (funx : X => s (r x)))
(ap (split_idem_retr (funx : X => s (r x)))
(ap s (H (r (s (r x))))))
@' ap (split_idem_sect (funx : X => s (r x)))
(ap (split_idem_retr (funx : X => s (r x)))
(ap s (H (r x))))
@' (ap (funx : X => s (r x)) (ap s (H (r x))))^
@' ap s (H (r (s (r x))))
@' ap s (H (r x)) =
ap s (H (r (s (r x))))
@' ap s (H (r x))
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap x: X
(ap (funx : X => s (r x))
(ap (funx : A => s (r (s x))) (H (r x))))^
@' ap (funx : A => s (r (s x))) (H (r (s (r x))))
@' ap (funx : A => s (r (s x))) (H (r x))
@' (ap (funx : A => s (r (s x))) (H (r x)))^
@' ap s (H (r (s (r x))))
@' ap s (H (r x)) =
ap s (H (r (s (r x))))
@' ap s (H (r x))
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap x: X
(ap (funx : X => s (r x))
(ap (funx : A => s (r (s x))) (H (r x))))^
@' ap (funx : A => s (r (s x))) (H (r (s (r x))))
@' ap (funx : A => s (r (s x))) (H (r x))
@' (ap (funx : A => s (r (s x))) (H (r x)))^
@' ap s (H (r (s (r x)))) = ap s (H (r (s (r x))))
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap x: X
(ap (funx : X => s (r x))
(ap (funx : A => s (r (s x))) (H (r x))))^
@' ap (funx : A => s (r (s x))) (H (r (s (r x))))
@' ap (funx : A => s (r (s x))) (H (r x))
@' (ap (funx : A => s (r (s x))) (H (r x)))^ = 1
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap x: X
ap (funx : A => s (r (s x))) (H (r (s (r x))))
@' ap (funx : A => s (r (s x))) (H (r x)) =
ap (funx : X => s (r x))
(ap (funx : A => s (r (s x))) (H (r x)))
@' ap (funx : A => s (r (s x))) (H (r x))
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap x: X
ap (funx : A => s (r (s x))) (H (r (s (r x))))
@' ap (funx : A => s (r (s x))) (H (r x)) =
ap (funx : retract_type R => s (r (s (r (s x)))))
(H (r x))
@' ap (funx : A => s (r (s x))) (H (r x))
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap x: X
ap s
(ap (funx : retract_type R => r (s x))
(H (r (s (r x)))))
@' ap (funx : A => s (r (s x))) (H (r x)) =
ap (funx : retract_type R => s (r (s (r (s x)))))
(H (r x))
@' ap (funx : A => s (r (s x))) (H (r x))
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap x: X
ap s
(ap (funx : retract_type R => r (s x))
(H (r (s (r x)))))
@' ap s
(ap (funx : retract_type R => r (s x)) (H (r x))) =
ap (funx : retract_type R => s (r (s (r (s x)))))
(H (r x))
@' ap s
(ap (funx : retract_type R => r (s x)) (H (r x)))
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap x: X
ap s
(ap (funx : retract_type R => r (s x))
(H (r (s (r x)))))
@' ap s
(ap (funx : retract_type R => r (s x)) (H (r x))) =
ap s
(ap (funx : retract_type R => r (s (r (s x))))
(H (r x)))
@' ap s
(ap (funx : retract_type R => r (s x)) (H (r x)))
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap x: X
ap (funx : retract_type R => r (s x))
(H (r (s (r x))))
@' ap (funx : retract_type R => r (s x)) (H (r x)) =
ap (funx : retract_type R => r (s (r (s x))))
(H (r x))
@' ap (funx : retract_type R => r (s x)) (H (r x))
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap x: X
ap (funx : retract_type R => r (s x))
(H (r (s (r x))))
@' ap (funx : retract_type R => r (s x)) (H (r x))
@' H (r x) =
ap (funx : retract_type R => r (s (r (s x))))
(H (r x))
@' ap (funx : retract_type R => r (s x)) (H (r x))
@' H (r x)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap x: X
ap (funx : retract_type R => r (s x))
(H (r (s (r x))))
@' H (retract_retr R (retract_sect R (r x)))
@' H (r x) =
ap (funx : retract_type R => r (s (r (s x))))
(H (r x))
@' ap (funx : retract_type R => r (s x)) (H (r x))
@' H (r x)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap x: X
ap (funx : retract_type R => r (s x))
(H (r (s (r x))))
@' H (retract_retr R (retract_sect R (r x)))
@' H (r x) =
ap (funx : retract_type R => r (s (r (s x))))
(H (r x))
@' H (retract_retr R (retract_sect R (r x)))
@' H (r x)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap x: X
H (retract_retr R (retract_sect R (r (s (r x)))))
@' H (r (s (r x)))
@' H (r x) =
ap (funx : retract_type R => r (s (r (s x))))
(H (r x))
@' H (retract_retr R (retract_sect R (r x)))
@' H (r x)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap x: X
H (retract_retr R (retract_sect R (r (s (r x)))))
@' H (r (s (r x)))
@' H (r x) =
ap (funx : retract_type R => r (s x))
(ap (funx : retract_type R => r (s x)) (H (r x)))
@' H (retract_retr R (retract_sect R (r x)))
@' H (r x)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap x: X
H (retract_retr R (retract_sect R (r (s (r x)))))
@' H (r (s (r x)))
@' H (r x) =
H (r (s (retract_retr R (retract_sect R (r x)))))
@' ap (funx : retract_type R => r (s x)) (H (r x))
@' H (r x)
fs: Funext X: Type R: RetractOf X A:= retract_type R: Type r:= retract_retr R: X -> retract_type R s:= retract_sect R: retract_type R -> X H:= retract_issect R: retract_retr R o retract_sect R == idmap x: X
H (r (s (r x)))
@' H (r x) =
ap (funx : retract_type R => r (s x)) (H (r x))
@' H (r x)
symmetry; refine (concat_A1p H (H (r x))).Close Scope long_path_scope.Qed.EndAlreadySplit.(** Using these facts, we can show that [RetractOf X] is a retract of [QuasiIdempotent X]. *)SectionRetractOfRetracts.Context `{ua : Univalence} {X : Type}.
ua: Univalence X: Type
RetractOf (QuasiIdempotent X)
ua: Univalence X: Type
RetractOf (QuasiIdempotent X)
ua: Univalence X: Type
(funx : RetractOf X =>
split_idem_retract' (qidem_retract x)) == idmap
ua: Univalence X: Type R: RetractOf X
split_idem_retract' (qidem_retract R) = R
exact (@path_retractof _ _
(split_idem_retract' (qidem_retract R)) R
(equiv_split_idem_retract R)
(equiv_split_idem_retract_retr R)
(equiv_split_idem_retract_sect R)
(equiv_split_idem_retract_issect R)).Defined.(** We have a similar result for splittings of a fixed map [f]. *)
ua: Univalence X: Type f: X -> X
RetractOf
{I : IsPreIdempotent f & IsQuasiIdempotent f}
ua: Univalence X: Type f: X -> X
RetractOf
{I : IsPreIdempotent f & IsQuasiIdempotent f}
ua: Univalence X: Type f: X -> X
hfiber quasiidempotent_pr1 f <~>
{I : IsPreIdempotent f & IsQuasiIdempotent f}
ua: Univalence X: Type f: X -> X
retract_type
(retractof_equiv' ?f
(retractof_hfiber retract_retractof_qidem
quasiidempotent_pr1 retract_idem
(funx : QuasiIdempotent X => 1) f)) <~>
Splitting f
ua: Univalence X: Type f: X -> X
hfiber quasiidempotent_pr1 f <~>
{I : IsPreIdempotent f & IsQuasiIdempotent f}
ua: Univalence X: Type f: X -> X
hfiber quasiidempotent_pr1 f <~> hfiber pr1 f
ua: Univalence X: Type f: X -> X
{x : QuasiIdempotent X & x = f} <~>
{x
: {g : X -> X &
{I : IsPreIdempotent g & IsQuasiIdempotent g}} &
x.1 = f}
ua: Univalence X: Type f: X -> X a: {f : PreIdempotent X & IsQuasiIdempotent f}
a = f <~> (a.1).1 = f
ua: Univalence X: Type f, g: X -> X I: IsPreIdempotent g J: IsQuasiIdempotent (g; I)
g = f <~> g = f
exact equiv_idmap.
ua: Univalence X: Type f: X -> X
retract_type
(retractof_equiv'
((hfiber_fibration f
(fung : X -> X =>
{I : IsPreIdempotent g &
IsQuasiIdempotent g}))^-1
oE (equiv_functor_sigma'
(equiv_sigma_assoc IsPreIdempotent
(funf : PreIdempotent X =>
IsQuasiIdempotent f))^-1
(funa : {f : PreIdempotent X &
IsQuasiIdempotent f} =>
(funproj2 : {a0 : X -> X &
IsPreIdempotent a0} =>
(fun (g : X -> X)
(I : IsPreIdempotent g)
(J : IsQuasiIdempotent (g; I)) =>
(1 : ((g; I); J).1 = f <~> g = f)
:
((g; I); J) = f <~> g = f) proj2.1
proj2.2) a.1 a.2
:
a = f <~>
((equiv_sigma_assoc IsPreIdempotent
(funf : PreIdempotent X =>
IsQuasiIdempotent f))^-1 a).1 = f)
:
hfiber quasiidempotent_pr1 f <~>
hfiber pr1 f))
(retractof_hfiber retract_retractof_qidem
quasiidempotent_pr1 retract_idem
(funx : QuasiIdempotent X => 1) f)) <~>
Splitting f
ua: Univalence X: Type f: X -> X
hfiber retract_idem f <~> Splitting f
ua: Univalence X: Type f: X -> X
{x : RetractOf X & retract_idem x = f} <~>
{R : RetractOf X & retract_idem R == f}
ua: Univalence X: Type f: X -> X R: RetractOf X
(funx : X => retract_sect R (retract_retr R x)) = f <~>
(funx : X => retract_sect R (retract_retr R x)) == f
apply equiv_ap10.Defined.(** And also for splittings of a fixed map that also induce a given witness of pre-idempotency. *)DefinitionSplitting_PreIdempotent (f : PreIdempotent X)
:= { S : Splitting f &
forallx, ap f (S.2 x)^
@ (S.2 (retract_idem S.1 x))^
@ ap (retract_sect S.1) (retract_issect S.1 (retract_retr S.1 x))
@ S.2 x
= (isidem f x) }.
ua: Univalence X: Type f: PreIdempotent X
RetractOf (IsQuasiIdempotent f)
ua: Univalence X: Type f: PreIdempotent X
RetractOf (IsQuasiIdempotent f)
ua: Univalence X: Type f: PreIdempotent X
hfiber pr1 f <~> IsQuasiIdempotent f
ua: Univalence X: Type f: PreIdempotent X
preidem_retract o retract_retr retract_retractof_qidem ==
pr1
retract_type
(retractof_equiv'
(hfiber_fibration f
(funfi : {x : _ & IsPreIdempotent x} =>
IsQuasiIdempotent fi.1))^-1
(retractof_hfiber retract_retractof_qidem pr1
preidem_retract
((funx : QuasiIdempotent X =>
(funproj2 : PreIdempotent X =>
(fun (g : X -> X) (I : IsPreIdempotent g)
(J : IsQuasiIdempotent (g; I)) =>
path_sigma'
(funf : X -> X => IsPreIdempotent f) 1
(path_forall
(funx0 : X =>
ap (split_idem_sect (...; J))
(split_idem_issect (...; J) (...)))
I
((funx0 : X =>
split_idem_preidem (...; J) x0)
:
(fun ... => ap ... ...) == I)
:
transport
(funf : X -> X => IsPreIdempotent f)
1
(funx0 : X =>
ap (split_idem_sect ...)
(split_idem_issect ... ...)) = I)
:
preidem_retract
(retract_retr retract_retractof_qidem
((g; I); J)) = ((g; I); J).1) proj2.1
proj2.2) x.1 x.2)
:
preidem_retract
o retract_retr retract_retractof_qidem == pr1)
f)) <~> Splitting_PreIdempotent f
ua: Univalence X: Type f: PreIdempotent X
{x : RetractOf X &
(funx0 : X => retract_sect x (retract_retr x x0);
funx0 : X =>
ap (retract_sect x)
(retract_issect x (retract_retr x x0))) = f} <~>
Splitting_PreIdempotent f
ua: Univalence X: Type f: PreIdempotent X
{x : RetractOf X &
(funx0 : X => retract_sect x (retract_retr x x0);
funx0 : X =>
ap (retract_sect x)
(retract_issect x (retract_retr x x0))) = f} <~>
{a : RetractOf X &
{p : retract_idem a == f &
forallx : X,
((ap f ((a; p).2 x)^ @
((a; p).2 (retract_idem (a; p).1 x))^) @
ap (retract_sect (a; p).1)
(retract_issect (a; p).1 (retract_retr (a; p).1 x))) @
(a; p).2 x = isidem f x}}
ua: Univalence X: Type f: PreIdempotent X R: RetractOf X
(funx : X => retract_sect R (retract_retr R x);
funx : X =>
ap (retract_sect R)
(retract_issect R (retract_retr R x))) = f <~>
{p
: (funx : X => retract_sect R (retract_retr R x)) ==
f &
forallx : X,
((ap f (p x)^ @
(p (retract_sect R (retract_retr R x)))^) @
ap (retract_sect R)
(retract_issect R (retract_retr R x))) @ p x =
isidem f x}
ua: Univalence X: Type f: PreIdempotent X R: RetractOf X
{p
: (funx : X => retract_sect R (retract_retr R x)) =
f.1 &
transport (funf : X -> X => IsPreIdempotent f) p
(funx : X =>
ap (retract_sect R)
(retract_issect R (retract_retr R x))) = f.2} <~>
{p
: (funx : X => retract_sect R (retract_retr R x)) ==
f &
forallx : X,
((ap f (p x)^ @
(p (retract_sect R (retract_retr R x)))^) @
ap (retract_sect R)
(retract_issect R (retract_retr R x))) @ p x =
isidem f x}
ua: Univalence X: Type f: PreIdempotent X R: RetractOf X H: (funx : X => retract_sect R (retract_retr R x)) =
f.1
transport (funf : X -> X => IsPreIdempotent f) H
(funx : X =>
ap (retract_sect R)
(retract_issect R (retract_retr R x))) = f.2 <~>
(forallx : X,
((ap f (ap10 H x)^ @
(ap10 H (retract_sect R (retract_retr R x)))^) @
ap (retract_sect R)
(retract_issect R (retract_retr R x))) @ ap10 H x =
isidem f x)
ua: Univalence X: Type f: X -> X I: IsPreIdempotent f R: RetractOf X H: (funx : X => retract_sect R (retract_retr R x)) =
f
transport (funf : X -> X => IsPreIdempotent f) H
(funx : X =>
ap (retract_sect R)
(retract_issect R (retract_retr R x))) = I <~>
(forallx : X,
((ap f (ap10 H x)^ @
(ap10 H (retract_sect R (retract_retr R x)))^) @
ap (retract_sect R)
(retract_issect R (retract_retr R x))) @ ap10 H x =
isidem f x)
ua: Univalence X: Type R: RetractOf X I: IsPreIdempotent
(funx : X => retract_sect R (retract_retr R x))
(funx : X =>
ap (retract_sect R)
(retract_issect R (retract_retr R x))) = I <~>
(forallx : X,
(1 @
ap (retract_sect R)
(retract_issect R (retract_retr R x))) @ 1 =
isidem
(funx0 : X => retract_sect R (retract_retr R x0))
x)
ua: Univalence X: Type R: RetractOf X I: IsPreIdempotent
(funx : X => retract_sect R (retract_retr R x))
(forallx : X,
ap (retract_sect R)
(retract_issect R (retract_retr R x)) = I x) <~>
(forallx : X,
(1 @
ap (retract_sect R)
(retract_issect R (retract_retr R x))) @ 1 =
isidem
(funx0 : X => retract_sect R (retract_retr R x0))
x)
ua: Univalence X: Type R: RetractOf X I: IsPreIdempotent
(funx : X => retract_sect R (retract_retr R x)) x: X
ap (retract_sect R)
(retract_issect R (retract_retr R x)) = I x <~>
(1 @
ap (retract_sect R)
(retract_issect R (retract_retr R x))) @ 1 =
isidem
(funx : X => retract_sect R (retract_retr R x)) x
ua: Univalence X: Type R: RetractOf X I: IsPreIdempotent
(funx : X => retract_sect R (retract_retr R x)) x: X
ap (retract_sect R)
(retract_issect R (retract_retr R x)) = I x <~>
(1 @
ap (retract_sect R)
(retract_issect R (retract_retr R x))) @ 1 = I x
ua: Univalence X: Type R: RetractOf X I: IsPreIdempotent
(funx : X => retract_sect R (retract_retr R x)) x: X
(1 @
ap (retract_sect R)
(retract_issect R (retract_retr R x))) @ 1 =
ap (retract_sect R)
(retract_issect R (retract_retr R x))
exact (concat_p1 _ @ concat_1p _).Defined.EndRetractOfRetracts.(** ** Fully coherent idempotents *)(** This gives us a way to define fully coherent idempotents. By Corollary 4.4.5.14 of *Higher Topos Theory*, if we assume univalence then [RetractOf X] has the correct homotopy type of the type of fully coherent idempotents on [X]. However, its defect is that it raises the universe level. But now that we've shown that [RetractOf X] is a retract of the type [QuasiIdempotent X], which is of the same size as [X], we can obtain an equivalent type by splitting the resulting idempotent on [QuasiIdempotent X].For convenience, we instead split the idempotent on splittings of a fixed map [f], and then sum them up to obtain the type of idempotents. *)SectionCoherentIdempotents.Context {ua : Univalence}.ClassIsIdempotent {X : Type} (f : X -> X)
:= is_coherent_idem : split_idem (retract_idem (splitting_retractof_isqidem f)).DefinitionBuild_IsIdempotent {X : Type} (f : X -> X)
: Splitting f -> IsIdempotent f
:= (equiv_split_idem_retract (splitting_retractof_isqidem f))^-1.Definitionisidem_isqidem {X : Type} (f : X -> X) `{IsQuasiIdempotent _ f}
: IsIdempotent f
:= Build_IsIdempotent f (split_idem_split f).
ua: Univalence X: Type f: X -> X H: IsIdempotent f
IsPreIdempotent f
ua: Univalence X: Type f: X -> X H: IsIdempotent f
IsPreIdempotent f
ua: Univalence X: Type f: X -> X H: IsIdempotent f
ua: Univalence X: Type f: X -> X H: IsIdempotent f
IsQuasiIdempotent f
ua: Univalence X: Type f: X -> X H: IsIdempotent f
IsQuasiIdempotent f
exact (split_idem_sect (retract_idem (splitting_retractof_isqidem f)) _).2.Defined.DefinitionIdempotent (X : Type) := { f : X -> X & IsIdempotent f }.Definitionidempotent_pr1 {X : Type} : Idempotent X -> (X -> X) := pr1.Coercionidempotent_pr1 : Idempotent >-> Funclass.#[export] Instanceisidem_idem (X : Type) (f : Idempotent X) : IsIdempotent f
:= f.2.(** The above definitions depend on [Univalence]. Technically this is the case by their construction, since they are a splitting of a map that we only know to be idempotent in the presence of univalence. This map could be defined, and hence "split", without univalence; but also only with univalence do we know that they have the right homotopy type. Thus univalence is used in two places: concluding (meta-theoretically) from HTT 4.4.5.14 that [RetractOf X] has the right homotopy type, and showing (in the next lemma) that it is equivalent to [Idempotent X]. In the absence of univalence, we don't currently have *any* provably-correct definition of the type of coherent idempotents; it ought to involve an infinite tower of coherences as defined in HTT section 4.4.5. However, there may be some Yoneda-like meta-theoretic argument which would imply that the above-defined types do have the correct homotopy type without univalence (though almost certainly not without funext). *)
ua: Univalence X: Type
Idempotent X <~> RetractOf X
ua: Univalence X: Type
Idempotent X <~> RetractOf X
ua: Univalence X: Type
Idempotent X <~> {f : X -> X & Splitting f}
ua: Univalence X: Type
{f : X -> X & Splitting f} <~> RetractOf X
ua: Univalence X: Type
Idempotent X <~> {f : X -> X & Splitting f}
ua: Univalence X: Type
{f : X -> X & IsIdempotent f} <~>
{f : X -> X & Splitting f}
{f : X -> X & {R : RetractOf X & retract_idem R == f}} <~>
RetractOf X
ua: Univalence X: Type
{b : RetractOf X & {a : X -> X & retract_idem b == a}} <~>
RetractOf X
ua: Univalence X: Type R: RetractOf X
Contr {a : X -> X & retract_idem R == a}
apply contr_basedhomotopy.Defined.(** For instance, here is the standard coherent idempotent structure on the identity map. *)#[export] Instanceisidem_idmap (X : Type@{i})
: @IsIdempotent@{i i j} X idmap
:= Build_IsIdempotent idmap (splitting_idmap X).Definitionidem_idmap (X : Type@{i}) : Idempotent@{i i j} X
:= (idmap ; isidem_idmap X).EndCoherentIdempotents.(** ** Quasi-idempotents need not be fully coherent *)(** We have shown that every quasi-idempotent can be "coherentified" into a fully coherent idempotent, analogously to how every quasi-inverse can be coherentified into an equivalence. However, just as for quasi-inverses, not every witness to quasi-idempotency *is itself* coherent. This is in contrast to a witness of pre-idempotency, which (if it extends to a quasi-idempotent) can itself be extended to a coherent idempotent; this is roughly the content of [split_idem_preidem] and [splitting_preidem_retractof_qidem]. The key step in showing this is to observe that when [f] is the identity, the retract type [Splitting_PreIdempotent f] of [splitting_preidem_retractof_qidem] is equivalent to the type of types-equivalent-to-[X], and hence contractible. *)
ua: Univalence X: Type
Contr (Splitting_PreIdempotent (preidem_idmap X))
ua: Univalence X: Type
Contr (Splitting_PreIdempotent (preidem_idmap X))
ua: Univalence X: Type
{Y : Type & X <~> Y} <~>
Splitting_PreIdempotent (preidem_idmap X)
ua: Univalence X: Type
{Y : Type & X <~> Y} <~>
{S : Splitting (preidem_idmap X) &
forallx : X,
retract_issect S.1 (retract_retr S.1 x) =
ap (retract_retr S.1) (S.2 x)}
ua: Univalence X, Y: Type r: X -> Y s: Y -> X eta: (funx : Y => r (s x)) == idmap ep: (funx : X => s (r x)) == idmap
(forallx : X, eta (r x) = ap r (ep x)) <~>
(forallx : X,
((ap idmap (ep x)^ @ (ep (s (r x)))^) @
ap s (eta (r x))) @ ep x = ispreidem_idmap X x)
ua: Univalence X, Y: Type r: X -> Y s: Y -> X eta: (funx : Y => r (s x)) == idmap ep: (funx : X => s (r x)) == idmap x: X
eta (r x) = ap r (ep x) <~>
((ap idmap (ep x)^ @ (ep (s (r x)))^) @
ap s (eta (r x))) @ ep x = ispreidem_idmap X x
ua: Univalence X, Y: Type r: X -> Y s: Y -> X eta: (funx : Y => r (s x)) == idmap ep: (funx : X => s (r x)) == idmap x: X
eta (r x) = ap r (ep x) <~>
((ap idmap (ep x)^ @ (ep (s (r x)))^) @
ap s (eta (r x))) @ ep x = 1
ua: Univalence X, Y: Type r: X -> Y s: Y -> X eta: (funx : Y => r (s x)) == idmap ep: (funx : X => s (r x)) == idmap x: X
eta (r x) = ap r (ep x) <~>
(ep x)^ @
((ep (s (r x)))^ @ (ap s (eta (r x)) @ ep x)) = 1
ua: Univalence X, Y: Type r: X -> Y s: Y -> X eta: (funx : Y => r (s x)) == idmap ep: (funx : X => s (r x)) == idmap x: X
eta (r x) = ap r (ep x) <~>
(ep (s (r x)))^ @ (ap s (eta (r x)) @ ep x) = ep x @ 1
ua: Univalence X, Y: Type r: X -> Y s: Y -> X eta: (funx : Y => r (s x)) == idmap ep: (funx : X => s (r x)) == idmap x: X
eta (r x) = ap r (ep x) <~>
((ep (s (r x)))^ @ ap s (eta (r x))) @ ep x = ep x
ua: Univalence X, Y: Type r: X -> Y s: Y -> X eta: (funx : Y => r (s x)) == idmap ep: (funx : X => s (r x)) == idmap x: X
eta (r x) = ap r (ep x) <~>
((ep (s (r x)))^ @ ap s (eta (r x))) @ ep x = 1 @ ep x
ua: Univalence X, Y: Type r: X -> Y s: Y -> X eta: (funx : Y => r (s x)) == idmap ep: (funx : X => s (r x)) == idmap x: X
eta (r x) = ap r (ep x) <~>
(ep (s (r x)))^ @ ap s (eta (r x)) = 1
ua: Univalence X, Y: Type r: X -> Y s: Y -> X eta: (funx : Y => r (s x)) == idmap ep: (funx : X => s (r x)) == idmap x: X
eta (r x) = ap r (ep x) <~>
ap s (eta (r x)) = ep (s (r x)) @ 1
ua: Univalence X, Y: Type r: X -> Y s: Y -> X eta: (funx : Y => r (s x)) == idmap ep: (funx : X => s (r x)) == idmap x: X
eta (r x) = ap r (ep x) <~>
ap s (eta (r x)) = ep (s (r x))
ua: Univalence X, Y: Type r: X -> Y s: Y -> X eta: (funx : Y => r (s x)) == idmap ep: (funx : X => s (r x)) == idmap x: X i:= isequiv_adjointify s r ep eta: IsEquiv s
eta (r x) = ap r (ep x) <~>
ap s (eta (r x)) = ep (s (r x))
ua: Univalence X, Y: Type r: X -> Y s: Y -> X eta: (funx : Y => r (s x)) == idmap ep: (funx : X => s (r x)) == idmap x: X i:= isequiv_adjointify s r ep eta: IsEquiv s
ap s (eta (r x)) = ap s (ap r (ep x)) <~>
ap s (eta (r x)) = ep (s (r x))
ua: Univalence X, Y: Type r: X -> Y s: Y -> X eta: (funx : Y => r (s x)) == idmap ep: (funx : X => s (r x)) == idmap x: X i:= isequiv_adjointify s r ep eta: IsEquiv s
ap s (ap r (ep x)) = ep (s (r x))
ua: Univalence X, Y: Type r: X -> Y s: Y -> X eta: (funx : Y => r (s x)) == idmap ep: (funx : X => s (r x)) == idmap x: X i:= isequiv_adjointify s r ep eta: IsEquiv s
ap s (ap r (ep x)) @ ep x = ep (s (r x)) @ ep x
ua: Univalence X, Y: Type r: X -> Y s: Y -> X eta: (funx : Y => r (s x)) == idmap ep: (funx : X => s (r x)) == idmap x: X i:= isequiv_adjointify s r ep eta: IsEquiv s
ap (funx : X => s (r x)) (ep x) @ ep x =
ep (s (r x)) @ ep x
exact (concat_A1p ep (ep x)).Qed.(** Therefore, there is a unique coherentification of the canonical witness [preidem_idmap] of pre-idempotency for the identity. Hence, to show that not every quasi-idempotent is coherent, it suffices to give a witness of quasi-idempotency extending [preidem_idmap] which is nontrivial (i.e. not equal to [qidem_idmap]). Such a witness is exactly an element of the 2-center, and we know that some types such as [BAut (BAut Bool)] have nontrivial 2-centers. In [Spaces.BAut.Bool.IncoherentIdempotent] we use this to construct an explicit counterexample. *)(** ** A pre-idempotent that is not quasi-idempotent *)(** We can also give a specific example of a pre-idempotent that does not split, hence is not coherentifiable and not even quasi-idempotent. The construction is inspired by Warning 1.2.4.8 in *Higher Algebra*, and can be found in [Spaces.BAut.Cantor]. *)