Equivalences
{-# OPTIONS --safe #-}
module foundation-core.equivalences where
Imports
open import foundation-core.cartesian-product-types open import foundation-core.coherently-invertible-maps open import foundation-core.dependent-pair-types open import foundation-core.functions open import foundation-core.homotopies open import foundation-core.identity-types open import foundation-core.retractions open import foundation-core.sections open import foundation-core.universe-levels
Idea
An equivalence is a map that has a section and a (separate) retraction. This is
also called being biinvertible. This may look odd: Why not say that an
equivalence is a map that has a 2-sided inverse? The reason is that the latter
requirement would put nontrivial structure on the map, whereas having the
section and retraction separate yields a property. To quickly see this: if f
is an equivalence, then it has up to homotopy only one section, and it has up to
homotopy only one retraction.
Definition
Equivalences
module _ {l1 l2 : Level} {A : UU l1} {B : UU l2} where is-equiv : (A → B) → UU (l1 ⊔ l2) is-equiv f = sec f × retr f _≃_ : {l1 l2 : Level} (A : UU l1) (B : UU l2) → UU (l1 ⊔ l2) A ≃ B = Σ (A → B) is-equiv
Components of an equivalence
module _ {l1 l2 : Level} {A : UU l1} {B : UU l2} {f : A → B} where sec-is-equiv : is-equiv f → sec f sec-is-equiv = pr1 retr-is-equiv : is-equiv f → retr f retr-is-equiv = pr2 map-sec-is-equiv : is-equiv f → B → A map-sec-is-equiv = pr1 ∘ pr1 map-retr-is-equiv : is-equiv f → B → A map-retr-is-equiv = pr1 ∘ pr2 isretr-is-equiv : (is-equiv-f : is-equiv f) → (f ∘ map-sec-is-equiv is-equiv-f) ~ id isretr-is-equiv is-equiv-f = pr2 (pr1 is-equiv-f) issec-is-equiv : (is-equiv-f : is-equiv f) → (map-retr-is-equiv is-equiv-f ∘ f) ~ id issec-is-equiv is-equiv-f = pr2 (pr2 is-equiv-f) module _ {l1 l2 : Level} {A : UU l1} {B : UU l2} where map-equiv : (A ≃ B) → (A → B) map-equiv e = pr1 e is-equiv-map-equiv : (e : A ≃ B) → is-equiv (map-equiv e) is-equiv-map-equiv e = pr2 e retr-map-equiv : (e : A ≃ B) → retr (map-equiv e) retr-map-equiv = retr-is-equiv ∘ is-equiv-map-equiv sec-map-equiv : (e : A ≃ B) → sec (map-equiv e) sec-map-equiv = sec-is-equiv ∘ is-equiv-map-equiv isretr-map-equiv : (e : A ≃ B) → (map-equiv e ∘ map-sec-is-equiv (is-equiv-map-equiv e)) ~ id isretr-map-equiv = isretr-is-equiv ∘ is-equiv-map-equiv issec-map-equiv : (e : A ≃ B) → (map-retr-is-equiv (is-equiv-map-equiv e) ∘ map-equiv e) ~ id issec-map-equiv = issec-is-equiv ∘ is-equiv-map-equiv
Families of equivalences
module _ {l1 l2 l3 : Level} {A : UU l1} where is-fiberwise-equiv : {B : A → UU l2} {C : A → UU l3} (f : (x : A) → B x → C x) → UU (l1 ⊔ l2 ⊔ l3) is-fiberwise-equiv f = (x : A) → is-equiv (f x) fiberwise-equiv : (B : A → UU l2) (C : A → UU l3) → UU (l1 ⊔ l2 ⊔ l3) fiberwise-equiv B C = Σ ((x : A) → B x → C x) is-fiberwise-equiv fam-equiv : (B : A → UU l2) (C : A → UU l3) → UU (l1 ⊔ l2 ⊔ l3) fam-equiv B C = (x : A) → B x ≃ C x
The identity map is an equivalence
module _ {l : Level} {A : UU l} where is-equiv-id : is-equiv (id {l} {A}) pr1 (pr1 is-equiv-id) = id pr2 (pr1 is-equiv-id) = refl-htpy pr1 (pr2 is-equiv-id) = id pr2 (pr2 is-equiv-id) = refl-htpy id-equiv : A ≃ A pr1 id-equiv = id pr2 id-equiv = is-equiv-id
Properties
A map has an two-sided inverse if and only if it is an equivalence
module _ {l1 l2 : Level} {A : UU l1} {B : UU l2} {f : A → B} where is-equiv-has-inverse' : has-inverse f → is-equiv f pr1 (pr1 (is-equiv-has-inverse' (pair g (pair H K)))) = g pr2 (pr1 (is-equiv-has-inverse' (pair g (pair H K)))) = H pr1 (pr2 (is-equiv-has-inverse' (pair g (pair H K)))) = g pr2 (pr2 (is-equiv-has-inverse' (pair g (pair H K)))) = K is-equiv-has-inverse : (g : B → A) (H : (f ∘ g) ~ id) (K : (g ∘ f) ~ id) → is-equiv f is-equiv-has-inverse g H K = is-equiv-has-inverse' (pair g (pair H K)) has-inverse-is-equiv : is-equiv f → has-inverse f pr1 (has-inverse-is-equiv (pair (pair g G) (pair h H))) = g pr1 (pr2 (has-inverse-is-equiv (pair (pair g G) (pair h H)))) = G pr2 (pr2 (has-inverse-is-equiv (pair (pair g G) (pair h H)))) = (((inv-htpy (H ·r g)) ∙h (h ·l G)) ·r f) ∙h H
Coherently invertible maps are equivalences
module _ {l1 l2 : Level} {A : UU l1} {B : UU l2} {f : A → B} where abstract is-coherently-invertible-is-equiv : is-equiv f → is-coherently-invertible f is-coherently-invertible-is-equiv = is-coherently-invertible-has-inverse ∘ has-inverse-is-equiv abstract is-equiv-is-coherently-invertible : is-coherently-invertible f → is-equiv f is-equiv-is-coherently-invertible (pair g (pair G (pair H K))) = is-equiv-has-inverse g G H
Structure obtained from being coherently invertible
module _ {l1 l2 : Level} {A : UU l1} {B : UU l2} {f : A → B} (H : is-equiv f) where map-inv-is-equiv : B → A map-inv-is-equiv = pr1 (has-inverse-is-equiv H) issec-map-inv-is-equiv : (f ∘ map-inv-is-equiv) ~ id issec-map-inv-is-equiv = issec-inv-has-inverse (has-inverse-is-equiv H) isretr-map-inv-is-equiv : (map-inv-is-equiv ∘ f) ~ id isretr-map-inv-is-equiv = isretr-inv-has-inverse (has-inverse-is-equiv H) coherence-map-inv-is-equiv : ( issec-map-inv-is-equiv ·r f) ~ (f ·l isretr-map-inv-is-equiv) coherence-map-inv-is-equiv = coherence-inv-has-inverse (has-inverse-is-equiv H) is-equiv-map-inv-is-equiv : is-equiv map-inv-is-equiv is-equiv-map-inv-is-equiv = is-equiv-has-inverse f ( isretr-map-inv-is-equiv) ( issec-map-inv-is-equiv)
The inverse of an equivalence is an equivalence
module _ {l1 l2 : Level} {A : UU l1} {B : UU l2} (e : A ≃ B) where map-inv-equiv : B → A map-inv-equiv = map-inv-is-equiv (is-equiv-map-equiv e) issec-map-inv-equiv : ((map-equiv e) ∘ map-inv-equiv) ~ id issec-map-inv-equiv = issec-map-inv-is-equiv (is-equiv-map-equiv e) isretr-map-inv-equiv : (map-inv-equiv ∘ (map-equiv e)) ~ id isretr-map-inv-equiv = isretr-map-inv-is-equiv (is-equiv-map-equiv e) coherence-map-inv-equiv : ( issec-map-inv-equiv ·r (map-equiv e)) ~ ( (map-equiv e) ·l isretr-map-inv-equiv) coherence-map-inv-equiv = coherence-map-inv-is-equiv (is-equiv-map-equiv e) is-equiv-map-inv-equiv : is-equiv map-inv-equiv is-equiv-map-inv-equiv = is-equiv-map-inv-is-equiv (is-equiv-map-equiv e) inv-equiv : B ≃ A pr1 inv-equiv = map-inv-equiv pr2 inv-equiv = is-equiv-map-inv-equiv
The 3-for-2 property of equivalences
Composites of equivalences are equivalences
module _ {l1 l2 l3 : Level} {A : UU l1} {B : UU l2} {X : UU l3} (f : A → X) (g : B → X) (h : A → B) (H : f ~ (g ∘ h)) where abstract is-equiv-comp-htpy : is-equiv h → is-equiv g → is-equiv f pr1 (is-equiv-comp-htpy (pair sec-h retr-h) (pair sec-g retr-g)) = section-comp-htpy f g h H sec-h sec-g pr2 (is-equiv-comp-htpy (pair sec-h retr-h) (pair sec-g retr-g)) = retraction-comp-htpy f g h H retr-g retr-h module _ {l1 l2 l3 : Level} {A : UU l1} {B : UU l2} {X : UU l3} where abstract is-equiv-comp : (g : B → X) (h : A → B) → is-equiv h → is-equiv g → is-equiv (g ∘ h) pr1 (is-equiv-comp g h (pair sec-h retr-h) (pair sec-g retr-g)) = section-comp g h sec-h sec-g pr2 (is-equiv-comp g h (pair sec-h retr-h) (pair sec-g retr-g)) = retraction-comp g h retr-g retr-h equiv-comp : (B ≃ X) → (A ≃ B) → (A ≃ X) pr1 (equiv-comp g h) = (map-equiv g) ∘ (map-equiv h) pr2 (equiv-comp g h) = is-equiv-comp (pr1 g) (pr1 h) (pr2 h) (pr2 g) _∘e_ : (B ≃ X) → (A ≃ B) → (A ≃ X) _∘e_ = equiv-comp
If a composite and its right factor are equivalences, then so is its left factor
module _ {l1 l2 l3 : Level} {A : UU l1} {B : UU l2} {X : UU l3} where abstract is-equiv-left-factor-htpy : (f : A → X) (g : B → X) (h : A → B) (H : f ~ (g ∘ h)) → is-equiv f → is-equiv h → is-equiv g is-equiv-left-factor-htpy f g h H ( pair sec-f retr-f) ( pair (pair sh issec-sh) retr-h) = ( pair ( section-left-factor-htpy f g h H sec-f) ( retraction-comp-htpy g f sh ( triangle-section f g h H (pair sh issec-sh)) ( retr-f) ( pair h issec-sh))) is-equiv-left-factor : (g : B → X) (h : A → B) → is-equiv (g ∘ h) → is-equiv h → is-equiv g is-equiv-left-factor g h is-equiv-gh is-equiv-h = is-equiv-left-factor-htpy (g ∘ h) g h refl-htpy is-equiv-gh is-equiv-h
If a composite and its left factor are equivalences, then so is its right factor
module _ {l1 l2 l3 : Level} {A : UU l1} {B : UU l2} {X : UU l3} where abstract is-equiv-right-factor-htpy : (f : A → X) (g : B → X) (h : A → B) (H : f ~ (g ∘ h)) → is-equiv g → is-equiv f → is-equiv h is-equiv-right-factor-htpy f g h H ( pair sec-g (pair rg isretr-rg)) ( pair sec-f retr-f) = ( pair ( section-comp-htpy h rg f ( triangle-retraction f g h H (pair rg isretr-rg)) ( sec-f) ( pair g isretr-rg)) ( retraction-right-factor-htpy f g h H retr-f)) is-equiv-right-factor : (g : B → X) (h : A → B) → is-equiv g → is-equiv (g ∘ h) → is-equiv h is-equiv-right-factor g h is-equiv-g is-equiv-gh = is-equiv-right-factor-htpy (g ∘ h) g h refl-htpy is-equiv-g is-equiv-gh
Equivalences are closed under homotopies
We show that if f ~ g
, then f
is an equivalence if and only if g
is an
equivalence. Furthermore, we show that if f
and g
are homotopic equivaleces,
then their inverses are also homotopic.
module _ {l1 l2 : Level} {A : UU l1} {B : UU l2} where abstract is-equiv-htpy : {f : A → B} (g : A → B) → f ~ g → is-equiv g → is-equiv f pr1 (pr1 (is-equiv-htpy g H (pair (pair gs issec) (pair gr isretr)))) = gs pr2 (pr1 (is-equiv-htpy g H (pair (pair gs issec) (pair gr isretr)))) = (H ·r gs) ∙h issec pr1 (pr2 (is-equiv-htpy g H (pair (pair gs issec) (pair gr isretr)))) = gr pr2 (pr2 (is-equiv-htpy g H (pair (pair gs issec) (pair gr isretr)))) = (gr ·l H) ∙h isretr is-equiv-htpy-equiv : {f : A → B} (e : A ≃ B) → f ~ map-equiv e → is-equiv f is-equiv-htpy-equiv e H = is-equiv-htpy (map-equiv e) H (is-equiv-map-equiv e) abstract is-equiv-htpy' : (f : A → B) {g : A → B} → f ~ g → is-equiv f → is-equiv g is-equiv-htpy' f H = is-equiv-htpy f (inv-htpy H) is-equiv-htpy-equiv' : (e : A ≃ B) {g : A → B} → map-equiv e ~ g → is-equiv g is-equiv-htpy-equiv' e H = is-equiv-htpy' (map-equiv e) H (is-equiv-map-equiv e) htpy-map-inv-is-equiv : {f g : A → B} (G : f ~ g) (H : is-equiv f) (K : is-equiv g) → (map-inv-is-equiv H) ~ (map-inv-is-equiv K) htpy-map-inv-is-equiv G H K b = ( inv ( isretr-map-inv-is-equiv K (map-inv-is-equiv H b))) ∙ ( ap (map-inv-is-equiv K) ( ( inv (G (map-inv-is-equiv H b))) ∙ ( issec-map-inv-is-equiv H b)))
Any retraction of an equivalence is an equivalence
abstract is-equiv-is-retraction : {l1 l2 : Level} {A : UU l1} {B : UU l2} {f : A → B} {g : B → A} → is-equiv f → (g ∘ f) ~ id → is-equiv g is-equiv-is-retraction {A = A} {f = f} {g = g} is-equiv-f H = is-equiv-left-factor-htpy id g f (inv-htpy H) is-equiv-id is-equiv-f
Any section of an equivalence is an equivalence
abstract is-equiv-is-section : {l1 l2 : Level} {A : UU l1} {B : UU l2} {f : A → B} {g : B → A} → is-equiv f → (f ∘ g) ~ id → is-equiv g is-equiv-is-section {B = B} {f = f} {g = g} is-equiv-f H = is-equiv-right-factor-htpy id f g (inv-htpy H) is-equiv-f is-equiv-id
If a section of f
is an equivalence, then f
is an equivalence
module _ {l1 l2 : Level} {A : UU l1} {B : UU l2} (f : A → B) where abstract is-equiv-sec-is-equiv : ( sec-f : sec f) → is-equiv (pr1 sec-f) → is-equiv f is-equiv-sec-is-equiv (pair g issec-g) is-equiv-sec-f = is-equiv-htpy h ( ( f ·l (inv-htpy (issec-map-inv-is-equiv is-equiv-sec-f))) ∙h ( htpy-right-whisk issec-g h)) ( is-equiv-map-inv-is-equiv is-equiv-sec-f) where h : A → B h = map-inv-is-equiv is-equiv-sec-f
Equivalences in commuting squares
is-equiv-equiv : {l1 l2 l3 l4 : Level} {A : UU l1} {B : UU l2} {X : UU l3} {Y : UU l4} {f : A → B} {g : X → Y} (i : A ≃ X) (j : B ≃ Y) (H : (map-equiv j ∘ f) ~ (g ∘ map-equiv i)) → is-equiv g → is-equiv f is-equiv-equiv {f = f} {g} i j H K = is-equiv-right-factor ( map-equiv j) ( f) ( is-equiv-map-equiv j) ( is-equiv-comp-htpy ( map-equiv j ∘ f) ( g) ( map-equiv i) ( H) ( is-equiv-map-equiv i) ( K)) is-equiv-equiv' : {l1 l2 l3 l4 : Level} {A : UU l1} {B : UU l2} {X : UU l3} {Y : UU l4} {f : A → B} {g : X → Y} (i : A ≃ X) (j : B ≃ Y) (H : (map-equiv j ∘ f) ~ (g ∘ map-equiv i)) → is-equiv f → is-equiv g is-equiv-equiv' {f = f} {g} i j H K = is-equiv-left-factor ( g) ( map-equiv i) ( is-equiv-comp-htpy ( g ∘ map-equiv i) ( map-equiv j) ( f) ( inv-htpy H) ( K) ( is-equiv-map-equiv j)) ( is-equiv-map-equiv i)
We will assume a commuting square
h
A --------> C
| |
f| |g
V V
B --------> D
i
module _ {l1 l2 l3 l4 : Level} {A : UU l1} {B : UU l2} {C : UU l3} {D : UU l4} (f : A → B) (g : C → D) (h : A → C) (i : B → D) (H : (i ∘ f) ~ (g ∘ h)) where abstract is-equiv-top-is-equiv-left-square : is-equiv i → is-equiv f → is-equiv g → is-equiv h is-equiv-top-is-equiv-left-square Ei Ef Eg = is-equiv-right-factor-htpy (i ∘ f) g h H Eg (is-equiv-comp i f Ef Ei) abstract is-equiv-top-is-equiv-bottom-square : is-equiv f → is-equiv g → is-equiv i → is-equiv h is-equiv-top-is-equiv-bottom-square Ef Eg Ei = is-equiv-right-factor-htpy (i ∘ f) g h H Eg (is-equiv-comp i f Ef Ei) abstract is-equiv-bottom-is-equiv-top-square : is-equiv f → is-equiv g → is-equiv h → is-equiv i is-equiv-bottom-is-equiv-top-square Ef Eg Eh = is-equiv-left-factor i f (is-equiv-comp-htpy (i ∘ f) g h H Eh Eg) Ef abstract is-equiv-left-is-equiv-right-square : is-equiv h → is-equiv i → is-equiv g → is-equiv f is-equiv-left-is-equiv-right-square Eh Ei Eg = is-equiv-right-factor i f Ei (is-equiv-comp-htpy (i ∘ f) g h H Eh Eg) abstract is-equiv-right-is-equiv-left-square : is-equiv h → is-equiv i → is-equiv f → is-equiv g is-equiv-right-is-equiv-left-square Eh Ei Ef = is-equiv-left-factor-htpy (i ∘ f) g h H (is-equiv-comp i f Ef Ei) Eh
Equivalences are embeddings
module _ {l1 l2 : Level} {A : UU l1} {B : UU l2} where is-emb-is-equiv : {f : A → B} → is-equiv f → (x y : A) → is-equiv (ap f {x} {y}) is-emb-is-equiv {f} H x y = is-equiv-has-inverse ( λ p → ( inv (isretr-map-inv-is-equiv H x)) ∙ ( ( ap (map-inv-is-equiv H) p) ∙ ( isretr-map-inv-is-equiv H y))) ( λ p → ( ap-concat f ( inv (isretr-map-inv-is-equiv H x)) ( ap (map-inv-is-equiv H) p ∙ isretr-map-inv-is-equiv H y)) ∙ ( ( ap-binary ( λ u v → u ∙ v) ( ap-inv f (isretr-map-inv-is-equiv H x)) ( ( ap-concat f ( ap (map-inv-is-equiv H) p) ( isretr-map-inv-is-equiv H y)) ∙ ( ap-binary ( λ u v → u ∙ v) ( inv (ap-comp f (map-inv-is-equiv H) p)) ( inv (coherence-map-inv-is-equiv H y))))) ∙ ( inv ( inv-con ( ap f (isretr-map-inv-is-equiv H x)) ( p) ( ( ap (f ∘ map-inv-is-equiv H) p) ∙ ( issec-map-inv-is-equiv H (f y))) ( ( ap-binary ( λ u v → u ∙ v) ( inv (coherence-map-inv-is-equiv H x)) ( inv (ap-id p))) ∙ ( nat-htpy (issec-map-inv-is-equiv H) p)))))) ( λ {refl → left-inv (isretr-map-inv-is-equiv H x)}) equiv-ap : (e : A ≃ B) (x y : A) → (x = y) ≃ (map-equiv e x = map-equiv e y) pr1 (equiv-ap e x y) = ap (map-equiv e) pr2 (equiv-ap e x y) = is-emb-is-equiv (is-equiv-map-equiv e) x y
Equivalence reasoning
Equivalences can be constructed by equational reasoning in the following way:
equivalence-reasoning
X ≃ Y by equiv-1
≃ Z by equiv-2
≃ V by equiv-3
The equivalence constructed in this way is equiv-1 ∘e (equiv-2 ∘e equiv-3)
,
i.e., the equivivalence is associated fully to the right.
infixl 1 equivalence-reasoning_ infixl 0 step-equivalence-reasoning equivalence-reasoning_ : {l1 : Level} (X : UU l1) → X ≃ X equivalence-reasoning X = id-equiv step-equivalence-reasoning : {l1 l2 l3 : Level} {X : UU l1} {Y : UU l2} → (X ≃ Y) → (Z : UU l3) → (Y ≃ Z) → (X ≃ Z) step-equivalence-reasoning e Z f = f ∘e e syntax step-equivalence-reasoning e Z f = e ≃ Z by f
See also
- For the notions of inverses and coherently invertible maps, also known as
half-adjoint equivalences, see
foundation.coherently-invertible-maps
. - For the notion of maps with contractible fibers see
foundation.contractible-maps
. - For the notion of path-split maps see
foundation.path-split-maps
.