# Action on equivalences of type families

```agda
module foundation.action-on-equivalences-type-families where
```

<details><summary>Imports</summary>

```agda
open import foundation.action-on-equivalences-functions
open import foundation.action-on-identifications-functions
open import foundation.equivalence-induction
open import foundation.univalence
open import foundation.universe-levels
open import foundation.whiskering-higher-homotopies-composition

open import foundation-core.commuting-squares-of-maps
open import foundation-core.constant-maps
open import foundation-core.contractible-types
open import foundation-core.equivalences
open import foundation-core.fibers-of-maps
open import foundation-core.function-types
open import foundation-core.homotopies
open import foundation-core.identity-types
```

</details>

## Ideas

Any family of types `B : 𝒰 → 𝒱` over a universe `𝒰` has an **action on
equivalences**

```text
  (A ≃ B) → P A ≃ P B
```

obtained by [equivalence induction](foundation.equivalence-induction.md). The
acion on equivalences of a type family `B` on a universe `𝒰` is uniquely
determined by the identification `B id-equiv = id-equiv`, and fits in a
[commuting square](foundation.commuting-squares-of-maps.md)

```text
                   ap B
        (X = Y) --------> (B X = B Y)
           |                    |
  equiv-eq |                    | equiv-eq
           ∨                    ∨
        (X ≃ Y) ---------> (B X ≃ B Y).
                     B
```

**Note:** In general -- in particular in our general constructions below -- we
need the [univalence axiom](foundation.univalence.md) to construct the action on
equivalences of a family of types. However, for many specific type families that
are defined in terms of the basic type constructors, we can construct the action
on equivalences directly without invoking the univalence axiom.

## Definitions

### The action on equivalences of a family of types over a universe

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

  abstract
    unique-action-equiv-family :
      {X : UU l1} 
      is-contr (fiber (ev-id-equiv  Y e  B X  B Y)) id-equiv)
    unique-action-equiv-family =
      is-contr-map-ev-id-equiv  Y e  B _  B Y) id-equiv

  action-equiv-family :
    {X Y : UU l1}  (X  Y)  B X  B Y
  action-equiv-family {X} {Y} =
    equiv-eq  action-equiv-function B

  compute-action-equiv-family-id-equiv :
    {X : UU l1} 
    action-equiv-family {X} {X} id-equiv  id-equiv
  compute-action-equiv-family-id-equiv {X} =
    ap equiv-eq (compute-action-equiv-function-id-equiv B X)

  map-action-equiv-family : {X Y : UU l1}  X  Y  B X  B Y
  map-action-equiv-family = map-equiv  action-equiv-family
```

## Properties

### The action on equivalences of a family of types over a universe fits in a commuting square with `equiv-eq`

We claim that the square

```text
                   ap B
        (X = Y) --------> (B X = B Y)
           |                    |
  equiv-eq |                    | equiv-eq
           ∨                    ∨
        (X ≃ Y) ---------> (B X ≃ B Y).
                     B
```

commutes for any two types `X Y : 𝒰` and any type family `B` over `𝒰`.

```agda
coherence-square-action-equiv-family :
  {l1 l2 : Level} (B : UU l1  UU l2) (X Y : UU l1) 
  coherence-square-maps
    ( ap B {X} {Y})
    ( equiv-eq)
    ( equiv-eq)
    ( action-equiv-family B)
coherence-square-action-equiv-family B X .X refl =
  compute-action-equiv-family-id-equiv B
```

### The identity function acts trivially on equivalences

```agda
compute-action-equiv-family-id :
  {l : Level} {X Y : UU l} (e : X  Y)  (action-equiv-family id e)  e
compute-action-equiv-family-id e =
  ap equiv-eq (ap-id (eq-equiv e))  is-section-eq-equiv e
```

### The action on equivalences of a constant map is constant

```agda
compute-action-equiv-family-const :
  {l1 l2 : Level} (B : UU l2) {X Y : UU l1}
  (e : X  Y)  (action-equiv-family (const (UU l1) B) e)  id-equiv
compute-action-equiv-family-const B {X} {Y} e =
  ap equiv-eq (compute-action-equiv-function-const B e)
```

### The action on equivalences of a composite function is the composite of the actions

```agda
distributive-action-equiv-function-comp :
  {l1 l2 l3 : Level} {C : UU l3} (g : UU l2  C) (f : UU l1  UU l2)
  {X Y : UU l1} 
  action-equiv-function (g  f) {X} {Y} ~
  action-equiv-function g  action-equiv-family f
distributive-action-equiv-function-comp g f e =
  ( ap-comp g f (eq-equiv e)) 
  ( left-whisker-comp² g
    ( inv-htpy is-retraction-eq-equiv)
    ( action-equiv-function f e))

distributive-action-equiv-family-comp :
  {l1 l2 l3 : Level} (g : UU l2  UU l3) (f : UU l1  UU l2)
  {X Y : UU l1} 
  action-equiv-family (g  f) {X} {Y} ~
  action-equiv-family g  action-equiv-family f
distributive-action-equiv-family-comp g f e =
  ap equiv-eq (distributive-action-equiv-function-comp g f e)
```

### The action on equivalences of any map preserves composition of equivalences

```agda
distributive-action-equiv-family-comp-equiv :
  {l1 l2 : Level} (f : UU l1  UU l2) {X Y Z : UU l1} 
  (e : X  Y) (e' : Y  Z) 
  action-equiv-family f (e' ∘e e) 
  action-equiv-family f e' ∘e action-equiv-family f e
distributive-action-equiv-family-comp-equiv f e e' =
  ( ap equiv-eq (distributive-action-equiv-function-comp-equiv f e e')) 
  ( inv
    ( compute-equiv-eq-concat
      ( action-equiv-function f e)
      ( action-equiv-function f e')))
```

### The action on equivalences of any map preserves inverses

```agda
compute-action-equiv-family-inv-equiv :
  {l1 l2 : Level} (f : UU l1  UU l2) {X Y : UU l1}
  (e : X  Y) 
  action-equiv-family f (inv-equiv e)  inv-equiv (action-equiv-family f e)
compute-action-equiv-family-inv-equiv f e =
  ( ap equiv-eq (compute-action-equiv-function-inv-equiv f e)) 
  ( inv (commutativity-inv-equiv-eq (action-equiv-function f e)))
```