# Identity types ```agda module foundation.identity-types where open import foundation-core.identity-types public ``` <details><summary>Imports</summary> ```agda open import foundation.action-on-identifications-functions open import foundation.binary-equivalences open import foundation.commuting-pentagons-of-identifications open import foundation.dependent-pair-types open import foundation.equivalence-extensionality open import foundation.function-extensionality open import foundation.universe-levels open import foundation-core.equivalences open import foundation-core.fibers-of-maps open import foundation-core.function-types open import foundation-core.homotopies ``` </details> ## Idea The equality relation on a type is a reflexive relation, with the universal property that it maps uniquely into any other reflexive relation. In type theory, we introduce the identity type as an inductive family of types, where the induction principle can be understood as expressing that the identity type is the least reflexive relation. ## Table of files directly related to identity types The following table lists files that are about identity types and operations on identifications in arbitrary types. {{#include tables/identity-types.md}} ## Properties ### The Mac Lane pentagon for identity types ```agda mac-lane-pentagon : {l : Level} {A : UU l} {a b c d e : A} (p : a = b) (q : b = c) (r : c = d) (s : d = e) → let α₁ = (ap (_∙ s) (assoc p q r)) α₂ = (assoc p (q ∙ r) s) α₃ = (ap (p ∙_) (assoc q r s)) α₄ = (assoc (p ∙ q) r s) α₅ = (assoc p q (r ∙ s)) in coherence-pentagon-identifications α₁ α₄ α₂ α₅ α₃ mac-lane-pentagon refl refl refl refl = refl ``` ### The groupoidal operations on identity types are equivalences ```agda module _ {l : Level} {A : UU l} where abstract is-equiv-inv : (x y : A) → is-equiv (λ (p : x = y) → inv p) is-equiv-inv x y = is-equiv-is-invertible inv inv-inv inv-inv equiv-inv : (x y : A) → (x = y) ≃ (y = x) pr1 (equiv-inv x y) = inv pr2 (equiv-inv x y) = is-equiv-inv x y abstract is-equiv-concat : {x y : A} (p : x = y) (z : A) → is-equiv (concat p z) is-equiv-concat p z = is-equiv-is-invertible ( inv-concat p z) ( is-section-inv-concat p) ( is-retraction-inv-concat p) abstract is-equiv-inv-concat : {x y : A} (p : x = y) (z : A) → is-equiv (inv-concat p z) is-equiv-inv-concat p z = is-equiv-is-invertible ( concat p z) ( is-retraction-inv-concat p) ( is-section-inv-concat p) equiv-concat : {x y : A} (p : x = y) (z : A) → (y = z) ≃ (x = z) pr1 (equiv-concat p z) = concat p z pr2 (equiv-concat p z) = is-equiv-concat p z equiv-inv-concat : {x y : A} (p : x = y) (z : A) → (x = z) ≃ (y = z) pr1 (equiv-inv-concat p z) = inv-concat p z pr2 (equiv-inv-concat p z) = is-equiv-inv-concat p z map-equiv-concat-equiv : {x x' : A} → ((y : A) → (x = y) ≃ (x' = y)) → (x' = x) map-equiv-concat-equiv {x} e = map-equiv (e x) refl is-section-equiv-concat : {x x' : A} → map-equiv-concat-equiv {x} {x'} ∘ equiv-concat ~ id is-section-equiv-concat refl = refl abstract is-retraction-equiv-concat : {x x' : A} → equiv-concat ∘ map-equiv-concat-equiv {x} {x'} ~ id is-retraction-equiv-concat e = eq-htpy (λ y → eq-htpy-equiv (λ where refl → right-unit)) abstract is-equiv-map-equiv-concat-equiv : {x x' : A} → is-equiv (map-equiv-concat-equiv {x} {x'}) is-equiv-map-equiv-concat-equiv = is-equiv-is-invertible ( equiv-concat) ( is-section-equiv-concat) ( is-retraction-equiv-concat) equiv-concat-equiv : {x x' : A} → ((y : A) → (x = y) ≃ (x' = y)) ≃ (x' = x) pr1 equiv-concat-equiv = map-equiv-concat-equiv pr2 equiv-concat-equiv = is-equiv-map-equiv-concat-equiv abstract is-equiv-concat' : (x : A) {y z : A} (q : y = z) → is-equiv (concat' x q) is-equiv-concat' x q = is-equiv-is-invertible ( inv-concat' x q) ( is-section-inv-concat' q) ( is-retraction-inv-concat' q) abstract is-equiv-inv-concat' : (x : A) {y z : A} (q : y = z) → is-equiv (inv-concat' x q) is-equiv-inv-concat' x q = is-equiv-is-invertible ( concat' x q) ( is-retraction-inv-concat' q) ( is-section-inv-concat' q) equiv-concat' : (x : A) {y z : A} (q : y = z) → (x = y) ≃ (x = z) pr1 (equiv-concat' x q) = concat' x q pr2 (equiv-concat' x q) = is-equiv-concat' x q equiv-inv-concat' : (x : A) {y z : A} (q : y = z) → (x = z) ≃ (x = y) pr1 (equiv-inv-concat' x q) = inv-concat' x q pr2 (equiv-inv-concat' x q) = is-equiv-inv-concat' x q is-binary-equiv-concat : {l : Level} {A : UU l} {x y z : A} → is-binary-equiv (λ (p : x = y) (q : y = z) → p ∙ q) pr1 (is-binary-equiv-concat {x = x}) q = is-equiv-concat' x q pr2 (is-binary-equiv-concat {z = z}) p = is-equiv-concat p z equiv-binary-concat : {l : Level} {A : UU l} {x y z w : A} → (p : x = y) (q : z = w) → (y = z) ≃ (x = w) equiv-binary-concat {x = x} {z = z} p q = (equiv-concat' x q) ∘e (equiv-concat p z) convert-eq-values : {l1 l2 : Level} {A : UU l1} {B : UU l2} {f g : A → B} (H : f ~ g) (x y : A) → (f x = f y) ≃ (g x = g y) convert-eq-values {f = f} {g} H x y = ( equiv-concat' (g x) (H y)) ∘e (equiv-concat (inv (H x)) (f y)) module _ {l1 : Level} {A : UU l1} where is-section-is-injective-concat : {x y z : A} (p : x = y) {q r : y = z} (s : (p ∙ q) = (p ∙ r)) → ap (concat p z) (is-injective-concat p s) = s is-section-is-injective-concat refl refl = refl cases-is-section-is-injective-concat' : {x y : A} {p q : x = y} (s : p = q) → ( ap ( concat' x refl) ( is-injective-concat' refl (right-unit ∙ (s ∙ inv right-unit)))) = ( right-unit ∙ (s ∙ inv right-unit)) cases-is-section-is-injective-concat' {p = refl} refl = refl is-section-is-injective-concat' : {x y z : A} (r : y = z) {p q : x = y} (s : (p ∙ r) = (q ∙ r)) → ap (concat' x r) (is-injective-concat' r s) = s is-section-is-injective-concat' refl s = ( ap (λ u → ap (concat' _ refl) (is-injective-concat' refl u)) (inv α)) ∙ ( ( cases-is-section-is-injective-concat' ( inv right-unit ∙ (s ∙ right-unit))) ∙ ( α)) where α : ( ( right-unit) ∙ ( ( inv right-unit ∙ (s ∙ right-unit)) ∙ ( inv right-unit))) = ( s) α = ( ap ( concat right-unit _) ( ( assoc (inv right-unit) (s ∙ right-unit) (inv right-unit)) ∙ ( ( ap ( concat (inv right-unit) _) ( ( assoc s right-unit (inv right-unit)) ∙ ( ( ap (concat s _) (right-inv right-unit)) ∙ ( right-unit))))))) ∙ ( ( inv (assoc right-unit (inv right-unit) s)) ∙ ( ( ap (concat' _ s) (right-inv right-unit)))) ``` ### Applying the right unit law on one side of a higher identification is an equivalence ```agda module _ {l : Level} {A : UU l} {x y : A} where equiv-right-unit : (p : x = y) (q : x = y) → (p = q) ≃ (p ∙ refl = q) equiv-right-unit p = equiv-concat right-unit equiv-right-unit' : (p : x = y) (q : x = y) → (p = q ∙ refl) ≃ (p = q) equiv-right-unit' p q = equiv-concat' p right-unit ``` ### Reassociating one side of a higher identification is an equivalence ```agda module _ {l : Level} {A : UU l} {x y z u : A} where equiv-concat-assoc : (p : x = y) (q : y = z) (r : z = u) (s : x = u) → ((p ∙ q) ∙ r = s) ≃ (p ∙ (q ∙ r) = s) equiv-concat-assoc p q r = equiv-concat (inv (assoc p q r)) equiv-concat-assoc' : (s : x = u) (p : x = y) (q : y = z) (r : z = u) → (s = (p ∙ q) ∙ r) ≃ (s = p ∙ (q ∙ r)) equiv-concat-assoc' s p q r = equiv-concat' s (assoc p q r) ``` ### Transposing inverses is an equivalence ```agda module _ {l : Level} {A : UU l} {x y z : A} where abstract is-equiv-left-transpose-eq-concat : (p : x = y) (q : y = z) (r : x = z) → is-equiv (left-transpose-eq-concat p q r) is-equiv-left-transpose-eq-concat refl q r = is-equiv-id equiv-left-transpose-eq-concat : (p : x = y) (q : y = z) (r : x = z) → ((p ∙ q) = r) ≃ (q = ((inv p) ∙ r)) pr1 (equiv-left-transpose-eq-concat p q r) = left-transpose-eq-concat p q r pr2 (equiv-left-transpose-eq-concat p q r) = is-equiv-left-transpose-eq-concat p q r equiv-left-transpose-eq-concat' : (p : x = z) (q : x = y) (r : y = z) → (p = q ∙ r) ≃ (inv q ∙ p = r) equiv-left-transpose-eq-concat' p q r = equiv-inv _ _ ∘e equiv-left-transpose-eq-concat q r p ∘e equiv-inv _ _ left-transpose-eq-concat' : (p : x = z) (q : x = y) (r : y = z) → p = q ∙ r → inv q ∙ p = r left-transpose-eq-concat' p q r = map-equiv (equiv-left-transpose-eq-concat' p q r) abstract is-equiv-right-transpose-eq-concat : (p : x = y) (q : y = z) (r : x = z) → is-equiv (right-transpose-eq-concat p q r) is-equiv-right-transpose-eq-concat p refl r = is-equiv-comp ( concat' p (inv right-unit)) ( concat (inv right-unit) r) ( is-equiv-concat (inv right-unit) r) ( is-equiv-concat' p (inv right-unit)) equiv-right-transpose-eq-concat : (p : x = y) (q : y = z) (r : x = z) → (p ∙ q = r) ≃ (p = r ∙ inv q) pr1 (equiv-right-transpose-eq-concat p q r) = right-transpose-eq-concat p q r pr2 (equiv-right-transpose-eq-concat p q r) = is-equiv-right-transpose-eq-concat p q r equiv-right-transpose-eq-concat' : (p : x = z) (q : x = y) (r : y = z) → (p = q ∙ r) ≃ (p ∙ inv r = q) equiv-right-transpose-eq-concat' p q r = equiv-inv q (p ∙ inv r) ∘e equiv-right-transpose-eq-concat q r p ∘e equiv-inv p (q ∙ r) right-transpose-eq-concat' : (p : x = z) (q : x = y) (r : y = z) → p = q ∙ r → p ∙ inv r = q right-transpose-eq-concat' p q r = map-equiv (equiv-right-transpose-eq-concat' p q r) ``` ### Computation of fibers of families of maps out of the identity type We show that `fiber (f x) y ≃ ((* , f * refl) = (x , y))` for every `x : A` and `y : B x`. ```agda module _ {l1 l2 : Level} {A : UU l1} {a : A} {B : A → UU l2} (f : (x : A) → (a = x) → B x) (x : A) (y : B x) where map-compute-fiber-map-out-of-identity-type : fiber (f x) y → ((a , f a refl) = (x , y)) map-compute-fiber-map-out-of-identity-type (refl , refl) = refl map-inv-compute-fiber-map-out-of-identity-type : ((a , f a refl) = (x , y)) → fiber (f x) y map-inv-compute-fiber-map-out-of-identity-type refl = refl , refl is-section-map-inv-compute-fiber-map-out-of-identity-type : map-compute-fiber-map-out-of-identity-type ∘ map-inv-compute-fiber-map-out-of-identity-type ~ id is-section-map-inv-compute-fiber-map-out-of-identity-type refl = refl is-retraction-map-inv-compute-fiber-map-out-of-identity-type : map-inv-compute-fiber-map-out-of-identity-type ∘ map-compute-fiber-map-out-of-identity-type ~ id is-retraction-map-inv-compute-fiber-map-out-of-identity-type (refl , refl) = refl is-equiv-map-compute-fiber-map-out-of-identity-type : is-equiv map-compute-fiber-map-out-of-identity-type is-equiv-map-compute-fiber-map-out-of-identity-type = is-equiv-is-invertible map-inv-compute-fiber-map-out-of-identity-type is-section-map-inv-compute-fiber-map-out-of-identity-type is-retraction-map-inv-compute-fiber-map-out-of-identity-type compute-fiber-map-out-of-identity-type : fiber (f x) y ≃ ((a , f a refl) = (x , y)) pr1 compute-fiber-map-out-of-identity-type = map-compute-fiber-map-out-of-identity-type pr2 compute-fiber-map-out-of-identity-type = is-equiv-map-compute-fiber-map-out-of-identity-type ```