# Equivalences

```agda
module foundation-core.equivalences where
```

<details><summary>Imports</summary>

```agda
open import foundation.action-on-identifications-functions
open import foundation.dependent-pair-types
open import foundation.universe-levels
open import foundation.whiskering-homotopies-composition

open import foundation-core.cartesian-product-types
open import foundation-core.coherently-invertible-maps
open import foundation-core.function-types
open import foundation-core.homotopies
open import foundation-core.identity-types
open import foundation-core.invertible-maps
open import foundation-core.retractions
open import foundation-core.sections
```

</details>

## Idea

An **equivalence** is a map that has a [section](foundation-core.sections.md)
and a (separate) [retraction](foundation-core.retractions.md). This condition is
also called being **biinvertible**.

The condition of biinvertibility may look odd: Why not say that an equivalence
is a map that has a [2-sided inverse](foundation-core.invertible-maps.md)? The
reason is that the condition of invertibility is
[structure](foundation.structure.md), whereas the condition of being
biinvertible is a [property](foundation-core.propositions.md). To quickly see
this: if `f` is an equivalence, then it has up to
[homotopy](foundation-core.homotopies.md) only one section, and it has up to
homotopy only one retraction.

## Definition

### The predicate of being an equivalence

```agda
module _
  {l1 l2 : Level} {A : UU l1} {B : UU l2}
  where

  is-equiv : (A  B)  UU (l1  l2)
  is-equiv f = section f × retraction f
```

### Components of a proof of equivalence

```agda
module _
  {l1 l2 : Level} {A : UU l1} {B : UU l2} {f : A  B} (H : is-equiv f)
  where

  section-is-equiv : section f
  section-is-equiv = pr1 H

  retraction-is-equiv : retraction f
  retraction-is-equiv = pr2 H

  map-section-is-equiv : B  A
  map-section-is-equiv = map-section f section-is-equiv

  map-retraction-is-equiv : B  A
  map-retraction-is-equiv = map-retraction f retraction-is-equiv

  is-section-map-section-is-equiv : is-section f map-section-is-equiv
  is-section-map-section-is-equiv = is-section-map-section f section-is-equiv

  is-retraction-map-retraction-is-equiv :
    is-retraction f map-retraction-is-equiv
  is-retraction-map-retraction-is-equiv =
    is-retraction-map-retraction f retraction-is-equiv
```

### Equivalences

```agda
module _
  {l1 l2 : Level} (A : UU l1) (B : UU l2)
  where

  equiv : UU (l1  l2)
  equiv = Σ (A  B) is-equiv

infix 6 _≃_

_≃_ : {l1 l2 : Level} (A : UU l1) (B : UU l2)  UU (l1  l2)
A  B = equiv A B
```

### Components of an equivalence

```agda
module _
  {l1 l2 : Level} {A : UU l1} {B : UU l2} (e : A  B)
  where

  map-equiv : A  B
  map-equiv = pr1 e

  is-equiv-map-equiv : is-equiv map-equiv
  is-equiv-map-equiv = pr2 e

  section-map-equiv : section map-equiv
  section-map-equiv = section-is-equiv is-equiv-map-equiv

  map-section-map-equiv : B  A
  map-section-map-equiv = map-section map-equiv section-map-equiv

  is-section-map-section-map-equiv :
    is-section map-equiv map-section-map-equiv
  is-section-map-section-map-equiv =
    is-section-map-section map-equiv section-map-equiv

  retraction-map-equiv : retraction map-equiv
  retraction-map-equiv = retraction-is-equiv is-equiv-map-equiv

  map-retraction-map-equiv : B  A
  map-retraction-map-equiv = map-retraction map-equiv retraction-map-equiv

  is-retraction-map-retraction-map-equiv :
    is-retraction map-equiv map-retraction-map-equiv
  is-retraction-map-retraction-map-equiv =
    is-retraction-map-retraction map-equiv retraction-map-equiv
```

### The identity equivalence

```agda
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 is invertible if and only if it is an equivalence

**Proof:** It is clear that if a map is
[invertible](foundation-core.invertible-maps.md), then it is also biinvertible,
and hence an equivalence.

For the converse, suppose that `f : A → B` is an equivalence with section
`g : B → A` equipped with `G : f ∘ g ~ id`, and retraction `h : B → A` equipped
with `H : h ∘ f ~ id`. We claim that the map `g : B → A` is also a retraction.
To see this, we concatenate the following homotopies

```text
         H⁻¹ ·r g ·r f                  h ·l G ·r f           H
  g ∘ h ---------------> h ∘ f ∘ g ∘ f -------------> h ∘ f -----> id.
```

```agda
module _
  {l1 l2 : Level} {A : UU l1} {B : UU l2} {f : A  B}
  where

  is-equiv-is-invertible' : is-invertible f  is-equiv f
  is-equiv-is-invertible' (g , H , K) = ((g , H) , (g , K))

  is-equiv-is-invertible :
    (g : B  A) (H : f  g ~ id) (K : g  f ~ id)  is-equiv f
  is-equiv-is-invertible g H K = is-equiv-is-invertible' (g , H , K)

  is-retraction-map-section-is-equiv :
    (H : is-equiv f)  is-retraction f (map-section-is-equiv H)
  is-retraction-map-section-is-equiv H =
    ( ( inv-htpy
        ( ( is-retraction-map-retraction-is-equiv H) ·r
          ( map-section-is-equiv H  f))) ∙h
      ( map-retraction-is-equiv H ·l is-section-map-section-is-equiv H ·r f)) ∙h
    ( is-retraction-map-retraction-is-equiv H)

  is-invertible-is-equiv : is-equiv f  is-invertible f
  pr1 (is-invertible-is-equiv H) = map-section-is-equiv H
  pr1 (pr2 (is-invertible-is-equiv H)) = is-section-map-section-is-equiv H
  pr2 (pr2 (is-invertible-is-equiv H)) = is-retraction-map-section-is-equiv H
```

### Coherently invertible maps are equivalences

```agda
module _
  {l1 l2 : Level} {A : UU l1} {B : UU l2} {f : A  B}
  where

  is-equiv-is-coherently-invertible :
    is-coherently-invertible f  is-equiv f
  is-equiv-is-coherently-invertible H =
    is-equiv-is-invertible' (is-invertible-is-coherently-invertible H)

  is-equiv-is-transpose-coherently-invertible :
    is-transpose-coherently-invertible f  is-equiv f
  is-equiv-is-transpose-coherently-invertible H =
    is-equiv-is-invertible'
      ( is-invertible-is-transpose-coherently-invertible H)
```

The following maps are not simple constructions and should not be computed with.
Therefore, we mark them as `abstract`.

```agda
  abstract
    is-coherently-invertible-is-equiv :
      is-equiv f  is-coherently-invertible f
    is-coherently-invertible-is-equiv =
      is-coherently-invertible-is-invertible  is-invertible-is-equiv

  abstract
    is-transpose-coherently-invertible-is-equiv :
      is-equiv f  is-transpose-coherently-invertible f
    is-transpose-coherently-invertible-is-equiv =
      is-transpose-coherently-invertible-is-invertible  is-invertible-is-equiv
```

### Structure obtained from being coherently invertible

```agda
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 (is-invertible-is-equiv H)

  is-section-map-inv-is-equiv : is-section f map-inv-is-equiv
  is-section-map-inv-is-equiv =
    is-section-map-inv-is-coherently-invertible-is-invertible
      ( is-invertible-is-equiv H)

  is-retraction-map-inv-is-equiv : is-retraction f map-inv-is-equiv
  is-retraction-map-inv-is-equiv =
    is-retraction-map-inv-is-coherently-invertible-is-invertible
      ( is-invertible-is-equiv H)

  coherence-map-inv-is-equiv :
    coherence-is-coherently-invertible f
      ( map-inv-is-equiv)
      ( is-section-map-inv-is-equiv)
      ( is-retraction-map-inv-is-equiv)
  coherence-map-inv-is-equiv =
    coh-is-coherently-invertible-is-invertible (is-invertible-is-equiv H)

  is-equiv-map-inv-is-equiv : is-equiv map-inv-is-equiv
  is-equiv-map-inv-is-equiv =
    is-equiv-is-invertible f
      ( is-retraction-map-inv-is-equiv)
      ( is-section-map-inv-is-equiv)
```

### The inverse of an equivalence is an equivalence

```agda
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)

  is-section-map-inv-equiv : is-section (map-equiv e) map-inv-equiv
  is-section-map-inv-equiv = is-section-map-inv-is-equiv (is-equiv-map-equiv e)

  is-retraction-map-inv-equiv : is-retraction (map-equiv e) map-inv-equiv
  is-retraction-map-inv-equiv =
    is-retraction-map-inv-is-equiv (is-equiv-map-equiv e)

  coherence-map-inv-equiv :
    coherence-is-coherently-invertible
      ( map-equiv e)
      ( map-inv-equiv)
      ( is-section-map-inv-equiv)
      ( is-retraction-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

The **3-for-2 property** of equivalences asserts that for any
[commuting triangle](foundation-core.commuting-triangles-of-maps.md) of maps

```text
       h
  A ------> B
   \       /
   f\     /g
     \   /
      ∨ ∨
       X,
```

if two of the three maps are equivalences, then so is the third.

We also record special cases of the 3-for-2 property of equivalences, where we
only assume maps `g : B → X` and `h : A → B`. In this special case, we set
`f := g ∘ h` and the triangle commutes by `refl-htpy`.

[André Joyal](https://en.wikipedia.org/wiki/André_Joyal) proposed calling this
property the 3-for-2 property, despite most mathematicians calling it the
_2-out-of-3 property_. The story goes that on the produce market is is common to
advertise a discount as "3-for-2". If you buy two apples, then you get the third
for free. Similarly, if you prove that two maps in a commuting triangle are
equivalences, then you get the third for free.

#### The left map in a commuting triangle is an equivalence if the other two maps are equivalences

```agda
module _
  {l1 l2 l3 : Level} {A : UU l1} {B : UU l2} {X : UU l3}
  (f : A  X) (g : B  X) (h : A  B) (T : f ~ g  h)
  where

  abstract
    is-equiv-left-map-triangle : is-equiv h  is-equiv g  is-equiv f
    pr1 (is-equiv-left-map-triangle H G) =
      section-left-map-triangle f g h T
        ( section-is-equiv H)
        ( section-is-equiv G)
    pr2 (is-equiv-left-map-triangle H G) =
      retraction-left-map-triangle f g h T
        ( retraction-is-equiv G)
        ( retraction-is-equiv H)
```

#### The right map in a commuting triangle is an equivalence if the other two maps are equivalences

```agda
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-right-map-triangle :
      is-equiv f  is-equiv h  is-equiv g
    is-equiv-right-map-triangle
      ( section-f , retraction-f)
      ( (sh , is-section-sh) , retraction-h) =
        ( pair
          ( section-right-map-triangle f g h H section-f)
          ( retraction-left-map-triangle g f sh
            ( inv-htpy
              ( ( H ·r map-section h (sh , is-section-sh)) ∙h
                ( g ·l is-section-map-section h (sh , is-section-sh))))
            ( retraction-f)
            ( h , is-section-sh)))
```

#### If the left and right maps in a commuting triangle are equivalences, then the top map is an equivalence

```agda
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

  section-is-equiv-top-map-triangle :
    is-equiv g  is-equiv f  section h
  section-is-equiv-top-map-triangle G F =
    section-left-map-triangle h
      ( map-retraction-is-equiv G)
      ( f)
      ( inv-htpy
        ( ( map-retraction g (retraction-is-equiv G) ·l H) ∙h
          ( is-retraction-map-retraction g (retraction-is-equiv G) ·r h)))
      ( section-is-equiv F)
      ( g , is-retraction-map-retraction-is-equiv G)

  map-section-is-equiv-top-map-triangle :
    is-equiv g  is-equiv f  B  A
  map-section-is-equiv-top-map-triangle G F =
    map-section h (section-is-equiv-top-map-triangle G F)

  abstract
    is-equiv-top-map-triangle :
      is-equiv g  is-equiv f  is-equiv h
    is-equiv-top-map-triangle
      ( section-g , (rg , is-retraction-rg))
      ( section-f , retraction-f) =
      ( pair
        ( section-left-map-triangle h rg f
          ( inv-htpy
            ( ( map-retraction g (rg , is-retraction-rg) ·l H) ∙h
              ( is-retraction-map-retraction g (rg , is-retraction-rg) ·r h)))
          ( section-f)
          ( g , is-retraction-rg))
        ( retraction-top-map-triangle f g h H retraction-f))
```

#### Composites of equivalences are equivalences

```agda
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 (sh , rh) (sg , rg)) = section-comp g h sh sg
    pr2 (is-equiv-comp g h (sh , rh) (sg , rg)) = retraction-comp g h rg rh

  comp-equiv : B  X  A  B  A  X
  pr1 (comp-equiv g h) = map-equiv g  map-equiv h
  pr2 (comp-equiv g h) = is-equiv-comp (pr1 g) (pr1 h) (pr2 h) (pr2 g)

  infixr 15 _∘e_
  _∘e_ : B  X  A  B  A  X
  _∘e_ = comp-equiv
```

#### If a composite and its right factor are equivalences, then so is its left factor

```agda
module _
  {l1 l2 l3 : Level} {A : UU l1} {B : UU l2} {X : UU l3}
  where

  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-right-map-triangle (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

```agda
module _
  {l1 l2 l3 : Level} {A : UU l1} {B : UU l2} {X : UU l3}
  where

  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-top-map-triangle (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.

```agda
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 G ((h , H) , (k , K)))) = h
    pr2 (pr1 (is-equiv-htpy g G ((h , H) , (k , K)))) = (G ·r h) ∙h H
    pr1 (pr2 (is-equiv-htpy g G ((h , H) , (k , K)))) = k
    pr2 (pr2 (is-equiv-htpy g G ((h , H) , (k , K)))) = (k ·l G) ∙h K

  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} (H : f ~ g) (F : is-equiv f) (G : is-equiv g) 
    map-inv-is-equiv F ~ map-inv-is-equiv G
  htpy-map-inv-is-equiv H F G =
    htpy-map-inv-is-invertible H
      ( is-invertible-is-equiv F)
      ( is-invertible-is-equiv G)
```

### Any retraction of an equivalence is an equivalence

```agda
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-right-map-triangle id g f (inv-htpy H) is-equiv-id is-equiv-f
```

### Any section of an equivalence is an equivalence

```agda
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-top-map-triangle 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

```agda
module _
  {l1 l2 : Level} {A : UU l1} {B : UU l2} (f : A  B)
  where

  abstract
    is-equiv-is-equiv-section :
      (s : section f)  is-equiv (map-section f s)  is-equiv f
    is-equiv-is-equiv-section (g , G) S = is-equiv-is-retraction S G
```

### If a retraction of `f` is an equivalence, then `f` is an equivalence

```agda
module _
  {l1 l2 : Level} {A : UU l1} {B : UU l2} (f : A  B)
  where

  abstract
    is-equiv-is-equiv-retraction :
      (r : retraction f)  is-equiv (map-retraction f r)  is-equiv f
    is-equiv-is-equiv-retraction (g , G) R = is-equiv-is-section R G
```

### Any section of an equivalence is homotopic to its inverse

```agda
module _
  {l1 l2 : Level} {A : UU l1} {B : UU l2} (e : A  B)
  where

  htpy-map-inv-equiv-section :
    (f : section (map-equiv e))  map-inv-equiv e ~ map-section (map-equiv e) f
  htpy-map-inv-equiv-section (f , H) =
    (map-inv-equiv e ·l inv-htpy H) ∙h (is-retraction-map-inv-equiv e ·r f)
```

### Any retraction of an equivalence is homotopic to its inverse

```agda
module _
  {l1 l2 : Level} {A : UU l1} {B : UU l2} (e : A  B)
  where

  htpy-map-inv-equiv-retraction :
    (f : retraction (map-equiv e)) 
    map-inv-equiv e ~ map-retraction (map-equiv e) f
  htpy-map-inv-equiv-retraction (f , H) =
    (inv-htpy H ·r map-inv-equiv e) ∙h (f ·l is-section-map-inv-equiv e)
```

### Equivalences in commuting squares

```agda
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-left-map-triangle
      ( 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-left-map-triangle
      ( 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

```text
        h
    A -----> C
    |        |
  f |        | g
    ∨        ∨
    B -----> D
        i
```

```agda
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-top-map-triangle (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-top-map-triangle (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-left-map-triangle (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-left-map-triangle (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-right-map-triangle (i  f) g h H (is-equiv-comp i f Ef Ei) Eh
```

### Equivalences are embeddings

```agda
module _
  {l1 l2 : Level} {A : UU l1} {B : UU l2}
  where

  abstract
    is-emb-is-equiv :
      {f : A  B}  is-equiv f  (x y : A)  is-equiv (ap f {x} {y})
    is-emb-is-equiv H x y =
      is-equiv-is-invertible'
        ( is-invertible-ap-is-coherently-invertible
          ( is-coherently-invertible-is-equiv H))

  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

  map-inv-equiv-ap :
    (e : A  B) (x y : A)  map-equiv e x  map-equiv e y  x  y
  map-inv-equiv-ap e x y = map-inv-equiv (equiv-ap e x y)
```

## Equivalence reasoning

Equivalences can be constructed by equational reasoning in the following way:

```text
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.

**Note.** In situations where it is important to have precise control over an
equivalence or its inverse, it is often better to avoid making use of
equivalence reasoning. For example, since many of the entries proving that a map
is an equivalence are marked as `abstract` in agda-unimath, the inverse of an
equivalence often does not compute to any map that one might expect the inverse
to be. If inverses of equivalences are used in equivalence reasoning, this
results in a composed equivalence that also does not compute to any expected
underlying map.

Even if a proof by equivalence reasoning is clear to the human reader,
constructing equivalences by hand by constructing maps back and forth and two
homotopies witnessing that they are mutual inverses is often the most
straigtforward solution that gives the best expected computational behavior of
the constructed equivalence. In particular, if the underlying map or its inverse
are noteworthy maps, it is good practice to define them directly rather than as
underlying maps of equivalences constructed by equivalence reasoning.

```agda
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 notion of coherently invertible maps, also known as half-adjoint
  equivalences, see
  [`foundation.coherently-invertible-maps`](foundation.coherently-invertible-maps.md).
- For the notion of maps with contractible fibers see
  [`foundation.contractible-maps`](foundation.contractible-maps.md).
- For the notion of path-split maps see
  [`foundation.path-split-maps`](foundation.path-split-maps.md).
- For the notion of finitely coherent equivalence, see
  [`foundation.finitely-coherent-equivalence`)(foundation.finitely-coherent-equivalence.md).
- For the notion of finitely coherently invertible map, see
  [`foundation.finitely-coherently-invertible-map`)(foundation.finitely-coherently-invertible-map.md).
- For the notion of infinitely coherent equivalence, see
  [`foundation.infinitely-coherent-equivalences`](foundation.infinitely-coherent-equivalences.md).

### Table of files about function types, composition, and equivalences

{{#include tables/composition.md}}