Other Agda modules in this section (34)
- Equivalences
- Factorizations
- Identifications.EndpointTransport
- Identifications.FunctorCoherence
- Identifications.IdentificationSquares
- Identifications.Inverses
- Identifications.OverBase
- Identifications.ProjectedFactorization
- Identifications.RestrictionDiagrams
- Identifications.RetractionCoherence
- Identifications.SectionEvaluation
- Identifications.TriangleCoherence
- Identifications.Triangles
- ProductConstructions
- Products.BinaryFunctors
- Products.Equivalences
- Products.FirstFactorSubstitution
- Products.PairedVertexFrames
- Products.Pairing
- Products.PairingOverBase
- Products.PairingRestriction
- Products.PairingSquares
- Products.ProductFunctor
- Products.ProductFunctorCoherence
- Products.ProductPairing
- Products.ProductPairingComposition
- Products.ProductPairingIdentity
- Products.ProductRestriction
- Products.TripleEvaluationOuterImage
- RelativeFunctors
- Retracts
- Squares
- Supporting
- WhiskeringEquivalence
Chapter 1, rebuild2, checked 14 October 2026 · source revision b982f5a.
# Retracts and the loop formulation The first rebuild recorded a retract by its two squares, endpoint laws `α : id C =₁ h ∘ g` and `β : j ∘ k =₁ id D`, and a compatibility `id₌ f =₂ loop`, where `loop : f =₁ f` runs around the pasted diagram. The new interface records the endpoint laws in the opposite domain orientation as the sides of a `SquareEquality`, whose compatibility compares the pasted cell with the cell of the identity square. The adapters below convert either compatibility into the other, for fixed squares, with the domain law inverted explicitly. They construct the stated data; they do not claim that the two conversions are mutually inverse on higher data. Write `λ = comp-unitˡ f`, `ρ = comp-unitʳ f` and `c` for the cell of the pasted square. The old loop is the right-nested composite λ ∙ ((β ▷ f) ∙ (a₁ ∙ (b₁ ∙ (c₁ ∙ (d₁ ∙ (e₁ ∙ ((f ◁ α) ∙ ρ ⁻¹))))))) where `c = a₁ ∙ (b₁ ∙ (c₁ ∙ (d₁ ∙ e₁)))` are the five factors of the pasted cell. After reassociating it is `λ ∙ ((β ▷ f) ∙ (c ∙ ((f ◁ α) ∙ ρ ⁻¹)))`. Both adapters then use only the vertical calculus, preservation of vertical composites and identities by whiskering, and `const-One` for the final identity identification. ```agda {-# OPTIONS --without-K #-} module SCT.VolumeI.Chapter01.Section03.RetractLoops where open import SCT.VolumeI.Chapter01.Section01.Vocabulary open import SCT.VolumeI.Chapter01.Section01.Terminal using (module Constructions) open Constructions open import SCT.VolumeI.Chapter01.Section02.Coherence using (id₌; comp-unitˡ; comp-unitʳ; comp-assoc; postWhisker-id₌; module Composition) open import SCT.VolumeI.Chapter01.Section02.Specialization using (comp₌-cong; comp₌-assoc; comp₌-unitˡ; comp₌-unitʳ; comp₌-inverseˡ; comp₌-inverseʳ; inv-comp-left; comp-inv-right; postWhisker-comp₌; post-constant; const-cong; const-One) open import SCT.VolumeI.Chapter01.Section03.Squares open import SCT.VolumeI.Chapter01.Section03.Retracts using (Retract) open Operations open Composition ``` ```agda module LoopCompatibility {Γ : Context} {C D C′ D′ : CAT Γ} {f : MAP C D} {f′ : MAP C′ D′} (inclusion : Square f f′) (retraction : Square f′ f) where private g = Square.source-map inclusion k = Square.target-map inclusion h = Square.source-map retraction j = Square.target-map retraction λf = comp-unitˡ f ρf = comp-unitʳ f a₁ : (j ∘ (k ∘ f)) =₁ ((j ∘ k) ∘ f) a₁ = (comp-assoc f k j) ⁻¹ b₁ : (j ∘ (f′ ∘ g)) =₁ (j ∘ (k ∘ f)) b₁ = j ◁ Square.cell inclusion c₁ : ((j ∘ f′) ∘ g) =₁ (j ∘ (f′ ∘ g)) c₁ = comp-assoc g f′ j d₁ : ((f ∘ h) ∘ g) =₁ ((j ∘ f′) ∘ g) d₁ = Square.cell retraction ▷ g e₁ : (f ∘ (h ∘ g)) =₁ ((f ∘ h) ∘ g) e₁ = (comp-assoc g h f) ⁻¹ pasted : (f ∘ (h ∘ g)) =₁ ((j ∘ k) ∘ f) pasted = Square.cell (comp-square retraction inclusion) identity-cell : (f ∘ id C) =₁ (id D ∘ f) identity-cell = Square.cell (id-square f) nested : (f =₁ (f ∘ (h ∘ g))) → f =₁ ((j ∘ k) ∘ f) nested T = a₁ ∙ (b₁ ∙ (c₁ ∙ (d₁ ∙ (e₁ ∙ T)))) reassociate : (T : f =₁ (f ∘ (h ∘ g))) → (pasted ∙ T) =₂ nested T reassociate T = comp₌-cong (id₌ a₁) (comp₌-cong (id₌ b₁) (comp₌-cong (id₌ c₁) (comp₌-assoc d₁ e₁ T) ∙ comp₌-assoc c₁ (d₁ ∙ e₁) T) ∙ comp₌-assoc b₁ (c₁ ∙ (d₁ ∙ e₁)) T) ∙ comp₌-assoc a₁ (b₁ ∙ (c₁ ∙ (d₁ ∙ e₁))) T T-from : id C =₁ (h ∘ g) → f =₁ (f ∘ (h ∘ g)) T-from α = (f ◁ α) ∙ ρf ⁻¹ cancel-whiskered : (p : (h ∘ g) =₁ id C) (q : id C =₁ (h ∘ g)) → (p ∙ q) =₂ const (id₌ (id C)) → ((f ◁ p) ∙ ((f ◁ q) ∙ ρf ⁻¹)) =₂ ρf ⁻¹ cancel-whiskered p q e = comp₌-unitˡ (ρf ⁻¹) ∙ (comp₌-cong (const-cong (postWhisker-id₌ f (id C)) ∙ (post-constant f (id₌ (id C)) ∙ ((postWhisker f ◁ e) ∙ (postWhisker-comp₌ f p q) ⁻¹))) (id₌ (ρf ⁻¹)) ∙ (comp₌-assoc (f ◁ p) (f ◁ q) (ρf ⁻¹)) ⁻¹) loop : id C =₁ (h ∘ g) → (j ∘ k) =₁ id D → f =₁ f loop α β = λf ∙ ((β ▷ f) ∙ nested (T-from α)) ``` From a `SquareEquality` with sides `s` and `t`, take `α = s ⁻¹` and `β = t`. Reassociate the loop, replace `(t ▷ f) ∙ c` by `(λ ⁻¹ ∙ ρ) ∙ (f ◁ s)` using the compatibility, cancel `f ◁ s` against `f ◁ s ⁻¹`, and then cancel the unitors. ```agda square-equality-to-loop : (E : SquareEquality (comp-square retraction inclusion) (id-square f)) → id₌ f =₂ loop ((SquareEquality.source-identification E) ⁻¹) (SquareEquality.target-identification E) square-equality-to-loop E = let s = SquareEquality.source-identification E t = SquareEquality.target-identification E T = T-from (s ⁻¹) to-unitor : ((t ▷ f) ∙ nested T) =₂ λf ⁻¹ to-unitor = comp-inv-right (λf ⁻¹) ρf ∙ (comp₌-cong (id₌ identity-cell) (cancel-whiskered s (s ⁻¹) (comp₌-inverseʳ s)) ∙ (comp₌-assoc identity-cell (f ◁ s) T ∙ (comp₌-cong (SquareEquality.compatibility E) (id₌ T) ∙ ((comp₌-assoc (t ▷ f) pasted T) ⁻¹ ∙ comp₌-cong (id₌ (t ▷ f)) ((reassociate T) ⁻¹))))) to-identity : loop (s ⁻¹) t =₂ id₌ f to-identity = const-One (id₌ f) ∙ (comp₌-inverseʳ λf ∙ comp₌-cong (id₌ λf) to-unitor) in to-identity ⁻¹ ``` Conversely, from `κ : id₌ f =₂ loop α β` take the sides `α ⁻¹` and `β`. Write `P = (β ▷ f) ∙ c`, `Q = (λ ⁻¹ ∙ ρ) ∙ (f ◁ α ⁻¹)` and `T = (f ◁ α) ∙ ρ ⁻¹`. The loop law gives `P ∙ T =₂ λ ⁻¹` after cancelling `λ`; cancelling `f ◁ α ⁻¹` against `f ◁ α` gives `Q ∙ T =₂ λ ⁻¹`. Cancelling `T` on the right identifies `P` with `Q`, the required compatibility. ```agda loop-to-square-equality : (α : id C =₁ (h ∘ g)) (β : (j ∘ k) =₁ id D) → id₌ f =₂ loop α β → SquareEquality (comp-square retraction inclusion) (id-square f) loop-to-square-equality α β κ = let P = (β ▷ f) ∙ pasted Q = identity-cell ∙ (f ◁ α ⁻¹) T = T-from α loop-reduced : (λf ∙ (P ∙ T)) =₂ id₌ f loop-reduced = κ ⁻¹ ∙ comp₌-cong (id₌ λf) (comp₌-cong (id₌ (β ▷ f)) (reassociate T) ∙ comp₌-assoc (β ▷ f) pasted T) P-T : (P ∙ T) =₂ λf ⁻¹ P-T = comp₌-unitʳ (λf ⁻¹) ∙ (comp₌-cong (id₌ (λf ⁻¹)) ((const-One (id₌ f)) ⁻¹) ∙ (comp₌-cong (id₌ (λf ⁻¹)) loop-reduced ∙ (inv-comp-left λf (P ∙ T)) ⁻¹)) Q-T : (Q ∙ T) =₂ λf ⁻¹ Q-T = comp-inv-right (λf ⁻¹) ρf ∙ (comp₌-cong (id₌ identity-cell) (cancel-whiskered (α ⁻¹) α (comp₌-inverseˡ α)) ∙ comp₌-assoc identity-cell (f ◁ α ⁻¹) T) in record { source-identification = α ⁻¹ ; target-identification = β ; compatibility = comp-inv-right Q T ∙ (comp₌-cong ((Q-T) ⁻¹ ∙ P-T) (id₌ (T ⁻¹)) ∙ (comp-inv-right P T) ⁻¹) } ``` For a retract, the first adapter gives the loop compatibility of its data; the second builds a retract from data with a loop compatibility. ```agda module _ {Γ : Context} {C D C′ D′ : CAT Γ} {f : MAP C D} {f′ : MAP C′ D′} where retract-loop-compatibility : (R : Retract f f′) → let open Retract R E = retraction-law in id₌ f =₂ LoopCompatibility.loop map retraction ((SquareEquality.source-identification E) ⁻¹) (SquareEquality.target-identification E) retract-loop-compatibility R = LoopCompatibility.square-equality-to-loop (Retract.map R) (Retract.retraction R) (Retract.retraction-law R) retract-from-loop : (inclusion : Square f f′) (retraction : Square f′ f) → (α : id C =₁ (Square.source-map retraction ∘ Square.source-map inclusion)) → (β : (Square.target-map retraction ∘ Square.target-map inclusion) =₁ id D) → id₌ f =₂ LoopCompatibility.loop inclusion retraction α β → Retract f f′ retract-from-loop inclusion retraction α β κ = record { map = inclusion ; retraction = retraction ; retraction-law = LoopCompatibility.loop-to-square-equality inclusion retraction α β κ } ```