# Yoneda identity types ```agda module foundation.yoneda-identity-types where ``` <details><summary>Imports</summary> ```agda open import foundation.action-on-identifications-functions open import foundation.dependent-pair-types open import foundation.function-extensionality open import foundation.multivariable-homotopies open import foundation.strictly-right-unital-concatenation-identifications open import foundation.transport-along-identifications open import foundation.univalence open import foundation.universal-property-identity-systems open import foundation.universe-levels open import foundation-core.contractible-types open import foundation-core.equivalences open import foundation-core.function-types open import foundation-core.functoriality-dependent-pair-types 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.torsorial-type-families ``` </details> ## Idea The standard definition of [identity types](foundation-core.identity-types.md) has the limitation that many of the basic operations only satisfy algebraic laws _weakly_. On this page, we consider the {{#concept "Yoneda identity types" Agda=yoneda-Id}} ```text (x =ʸ y) := (z : A) → (z = x) → (z = y) ``` Through the interpretation of types as ∞-categories, where the hom-space `hom(x , y)` is defined to be the identity type `x = y`, we may observe that this is an instance of the Yoneda embedding. We use a superscript `y` in the notation of the Yoneda identity types, and similarly we call elements of the Yoneda identity types for {{#concept "Yoneda identifications" Agda=yoneda-Id}}. The Yoneda identity types are [equivalent](foundation-core.equivalences.md) to the standard identity types, but satisfy strict laws - `(p ∙ʸ q) ∙ʸ r ≐ p ∙ʸ (q ∙ʸ r)`, - `reflʸ ∙ʸ p ≐ p`, and - `p ∙ʸ reflʸ ≐ p`. This is achieved by proxying to function composition and utilizing its computational properties, and relies heavily on the [function extensionality axiom](foundation.function-extensionality.md). More concretely, the reflexivity is given by the identity function, and path concatenation is given by function composition. In addition to these strictness laws, we can make the type satisfy the strict law `invʸ reflʸ ≐ reflʸ`. Moreover, while the induction principle of the Yoneda identity types does not in general satisfy the computation rule strictly, we can define its recursion principle such that does. ## Definition ```agda module _ {l : Level} {A : UU l} where yoneda-Id : (x y : A) → UU l yoneda-Id x y = (z : A) → z = x → z = y infix 6 _=ʸ_ _=ʸ_ : A → A → UU l (a =ʸ b) = yoneda-Id a b ``` We define the reflexivity by the identity function: ```agda reflʸ : {x : A} → x =ʸ x reflʸ z = id ``` ## Properties ### Elements of the Yoneda identity type act like postconcatenation operations The following is a collection of properties of Yoneda identifications similar to properties of the postconcatenation operation of identifications. ```agda module _ {l : Level} {A : UU l} where commutative-preconcat-Id-yoneda-Id : {x y z w : A} (f : x =ʸ y) (p : w = z) (q : z = x) → f w (p ∙ q) = p ∙ f z q commutative-preconcat-Id-yoneda-Id f refl q = refl commutative-preconcat-refl-Id-yoneda-Id : {x y z : A} (f : x =ʸ y) (q : z = x) → f z q = q ∙ f x refl commutative-preconcat-refl-Id-yoneda-Id {z = z} f q = ap (f z) (inv right-unit) ∙ commutative-preconcat-Id-yoneda-Id f q refl commutative-preconcatr-Id-yoneda-Id : {x y z w : A} (f : x =ʸ y) (p : w = z) (q : z = x) → f w (p ∙ᵣ q) = p ∙ᵣ f z q commutative-preconcatr-Id-yoneda-Id {x} {y} {z} {w} f p q = ( ap (f w) (eq-concat-right-strict-concat p q)) ∙ ( commutative-preconcat-Id-yoneda-Id f p q) ∙ ( eq-right-strict-concat-concat p (f z q)) commutative-preconcatr-refl-Id-yoneda-Id : {x y z : A} (f : x =ʸ y) (q : z = x) → f z q = q ∙ᵣ f x refl commutative-preconcatr-refl-Id-yoneda-Id f q = commutative-preconcatr-Id-yoneda-Id f q refl compute-inv-Id-yoneda-Id : {x y : A} (f : x =ʸ y) → f y (inv (f x refl)) = refl compute-inv-Id-yoneda-Id {x} f = ( commutative-preconcat-refl-Id-yoneda-Id f (inv (f x refl))) ∙ ( left-inv (f x refl)) inv-distributive-inv-Id-yoneda-Id : {x y z : A} (f : x =ʸ y) (g : x =ʸ z) → inv (g y (inv (f x refl))) = f z (inv (g x refl)) inv-distributive-inv-Id-yoneda-Id {x} f g = ( ap inv (commutative-preconcat-refl-Id-yoneda-Id g (inv (f x refl)))) ∙ ( distributive-inv-concat (inv (f x refl)) (g x refl)) ∙ ( ap (inv (g x refl) ∙_) (inv-inv (f x refl))) ∙ ( inv (commutative-preconcat-refl-Id-yoneda-Id f (inv (g x refl)))) distributive-inv-Id-yoneda-Id : {x y z : A} (f : x =ʸ y) (g : x =ʸ z) → f z (inv (g x refl)) = inv (g y (inv (f x refl))) distributive-inv-Id-yoneda-Id f g = inv (inv-distributive-inv-Id-yoneda-Id f g) ``` ### The Yoneda identity types are equivalent to the standard identity types The equivalence `(x = y) ≃ (x =ʸ y)` is defined from left to right by the postconcatenation operation ```text yoneda-eq-eq := p ↦ (q ↦ q ∙ p) : x = y → x =ʸ y, ``` and from right to left by evaluation at the reflexivity ```text eq-yoneda-eq := f ↦ f refl : x =ʸ y → x = y. ``` It should be noted that we define the map `x = y → x =ʸ y` using the [strictly right unital concatenation operation](foundation.strictly-right-unital-concatenation-identifications.md). While this obstructs us from showing that the [homotopy](foundation-core.homotopies.md) `eq-yoneda-eq ∘ yoneda-eq-eq ~ id` holds by reflexivity as demonstrated by the computation ```text eq-yoneda-eq ∘ yoneda-eq-eq ≐ p ↦ (f ↦ f refl) (q ↦ q ∙ p) ≐ p ↦ ((q ↦ q ∙ p) refl) ≐ p ↦ refl ∙ p, ``` it allows us to show that reflexivities are preserved strictly in both directions, and not just from `x =ʸ y` to `x = y`. From left to right: ```text yoneda-eq-eq refl ≐ (p ↦ (q ↦ q ∙ p)) refl ≐ (q ↦ q ∙ refl) ≐ (q ↦ q) ≐ reflʸ ``` and from right to left: ```text eq-yoneda-eq reflʸ ≐ (f ↦ f refl) reflʸ ≐ (q ↦ q) refl ≐ refl. ``` ```agda module _ {l : Level} {A : UU l} {x y : A} where yoneda-eq-eq : x = y → x =ʸ y yoneda-eq-eq p z q = q ∙ᵣ p eq-yoneda-eq : x =ʸ y → x = y eq-yoneda-eq f = f x refl ``` The construction of the homotopy `yoneda-eq-eq ∘ eq-yoneda-eq ~ id` requires the [function extensionality axiom](foundation.function-extensionality.md). And while we could show an analogous induction principle of the Yoneda identity types without the use of this axiom, function extensionality will become indispensable regardless when we proceed to proving miscellaneous algebraic laws of the Yoneda identity type. ```agda is-section-eq-yoneda-eq : is-section yoneda-eq-eq eq-yoneda-eq is-section-eq-yoneda-eq f = eq-multivariable-htpy 2 ( λ _ p → inv (commutative-preconcatr-refl-Id-yoneda-Id f p)) is-retraction-eq-yoneda-eq : is-retraction yoneda-eq-eq eq-yoneda-eq is-retraction-eq-yoneda-eq p = left-unit-right-strict-concat is-equiv-yoneda-eq-eq : is-equiv yoneda-eq-eq pr1 (pr1 is-equiv-yoneda-eq-eq) = eq-yoneda-eq pr2 (pr1 is-equiv-yoneda-eq-eq) = is-section-eq-yoneda-eq pr1 (pr2 is-equiv-yoneda-eq-eq) = eq-yoneda-eq pr2 (pr2 is-equiv-yoneda-eq-eq) = is-retraction-eq-yoneda-eq is-equiv-eq-yoneda-eq : is-equiv eq-yoneda-eq pr1 (pr1 is-equiv-eq-yoneda-eq) = yoneda-eq-eq pr2 (pr1 is-equiv-eq-yoneda-eq) = is-retraction-eq-yoneda-eq pr1 (pr2 is-equiv-eq-yoneda-eq) = yoneda-eq-eq pr2 (pr2 is-equiv-eq-yoneda-eq) = is-section-eq-yoneda-eq equiv-yoneda-eq-eq : (x = y) ≃ (x =ʸ y) pr1 equiv-yoneda-eq-eq = yoneda-eq-eq pr2 equiv-yoneda-eq-eq = is-equiv-yoneda-eq-eq equiv-eq-yoneda-eq : (x =ʸ y) ≃ (x = y) pr1 equiv-eq-yoneda-eq = eq-yoneda-eq pr2 equiv-eq-yoneda-eq = is-equiv-eq-yoneda-eq ``` This equvialence preserves the reflexivity elements strictly in both directions. ```agda module _ {l : Level} {A : UU l} {x : A} where is-section-eq-yoneda-eq-refl : yoneda-eq-eq (eq-yoneda-eq (reflʸ {x = x})) = reflʸ is-section-eq-yoneda-eq-refl = refl preserves-refl-yoneda-eq-eq : yoneda-eq-eq (refl {x = x}) = reflʸ preserves-refl-yoneda-eq-eq = refl preserves-refl-eq-yoneda-eq : eq-yoneda-eq (reflʸ {x = x}) = refl preserves-refl-eq-yoneda-eq = refl ``` Below, we consider the alternative definition of `yoneda-eq-eq` using the strictly left unital concatenation operation on standard identity types. As we can see, the retracting homotopy holds strictly, but now `yoneda-eq-eq refl` does not compute strictly to `reflʸ`. ```agda module _ {l : Level} {A : UU l} {x y : A} where yoneda-eq-eq' : x = y → x =ʸ y yoneda-eq-eq' p z q = q ∙ p is-section-eq-yoneda-eq' : is-section yoneda-eq-eq' eq-yoneda-eq is-section-eq-yoneda-eq' f = eq-multivariable-htpy 2 ( λ _ p → inv (commutative-preconcat-refl-Id-yoneda-Id f p)) is-retraction-eq-yoneda-eq' : is-retraction yoneda-eq-eq' eq-yoneda-eq is-retraction-eq-yoneda-eq' p = refl module _ {l : Level} {A : UU l} where preserves-refl-yoneda-eq-eq' : {x : A} → yoneda-eq-eq' (refl {x = x}) = reflʸ preserves-refl-yoneda-eq-eq' = eq-multivariable-htpy 2 (λ _ p → right-unit) ``` ### Torsoriality of the Yoneda identity types ```agda module _ {l : Level} {A : UU l} {x : A} where is-torsorial-yoneda-Id : is-torsorial (yoneda-Id x) is-torsorial-yoneda-Id = is-contr-equiv ( Σ A (x =_)) ( equiv-tot (λ y → equiv-eq-yoneda-eq {x = x} {y})) ( is-torsorial-Id x) ``` ### The dependent universal property of the Yoneda identity types ```agda module _ {l : Level} {A : UU l} {x : A} where dependent-universal-property-identity-system-yoneda-Id : dependent-universal-property-identity-system ( yoneda-Id x) ( reflʸ) dependent-universal-property-identity-system-yoneda-Id = dependent-universal-property-identity-system-is-torsorial ( reflʸ) ( is-torsorial-yoneda-Id) ``` ### The induction principle for the Yoneda identity types The Yoneda identity types satisfy the induction principle of the identity types. This states that given a base point `x : A` and a family of types over the identity types based at `x`, `B : (y : A) (f : x =ʸ y) → UU l2`, then to construct a dependent function `g : (y : A) (f : x =ʸ y) → B y p` it suffices to define it at `g x reflʸ`. **Note.** As stated before, a drawback of the Yoneda identity types is that they do not satisfy a strict computation rule for this induction principle. ```agda module _ {l1 l2 : Level} {A : UU l1} {x : A} (B : (y : A) (f : x =ʸ y) → UU l2) where ind-yoneda-Id' : (b : B x reflʸ) {y : A} (f : x =ʸ y) → B y f ind-yoneda-Id' b {y} = map-inv-is-equiv ( dependent-universal-property-identity-system-yoneda-Id B) ( b) ( y) compute-ind-yoneda-Id' : (b : B x reflʸ) → ind-yoneda-Id' b reflʸ = b compute-ind-yoneda-Id' = is-section-map-inv-is-equiv ( dependent-universal-property-identity-system-yoneda-Id B) uniqueness-ind-yoneda-Id' : (b : (y : A) (f : x =ʸ y) → B y f) → (λ y → ind-yoneda-Id' (b x reflʸ) {y}) = b uniqueness-ind-yoneda-Id' = is-retraction-map-inv-is-equiv ( dependent-universal-property-identity-system-yoneda-Id B) ``` The following is a more concrete construction of the induction principle. We observe that while `eq-yoneda-eq` and `yoneda-eq-eq` preserve reflexivities strictly as required, the reduction is obstructed because the proof of `is-section-eq-yoneda-eq` does not reduce to `refl` when `f ≐ reflʸ`. ```agda module _ {l1 l2 : Level} {A : UU l1} {x : A} (B : (y : A) (f : x =ʸ y) → UU l2) where ind-yoneda-Id : (b : B x reflʸ) {y : A} (f : x =ʸ y) → B y f ind-yoneda-Id b {y} f = tr ( B y) ( is-section-eq-yoneda-eq f) ( ind-Id x (λ y p → B y (yoneda-eq-eq p)) b y (eq-yoneda-eq f)) ``` While the induction principle does not have the desired reduction behaviour, the nondependent eliminator does. This is simply because we no longer need to [transport](foundation-core.transport-along-identifications.md) along `is-section-eq-yoneda-eq`. ```agda module _ {l1 l2 : Level} {A : UU l1} {x : A} {B : A → UU l2} where rec-yoneda-Id : (b : B x) {y : A} → x =ʸ y → B y rec-yoneda-Id b f = tr B (eq-yoneda-eq f) b compute-rec-yoneda-Id : (b : B x) → rec-yoneda-Id b reflʸ = b compute-rec-yoneda-Id b = refl uniqueness-rec-yoneda-Id : (b : (y : A) → x =ʸ y → B y) → (λ y → rec-yoneda-Id (b x reflʸ) {y}) = b uniqueness-rec-yoneda-Id b = ( inv ( uniqueness-ind-yoneda-Id' ( λ y _ → B y) ( λ y → rec-yoneda-Id (b x reflʸ)))) ∙ ( uniqueness-ind-yoneda-Id' (λ y _ → B y) b) ``` ## Structure The Yoneda identity types form a strictly compositional weak groupoidal structure on types. ### Inverting Yoneda identifications We consider two ways of defining the inversion operation on Yoneda identifications: by the strictly right unital, and strictly left unital concatenation operation on the underlying identity type respectively. In contrast to the latter, the former enjoys the computational property ```text invʸ reflʸ ≐ reflʸ, ``` hence it will be preferred going forward. #### The inversion operation defined by the strictly right unital concatenation operation on identifications ```agda module _ {l : Level} {A : UU l} where invʸ : {x y : A} → x =ʸ y → y =ʸ x invʸ {x} f z p = p ∙ᵣ inv (f x refl) compute-inv-refl-yoneda-Id : {x : A} → invʸ (reflʸ {x = x}) = reflʸ compute-inv-refl-yoneda-Id = refl inv-inv-yoneda-Id : {x y : A} (f : x =ʸ y) → invʸ (invʸ f) = f inv-inv-yoneda-Id {x} f = eq-multivariable-htpy 2 ( λ _ p → ( ap ( p ∙ᵣ_) ( ap inv left-unit-right-strict-concat ∙ inv-inv (f x refl))) ∙ ( inv (commutative-preconcatr-refl-Id-yoneda-Id f p))) ``` The inversion operation corresponds to the standard inversion operation on identifications: ```agda module _ {l : Level} {A : UU l} where preserves-inv-yoneda-eq-eq' : {x y : A} (p : x = y) → yoneda-eq-eq (inv p) = invʸ (yoneda-eq-eq' p) preserves-inv-yoneda-eq-eq' p = refl preserves-inv-yoneda-eq-eq : {x y : A} (p : x = y) → yoneda-eq-eq (inv p) = invʸ (yoneda-eq-eq p) preserves-inv-yoneda-eq-eq p = eq-multivariable-htpy 2 ( λ _ q → ap (λ r → q ∙ᵣ inv r) (inv left-unit-right-strict-concat)) preserves-inv-eq-yoneda-eq : {x y : A} (f : x =ʸ y) → eq-yoneda-eq (invʸ f) = inv (eq-yoneda-eq f) preserves-inv-eq-yoneda-eq f = left-unit-right-strict-concat ``` #### The inversion operation defined by the strictly left unital concatenation operation on identifications ```agda module _ {l : Level} {A : UU l} where left-strict-inv-yoneda-Id : {x y : A} → x =ʸ y → y =ʸ x left-strict-inv-yoneda-Id {x} f z p = p ∙ inv (f x refl) compute-left-strict-inv-yoneda-Id-refl : {x : A} → left-strict-inv-yoneda-Id (reflʸ {x = x}) = reflʸ compute-left-strict-inv-yoneda-Id-refl = eq-multivariable-htpy 2 (λ _ p → right-unit) left-strict-inv-left-strict-inv-yoneda-Id : {x y : A} (f : x =ʸ y) → left-strict-inv-yoneda-Id (left-strict-inv-yoneda-Id f) = f left-strict-inv-left-strict-inv-yoneda-Id {x} f = eq-multivariable-htpy 2 ( λ _ p → ( ap (p ∙_) (inv-inv (f x refl))) ∙ ( inv (commutative-preconcat-refl-Id-yoneda-Id f p))) ``` This inversion operation also corresponds to the standard inversion operation on identifications: ```agda module _ {l : Level} {A : UU l} where preserves-left-strict-inv-yoneda-eq-eq : {x y : A} (p : x = y) → yoneda-eq-eq (inv p) = left-strict-inv-yoneda-Id (yoneda-eq-eq p) preserves-left-strict-inv-yoneda-eq-eq p = eq-multivariable-htpy 2 ( λ _ q → ( eq-concat-right-strict-concat q (inv p)) ∙ ( ap (λ r → q ∙ inv r) (inv left-unit-right-strict-concat))) preserves-left-strict-inv-eq-yoneda-eq : {x y : A} (f : x =ʸ y) → eq-yoneda-eq (left-strict-inv-yoneda-Id f) = inv (eq-yoneda-eq f) preserves-left-strict-inv-eq-yoneda-eq f = refl ``` ### Concatenation of Yoneda identifications The concatenation operation on Yoneda identifications is defined by function composition ```text f ∙ʸ g := z p ↦ g z (f z p) ``` and is thus strictly associative and two-sided unital (since the reflexivities are given by the identity functions). ```agda module _ {l : Level} {A : UU l} where infixl 15 _∙ʸ_ _∙ʸ_ : {x y z : A} → x =ʸ y → y =ʸ z → x =ʸ z (f ∙ʸ g) z p = g z (f z p) concat-yoneda-Id : {x y : A} → x =ʸ y → (z : A) → y =ʸ z → x =ʸ z concat-yoneda-Id f z g = f ∙ʸ g concat-yoneda-Id' : (x : A) {y z : A} → y =ʸ z → x =ʸ y → x =ʸ z concat-yoneda-Id' x g f = f ∙ʸ g ``` The concatenation operation corresponds to the standard concatenation operation on identifications: ```agda module _ {l : Level} {A : UU l} where preserves-concat-yoneda-eq-eq : {x y z : A} (p : x = y) (q : y = z) → yoneda-eq-eq (p ∙ q) = yoneda-eq-eq p ∙ʸ yoneda-eq-eq q preserves-concat-yoneda-eq-eq refl refl = refl preserves-concat-eq-yoneda-eq : {x y z : A} (f : x =ʸ y) (g : y =ʸ z) → eq-yoneda-eq (f ∙ʸ g) = eq-yoneda-eq f ∙ eq-yoneda-eq g preserves-concat-eq-yoneda-eq {x} f g = commutative-preconcat-refl-Id-yoneda-Id g (f x refl) ``` ### The groupoidal laws for the Yoneda identity types As we may now observe, associativity and the unit laws hold by `refl`. ```agda module _ {l : Level} {A : UU l} {x y : A} where assoc-yoneda-Id : (f : x =ʸ y) {z w : A} (g : y =ʸ z) (h : z =ʸ w) → (f ∙ʸ g) ∙ʸ h = f ∙ʸ (g ∙ʸ h) assoc-yoneda-Id f g h = refl left-unit-yoneda-Id : {f : x =ʸ y} → reflʸ ∙ʸ f = f left-unit-yoneda-Id = refl right-unit-yoneda-Id : {f : x =ʸ y} → f ∙ʸ reflʸ = f right-unit-yoneda-Id = refl ``` In addition, we show a range of basic algebraic laws for the Yoneda identity types. ```agda left-inv-yoneda-Id : (f : x =ʸ y) → invʸ f ∙ʸ f = reflʸ left-inv-yoneda-Id f = eq-multivariable-htpy 2 ( λ _ p → ( commutative-preconcatr-Id-yoneda-Id f p (inv (f x refl))) ∙ ( ap (p ∙ᵣ_) (compute-inv-Id-yoneda-Id f))) left-left-strict-inv-yoneda-Id : (f : x =ʸ y) → left-strict-inv-yoneda-Id f ∙ʸ f = reflʸ left-left-strict-inv-yoneda-Id f = eq-multivariable-htpy 2 ( λ _ p → ( commutative-preconcat-Id-yoneda-Id f p (inv (f x refl))) ∙ ( ap (p ∙_) (compute-inv-Id-yoneda-Id f) ∙ right-unit)) right-inv-yoneda-Id : (f : x =ʸ y) → f ∙ʸ invʸ f = reflʸ right-inv-yoneda-Id f = eq-multivariable-htpy 2 ( λ _ p → ( ap ( _∙ᵣ inv (f x refl)) ( commutative-preconcatr-refl-Id-yoneda-Id f p)) ∙ ( assoc-right-strict-concat p (f x refl) (inv (f x refl))) ∙ ( ap (p ∙ᵣ_) (right-inv-right-strict-concat (f x refl)))) right-left-strict-inv-yoneda-Id : (f : x =ʸ y) → f ∙ʸ left-strict-inv-yoneda-Id f = reflʸ right-left-strict-inv-yoneda-Id f = eq-multivariable-htpy 2 ( λ _ p → ( ap ( _∙ inv (f x refl)) ( commutative-preconcat-refl-Id-yoneda-Id f p)) ∙ ( assoc p (f x refl) (inv (f x refl))) ∙ ( ap (p ∙_) (right-inv (f x refl))) ∙ ( right-unit)) distributive-inv-concat-yoneda-Id : (f : x =ʸ y) {z : A} (g : y =ʸ z) → invʸ (f ∙ʸ g) = invʸ g ∙ʸ invʸ f distributive-inv-concat-yoneda-Id f g = eq-multivariable-htpy 2 ( λ _ p → ( ap ( p ∙ᵣ_) ( ( ap ( inv) ( commutative-preconcatr-refl-Id-yoneda-Id g (f x refl))) ∙ ( distributive-inv-right-strict-concat (f x refl) (g y refl)))) ∙ ( inv ( assoc-right-strict-concat p (inv (g y refl)) (inv (f x refl))))) distributive-left-strict-inv-concat-yoneda-Id : (f : x =ʸ y) {z : A} (g : y =ʸ z) → left-strict-inv-yoneda-Id (f ∙ʸ g) = left-strict-inv-yoneda-Id g ∙ʸ left-strict-inv-yoneda-Id f distributive-left-strict-inv-concat-yoneda-Id f g = eq-multivariable-htpy 2 ( λ _ p → ( ap ( p ∙_) ( ( ap ( inv) ( commutative-preconcat-refl-Id-yoneda-Id g (f x refl))) ∙ ( distributive-inv-concat (f x refl) (g y refl)))) ∙ ( inv (assoc p (inv (g y refl)) (inv (f x refl))))) ``` ## Operations We can define a range basic operations on the Yoneda identifications that all enjoy strict computational properties. ### Action of functions on Yoneda identifications ```agda module _ {l1 l2 : Level} {A : UU l1} {B : UU l2} (f : A → B) where eq-ap-yoneda-Id : {x y : A} → x =ʸ y → f x = f y eq-ap-yoneda-Id = ap f ∘ eq-yoneda-eq ap-yoneda-Id : {x y : A} → x =ʸ y → f x =ʸ f y ap-yoneda-Id = yoneda-eq-eq ∘ eq-ap-yoneda-Id compute-ap-refl-yoneda-Id : {x : A} → ap-yoneda-Id (reflʸ {x = x}) = reflʸ compute-ap-refl-yoneda-Id = refl module _ {l1 : Level} {A : UU l1} where compute-ap-id-yoneda-Id : {x y : A} (p : x =ʸ y) → ap-yoneda-Id id p = p compute-ap-id-yoneda-Id {x} p = eq-multivariable-htpy 2 ( λ _ q → ( ap (q ∙ᵣ_) (ap-id (p x refl))) ∙ ( inv (commutative-preconcatr-refl-Id-yoneda-Id p q))) ``` ### Action of binary functions on Yoneda identifications We obtain an action of binary functions on Yoneda identifications that computes on both arguments using one of the two sides in the Gray interchanger diagram ```text ap (r ↦ f x r) q f x y -------------> f x y' | | | | ap (r ↦ f r y) p | | ap (r ↦ f r y') p | | ∨ ∨ f x' y ------------> f x' y' ap (r ↦ f x' r) q ``` and the fact that the concatenation operation on Yoneda identifications is two-sided strictly unital. ```agda module _ {l1 l2 l3 : Level} {A : UU l1} {B : UU l2} {C : UU l3} (f : A → B → C) where ap-binary-yoneda-Id : {x x' : A} (p : x =ʸ x') {y y' : B} (q : y =ʸ y') → f x y =ʸ f x' y' ap-binary-yoneda-Id {x} {x'} p {y} {y'} q = ap-yoneda-Id (λ z → f z y) p ∙ʸ ap-yoneda-Id (f x') q left-unit-ap-binary-yoneda-Id : {x : A} {y y' : B} (q : y =ʸ y') → ap-binary-yoneda-Id reflʸ q = ap-yoneda-Id (f x) q left-unit-ap-binary-yoneda-Id q = refl right-unit-ap-binary-yoneda-Id : {x x' : A} (p : x =ʸ x') {y : B} → ap-binary-yoneda-Id p reflʸ = ap-yoneda-Id (λ z → f z y) p right-unit-ap-binary-yoneda-Id p = refl ``` ### Transport along Yoneda identifications ```agda module _ {l1 l2 : Level} {A : UU l1} (B : A → UU l2) where tr-yoneda-Id : {x y : A} → x =ʸ y → B x → B y tr-yoneda-Id = tr B ∘ eq-yoneda-eq compute-tr-refl-yoneda-Id : {x : A} → tr-yoneda-Id (reflʸ {x = x}) = id compute-tr-refl-yoneda-Id = refl ``` ### Standard function extensionality with respect to Yoneda identifications ```agda module _ {l1 l2 : Level} {A : UU l1} {B : A → UU l2} {f g : (x : A) → B x} where htpy-yoneda-eq : f =ʸ g → f ~ g htpy-yoneda-eq = htpy-eq ∘ eq-yoneda-eq yoneda-eq-htpy : f ~ g → f =ʸ g yoneda-eq-htpy = yoneda-eq-eq ∘ eq-htpy equiv-htpy-yoneda-eq : (f =ʸ g) ≃ (f ~ g) equiv-htpy-yoneda-eq = equiv-funext ∘e equiv-eq-yoneda-eq equiv-yoneda-eq-htpy : (f ~ g) ≃ (f =ʸ g) equiv-yoneda-eq-htpy = equiv-yoneda-eq-eq ∘e equiv-eq-htpy funext-yoneda-Id : is-equiv htpy-yoneda-eq funext-yoneda-Id = is-equiv-map-equiv equiv-htpy-yoneda-eq ``` ### Standard univalence with respect to Yoneda identifications ```agda module _ {l1 : Level} {A B : UU l1} where map-yoneda-eq : A =ʸ B → A → B map-yoneda-eq = map-eq ∘ eq-yoneda-eq equiv-yoneda-eq : A =ʸ B → A ≃ B equiv-yoneda-eq = equiv-eq ∘ eq-yoneda-eq yoneda-eq-equiv : A ≃ B → A =ʸ B yoneda-eq-equiv = yoneda-eq-eq ∘ eq-equiv equiv-equiv-yoneda-eq : (A =ʸ B) ≃ (A ≃ B) equiv-equiv-yoneda-eq = equiv-univalence ∘e equiv-eq-yoneda-eq is-equiv-equiv-yoneda-eq : is-equiv equiv-yoneda-eq is-equiv-equiv-yoneda-eq = is-equiv-map-equiv equiv-equiv-yoneda-eq equiv-yoneda-eq-equiv : (A ≃ B) ≃ (A =ʸ B) equiv-yoneda-eq-equiv = equiv-yoneda-eq-eq ∘e equiv-eq-equiv A B is-equiv-yoneda-eq-equiv : is-equiv yoneda-eq-equiv is-equiv-yoneda-eq-equiv = is-equiv-map-equiv equiv-yoneda-eq-equiv ``` ### Whiskering of Yoneda identifications ```agda module _ {l : Level} {A : UU l} {x y z : A} where left-whisker-concat-yoneda-Id : (p : x =ʸ y) {q r : y =ʸ z} → q =ʸ r → p ∙ʸ q =ʸ p ∙ʸ r left-whisker-concat-yoneda-Id p β = ap-yoneda-Id (p ∙ʸ_) β right-whisker-concat-yoneda-Id : {p q : x =ʸ y} → p =ʸ q → (r : y =ʸ z) → p ∙ʸ r =ʸ q ∙ʸ r right-whisker-concat-yoneda-Id α r = ap-yoneda-Id (_∙ʸ r) α ``` ### Horizontal concatenation of Yoneda identifications We define horizontal concatenation in such a way that it computes as left whiskering when the left-hand argument is `refl`, and computes as right whiskering when the right-hand argument is `refl`. ```agda module _ {l : Level} {A : UU l} {x y z : A} where horizontal-concat-yoneda-Id² : {p q : x =ʸ y} → p =ʸ q → {u v : y =ʸ z} → u =ʸ v → p ∙ʸ u =ʸ q ∙ʸ v horizontal-concat-yoneda-Id² = ap-binary-yoneda-Id (_∙ʸ_) compute-left-horizontal-concat-yoneda-Id² : {p : x =ʸ y} {u v : y =ʸ z} (β : u =ʸ v) → horizontal-concat-yoneda-Id² reflʸ β = left-whisker-concat-yoneda-Id p β compute-left-horizontal-concat-yoneda-Id² β = refl compute-right-horizontal-concat-yoneda-Id² : {p q : x =ʸ y} (α : p =ʸ q) {u : y =ʸ z} → horizontal-concat-yoneda-Id² α (reflʸ {x = u}) = right-whisker-concat-yoneda-Id α u compute-right-horizontal-concat-yoneda-Id² α = refl module _ {l : Level} {A : UU l} {x y : A} where left-unit-horizontal-concat-yoneda-Id² : {p q : x =ʸ y} (α : p =ʸ q) → horizontal-concat-yoneda-Id² reflʸ α = α left-unit-horizontal-concat-yoneda-Id² = compute-ap-id-yoneda-Id right-unit-horizontal-concat-yoneda-Id² : {p q : x =ʸ y} (α : p =ʸ q) → horizontal-concat-yoneda-Id² α (reflʸ {x = reflʸ}) = α right-unit-horizontal-concat-yoneda-Id² = compute-ap-id-yoneda-Id ``` Since concatenation on Yoneda identifications is strictly associative, the composites ```text horizontal-concat-yoneda-Id² (horizontal-concat-yoneda-Id² α β) γ ``` and ```text horizontal-concat-yoneda-Id² α (horizontal-concat-yoneda-Id² β γ) ``` inhabit the same type. Therefore, we can pose the question of whether the horizontal concatenation operation is associative, which it is, albeit weakly: ```agda module _ {l : Level} {A : UU l} {x y z w : A} where assoc-horizontal-concat-yoneda-Id² : {p p' : x =ʸ y} (α : p =ʸ p') {q q' : y =ʸ z} (β : q =ʸ q') {r r' : z =ʸ w} (γ : r =ʸ r') → horizontal-concat-yoneda-Id² (horizontal-concat-yoneda-Id² α β) γ = horizontal-concat-yoneda-Id² α (horizontal-concat-yoneda-Id² β γ) assoc-horizontal-concat-yoneda-Id² α {q} β {r} = ind-yoneda-Id ( λ _ γ → ( horizontal-concat-yoneda-Id² (horizontal-concat-yoneda-Id² α β) γ) = ( horizontal-concat-yoneda-Id² α (horizontal-concat-yoneda-Id² β γ))) ( ind-yoneda-Id ( λ _ β → ( horizontal-concat-yoneda-Id² ( horizontal-concat-yoneda-Id² α β) ( reflʸ {x = r})) = ( horizontal-concat-yoneda-Id² ( α) ( horizontal-concat-yoneda-Id² β (reflʸ {x = r})))) ( ind-yoneda-Id ( λ _ α → ( horizontal-concat-yoneda-Id² ( horizontal-concat-yoneda-Id² α (reflʸ {x = q})) ( reflʸ {x = r})) = ( horizontal-concat-yoneda-Id² ( α) ( horizontal-concat-yoneda-Id² (reflʸ {x = q}) (reflʸ {x = r})))) ( refl) ( α)) ( β)) ``` ### Vertical concatenation of Yoneda identifications ```agda module _ {l : Level} {A : UU l} {x y : A} where vertical-concat-yoneda-Id² : {p q r : x =ʸ y} → p =ʸ q → q =ʸ r → p =ʸ r vertical-concat-yoneda-Id² α β = α ∙ʸ β ``` ## See also - [The strictly involutive identity types](foundation.strictly-involutive-identity-types.md) for an identity relation that is strictly involutive, and one-sided unital. - [The computational identity types](foundation.computational-identity-types.md) for an identity relation that is strictly involutive, associative, and one-sided unital. ## References {{#bibliography}} {{#reference Esc19DefinitionsEquivalence}}