Overview
This site documents the Agda implementation of the results of Derivatives of Containers in Univalent Foundations (arXiv:2512.17484). The overview on this page mirrors the paper. It lists each numbered result and links it to the corresponding implementation in the library. Many submodules of this library have additional documentation which explains proofs and constructions in greater detail than what would have appropriate for the paper.
The library does not depend on additional postulates, nor does it have any open holes.
It is accepted by Agda in --safe mode.
{-# OPTIONS --safe #-}
The Agda source code, as well as further documentation, can be found at
Basic notation and definitions
open import Derivative.Prelude
Removing Isolated Points in Univalent Foundations
Isolated points
open import Derivative.Isolated
Definition 2.1: Isolated points.
_ : (a : A) → Type _ _ = isIsolated
Lemma 2.2: Isolated points have propositional paths.
_ : (a : A) → isIsolated a → (b : A) → isProp (a ≡ b) _ = isIsolated→isPropPath
Corollary 2.3: Being isolated is a proposition.
_ : (a : A) → isProp (isIsolated a) _ = isPropIsIsolated
Proposition 2.4: Isolated points form a set.
_ : isSet (A °) _ = isSetIsolated
Lemma 2.5: Equivalences preserve and reflect isolated points, hence induce an equivalence.
_ : (e : A ≃ B) → ∀ a → isIsolated a ≃ isIsolated (equivFun e a) _ = isIsolated≃isIsolatedEquivFun
This induces an equivalence on sets of isolated points:
_ : (e : A ≃ B) → A ° ≃ B ° _ = IsolatedSubstEquiv
Proposition 2.6: Embeddings reflect isolated points.
_ : (f : A → B) → isEmbedding f → ∀ {a} → isIsolated (f a) → isIsolated a _ = EmbeddingReflectIsolated
Proposition 2.7: The constructors \( \mathsf{inl} : A → A ⊎ B \) and \( \mathsf{inr} : B → A ⊎ B \) preserve and reflect isolated points.
_ : ∀ {a : A} → isIsolated a ≃ isIsolated (inl {B = B} a) _ = isIsolated≃isIsolatedInl _ : ∀ {b : B} → isIsolated b ≃ isIsolated (inr {A = A} b) _ = isIsolated≃isIsolatedInr
Problem 2.8: The above induces an equivalence that distributes isolated points over binary sums:
_ : (A ⊎ B) ° ≃ (A °) ⊎ (B °) _ = IsolatedSumEquiv
The type \( A ⊎ 𝟙 \) is used so often that we abbreviate it as \( \mathsf{Maybe}(A) \):
_ : (A : Type) → Maybe A ≡ (A ⊎ 𝟙) _ = λ A → refl
The point \( \mathsf{nothing} : \mathsf{Maybe}(A) \) is always isolated:
_ : isIsolated {A = Maybe A} nothing _ = isIsolatedNothing _ : (Maybe A) ° _ = nothing°
Corollary 2.9: The isolated points of \( \mathsf{Maybe}(A) \) are the isolated points of \( A \) and \( \mathsf{nothing} \):
_ : (A : Type) → (Maybe A) ° ≃ Maybe (A °) _ = λ A → (Maybe A) ° ≃⟨ IsolatedSumEquiv ⟩ (A °) ⊎ (𝟙 °) ≃⟨ ⊎-right-≃ (isProp→IsolatedEquiv isProp-𝟙*) ⟩ Maybe (A °) ≃∎
Proposition 2.10: There is a map taking (dependent) pairs of isolated points to an isolated point in the corresponding type of pairs:
_ : (Σ[ (a , _) ∈ A ° ] (B a) °) → (Σ[ a ∈ A ] B a) ° _ = Σ-isolate A B
Lemma 2.11, Proposition 2.12: The fibers of this map are propositions, hence it is an embedding.
_ : (a : A) (b : B a) (h : isIsolated {A = Σ A B} (a , b)) → fiber (Σ-isolate A B) ((a , b) , h) ≃ (isIsolated a × isIsolated b) _ = Σ-isolate-fiber-equiv A B _ : isEmbedding (Σ-isolate A B) _ = isEmbedding-Σ-isolate A B
Lemma 2.13:
Σ-isolate is a surjection (hence an equivalence) iff pairing (_,_) reflects isolated points.
_ : isSurjection (Σ-isolate A B) ≃ (∀ a → (b : B a) → isIsolated {A = Σ A B} (a , b) → isIsolated a × isIsolated b) _ = isSurjection-Σ-isolate≃isIsolatedPair A B
Corollary 2.14:
Over discrete types, Σ-isolate is an equivalence.
_ : Discrete A → (∀ a → Discrete (B a)) → isEquiv (Σ-isolate A B) _ = Discrete→isEquiv-Σ-isolate
Proposition 2.15: Over a fixed isolated point \( a_0 : A \), pairing \( λ b.\, (a_0 , b) \) preserves and reflects isolated points.
_ : {a₀ : A} → isIsolated a₀ → (b₀ : B a₀) → isIsolated b₀ ≃ isIsolated {A = Σ A B} (a₀ , b₀) _ = isIsolatedFst→isIsolatedSnd≃isIsolatedPair
Proposition 2.16:
Discreteness of a type can be characterized by Σ-isolate at the family \( B(a) ≔ (a_0 = a) \).
_ : Discrete A ≃ ((a₀ : A) → isEquiv (Σ-isolate A (a₀ ≡_))) _ = Discrete≃isEquiv-Σ-isolate-singl
Removing points
open import Derivative.Remove
The type \( A ∖ a_0 \) is the subtype of \( A \) with \( a_0 \) removed.
_ : (A : Type) → (a₀ : A) → (A ∖ a₀) ≡ (Σ[ a ∈ A ] a₀ ≢ a) _ = λ A a → refl
Problem 2.17: Show that first adding a point to \( A \), then removing it gives a type equivalent to \( A \).
_ : Maybe A ∖ nothing ≃ A _ = removeNothingEquiv
Problem 2.18: More generally, removing a point from a binary sum is equivalent to first removing the point from either side, then taking the sum.
_ : ∀ {a : A} → ((A ∖ a) ⊎ B) ≃ ((A ⊎ B) ∖ (inl a)) _ = remove-left-equiv _ : ∀ {b : B} → (A ⊎ (B ∖ b)) ≃ ((A ⊎ B) ∖ (inr b)) _ = remove-right-equiv
The other way around, there is a map that takes \( \mathsf{Maybe}(A ∖ a_0) \) and replaces \( \mathsf{nothing} \) with \( a_0 \):
_ : (a₀ : A) → Maybe (A ∖ a₀) → A _ = replace
Proposition 2.19: The map \( \mathsf{replace}(a_0) \) is an equivalence if and only if \( a_0 \) is isolated.
_ : (a₀ : A) → isIsolated a₀ ≃ isEquiv (replace a₀) _ = isIsolated≃isEquiv-replace
Problem 2.20: If \( a_0 \) is h-isolated (i.e. \( \mathsf{isProp}(a_0 = a_0) \)), then there is a map that looks like it characterizes removal of points from \( Σ \)-types.
_ : ∀ (a₀ : A) (b₀ : B a₀) → (isProp (a₀ ≡ a₀)) → (Σ[ (a , _) ∈ A ∖ a₀ ] B a) ⊎ (B a₀ ∖ b₀) → (Σ A B ∖ (a₀ , b₀)) _ = Σ-remove
Proposition 2.21:
If a₀ is isolated, then it is h-isolated, and Σ-remove a₀ b₀ is an equivalence.
_ : ∀ {a₀ : A} {b₀ : B a₀} → (h : isIsolated a₀) → isEquiv (Σ-remove {B = B} a₀ b₀ _) _ = isIsolatedFst→isEquiv-Σ-remove
Grafting
Problem 2.22: For all \( a : A^\circ \), grafting extends the domain of a function \( f : A \setminus a_0 \to B \) to all of \( A \), given some \( b_0 : B \).
_ : (a : A °) → (((A ∖° a) → B) × B) → (A → B) _ = graft
Proposition 2.23: This defines an induction-like principle for maps out of types \( A \) with an isolated point \( a_0 : A^\circ \). In particular, it has computation rules,
_ : (a° : A °) (f : (A ∖° a°) → B) {b₀ : B} → graft a° (f , b₀) (a° .fst) ≡ b₀ _ = graft-β-yes _ : (a° : A °) (f : (A ∖° a°) → B) {b₀ : B} (a : A ∖° a°) → graft a° (f , b₀) (a .fst) ≡ f a _ = graft-β-no
Grafting for dependent functions is defined in:
import Derivative.Isolated.DependentGrafting
Note
We do not use this more general definition as it contains an extra transport,
which, for non-dependent functions, is a transport over refl.
Since transport refl does not definitionally reduce to the identity function,
we would have to manually get rid of it everywhere.
Derivatives of Containers
open import Derivative.Container
Definition 3.1: A container \( (S ◁ P) \) consists of shapes \( S : \mathsf{Type} \) and a family of positions \( P : S → \mathsf{Type} \) over those shapes.
_ : (ℓ : Level) → Type (ℓ-suc ℓ) _ = λ ℓ → Container ℓ ℓ _ : (S : Type) → (P : S → Type) → Container _ _ _ = λ S P → (S ◁ P)
We sometimes use the notation \( (s : S \lhd P(s)) \) when defining containers.
_ : (S : Type) (P : S → Type) → Container _ _ _ = λ S P → (s ∈ S ◁ P s)
We use ∈ instead of :, as the latter is part of Agda's syntax.
This mirrors the notation Σ[ a ∈ A ] B a for Σ A B.
Universe polymorphism
Containers are defined for shapes and positions in any universe.
For most constructions, we consider containers at a fixed level ℓ,
that is the type Container ℓ ℓ.
Some examples consider containers with large shapes (i.e. Container (ℓ-suc ℓ) ℓ), but this is mostly for convenience.
The shapes of those containers could be resized to a type at level ℓ.
Definition 3.2, 3.3: A linear morphism of containers consists of a map of shapes, and a family of equivalences of positions.
_ : F ⊸ G ≃ (Σ[ fₛₕ ∈ (F .Shape → G .Shape) ] ∀ s → G .Pos (fₛₕ s) ≃ F .Pos s) _ = ⊸-Σ-equiv
Containers and linear morphisms assemble into a wild category. Set-truncated containers form a 1-category.
open import Derivative.Category ℓ-zero _ : WildCat _ _ _ = ℂont⊸∞ _ : Category _ _ _ = ℂont⊸
Definition 3.4: An \( (n, k) \)-truncated container has \( n \)-truncated shapes, and \( k \)-truncated positions.
_ : (n k : HLevel) → (F : Container _ _) → Type _ _ = isTruncatedContainer {ℓS = ℓ-zero} {ℓP = ℓ-zero}
Definition 3.5: The extent of a container.
⟦_⟧ : (F : Container _ _) → Type → Type ⟦ S ◁ P ⟧ X = Σ[ s ∈ S ] (P s → X)
Definition 3.6 Basic operations on containers.
-
Product:
_ = _⊗_
-
Sum:
_ = _⊕_
-
Substitution:
_ = _[_]
-
Constants:
_ : Type → Container ℓ-zero _ _ = Const
-
Tuples:
_ : Type → Container ℓ-zero _ _ = 𝕪
-
Identity:
_ : Container ℓ-zero ℓ-zero _ = Id
Definition 3.7: A morphism is an equivalence of containers if its shape map is an equivalence of types. We bundle this into a record.
_ : (F G : Container _ _) → Type ℓ-zero _ = Equiv
Equivalences of containers form an identity system.
open import Derivative.Parametrized.Univalence using (ContainerEquivJ ; containerEquivPreCompEquiv)
Note
This is defined for parametrized containers (introduced below) to avoid having to define it twice.
Problem 3.8: Equivalence-induction for containers.
_ = ContainerEquivJ
Lemma 3.9: Precomposition with a container equivalence is an equivalence of types.
_ = containerEquivPreCompEquiv
Lemma 3.10: Extensionality for morphisms says that we can compare them by their shape- and position maps.
_ : (f g : F ⊸ G) → (Σ[ p ∈ f .shape ≡ g .shape ] (PathP (λ i → ∀ s → G .Pos (p i s) ≃ F .Pos s) (f .pos) (g .pos))) ≃ (f ≡ g) _ = ⊸≡Equiv
Derivatives, Universally
open import Derivative.Derivative
Definition 3.11: The derivative of an untruncated container. Its shapes contain an isolated position.
_ : (S : Type) (P : S → Type) → ∂ (S ◁ P) ≡ ((s , p) ∈ (Σ[ s ∈ S ] P s °) ◁ (P s ∖° p)) _ = λ S P → refl
Example 3.12: Description of the derivative of the container of lists, \( ((n : ℕ) \lhd [n]) \).
open import Derivative.Examples.List using (∂List)
Note
We define lists as a \( 1 \)-parametrized container (introduced below) to avoid having to define them twice.
Problem 3.13:
Extend the derivative to a functor on the wild category of containers and linear morphisms, ℂont∞.
_ : WildFunctor ℂont⊸∞ ℂont⊸∞ _ = ∂∞
Proposition 3.14: Taking derivatives preserves the truncation level of containers (except for very low levels).
_ : ∀ (n k : HLevel) → isTruncatedContainer (2 + n) (1 + k) F → isTruncatedContainer (2 + n) (1 + k) (∂ F) _ = isTruncatedDerivative
Corollary 3.15: \( \partial \) restricts to an endofunctor of the 1-category of set-truncated containers.
_ : Functor ℂont⊸ ℂont⊸ _ = ∂ₛ
Problem 3.16:
Define a wild adjunction \( \_ \otimes \mathsf{Id} \dashv \partial \).
This consists of two families of morphisms unit and counit,
open import Derivative.Adjunction _ : F ⊸ (∂ (F ⊗Id)) _ = unit _ _ : (∂ G ⊗Id) ⊸ G _ = counit _
natural in \( F \) and \( G \), respectively,
_ = is-natural-unit _ = is-natural-counit
and zig-zag fillers
_ : [ unit F ]⊗Id ⋆ counit (F ⊗Id) ≡ id (F ⊗Id) _ = zig≡ _ _ : unit (∂ G) ⋆ ∂[ counit G ] ≡ id (∂ G) _ = zag≡ _
These data assemble into a wild adjunction:
open import Derivative.Basics.WildCategories using (_⊣∞_) _ : -⊗Id ⊣∞ ∂∞ _ = ⊗Id-∂-wild-adjunction
Theorem 3.17: The above restricts to an adjunction in the 1-category of set-truncated containers.
_ : -⊗Idₛ ⊣ ∂ₛ _ = ⊗Id-∂-adjunction
Corollary 3.18: There is an adjunction \( \_ ⊗ \mathsf{y}[n] ⊣ ∂^n \) in the 1-category of set-truncated containers and linear morphisms.
We have decided to not formalize this as stated.
This follows directly from composing ⊗Id-∂-adjunction with itself \( n \) times.
The added overhead of a formal statement is, in our opinion, not worth the marginal gain.
We do, however, prove something much more general which is discussed in the conclusion of the paper, and below: It is possible to construct a wild right-adjoint \( ∂^H \) to \( \_ ⊗ \mathsf{y}(H) \), for an arbitrary type \( H \). For \( H = [n] \), one can (but we do not) prove that \( ∂^n \) and \( ∂^{[n]} \) are propositionally equal, hence \( \_ ⊗ \mathsf{y}[n] ⊣ ∂^n \).
Basic Laws of Derivatives
open import Derivative.Properties
Proposition 3.19: Derivative of containers whose positions are propositions.
_ : (S : Type) {P : S → Type} → (∀ s → isProp (P s)) → Equiv (∂ (S ◁ P)) (Σ S P ◁ const 𝟘) _ = ∂-prop-trunc
Proposition 3.20: The sum- and product rules.
_ : Equiv (∂ (F ⊕ G)) (∂ F ⊕ ∂ G) _ = sum-rule _ _ _ : Equiv (∂ (F ⊗ G)) ((∂ F ⊗ G) ⊕ (F ⊗ ∂ G)) _ = prod-rule _ _
Proposition 3.21:
The Bag container is a fixed point of \( \partial \).
open import Derivative.Examples.Bag _ : Equiv (∂ Bag) Bag _ = ∂-Bag-equiv
Proposition 3.22: Any predicate closed under addition and removal of single points induces a fixed point of \( \partial \).
module _ (P : Type → Type) (is-prop-P : ∀ A → isProp (P A)) (is-P-+1 : ∀ {A : Type} → P A → P (A ⊎ 𝟙)) (is-P-∖ : ∀ {A : Type} → P A → (a : A °) → P (A ∖° a)) where open Derivative.Examples.Bag.Universe P is-prop-P is-P-+1 is-P-∖ renaming (uBag to Bagᴾ) _ : Equiv (∂ Bagᴾ) Bagᴾ _ = ∂-uBag
The Chain Rule
open import Derivative.ChainRule
Problem 4.1: The lax chain rule.
_ : (((∂ F) [ G ]) ⊗ ∂ G) ⊸ (∂ (F [ G ])) _ = chain-rule _ _
Definition 4.2: A morphism of containers is an embedding if its shape map is an embedding.
_ : {F G : Container ℓ ℓ} → F ⊸ G → Type _ _ = isContainerEmbedding
Proposition 4.3: The chain rule is an embedding of containers.
_ : isContainerEmbedding (chain-rule F G) _ = isContainerEmbeddingChainRule _ _
Proposition 4.4:
The chain rule is an equivalence iff Σ-isolate is.
module _ (F G : Container ℓ ℓ) where open Container F renaming (Shape to S ; Pos to P) open Container G renaming (Shape to T ; Pos to Q) _ : isContainerEquiv (chain-rule F G) ≃ (∀ s → (f : P s → T) → isEquiv (Σ-isolate (P s) (Q ∘ f))) _ = isEquivChainRule≃isEquiv-Σ-isolated F G
Theorem 4.5:
For discrete containers, the chain rule is an equivalence.
Therefore it is an isomorphism in the 1-category of set-truncated containers, ℂont.
_ : (F G : DiscreteContainer ℓ ℓ) → isStrong (F .fst) (G .fst) _ = DiscreteContainer→isStrong
Theorem 4.6: The chain rule is invertible for arbitrary containers if and only if arbitrary types are discrete. This is impossible in the presence of types of higher truncation level.
_ : ((F G : Container ℓ ℓ) → isStrong F G) ≃ ((A : Type ℓ) → Discrete A) _ = isGloballyStrong≃AllTypesDiscrete _ : ¬ isGloballyStrong ℓ-zero _ = ¬isGloballyStrong
Corollary 4.7: The chain rule is an equivalence for all set-truncated containers if and only if all sets are discrete.
_ : ((F G : SetContainer ℓ ℓ) → isStrong (F .fst) (G .fst)) ≃ ((A : hSet ℓ) → Discrete ⟨ A ⟩) _ = isStrongSets≃AllSetsDiscrete
Derivatives of Fixed Points
Parametrized Containers
import Derivative.Parametrized.Container as Containerᴾ
Definition 5.1: Parametrized containers have positions indexed by some \( \mathsf{Ix} : \mathsf{Type} \).
Containerᴾ : (Ix : Type) → Type _ Containerᴾ = Containerᴾ.Container ℓ-zero _ : Containerᴾ Ix ≃ (Σ[ S ∈ Type ] (Ix → S → Type)) _ = Containerᴾ.Container-Σ-equiv
Overloading notation
Unfortunately, Agda does not allow overloading the names of definitions for parametrized and unary containers.
The parametrized versions are suffixed with ᴾ, if necessary.
open Containerᴾ using (₀ ; ₁ ; 𝟚 ; _⧟_ ; ↑ ; π₁) renaming ( _⊗_ to _⊗ᴾ_ ; _⊕_ to _⊕ᴾ_ ; _⋆_ to _⋆ᴾ_ ; _⊸_ to _⊸ᴾ_ ; isContainerEquiv to isContainerEquivᴾ ; isContainerEmbedding to isContainerEmbeddingᴾ ; [-]-map to [_]-map ) open Containerᴾ.Container
Definition 5.2: Substitution for parametrized containers.
_[_]ᴾ : (F : Containerᴾ (Maybe Ix)) (G : Containerᴾ Ix) → Containerᴾ Ix _[_]ᴾ = Containerᴾ._[_]
Definition 5.3: The derivative of a parametrized container is defined for each isolated index \( i : \mathsf{Ix}^\circ \).
import Derivative.Parametrized.Derivative as ParametrizedDerivative ∂ᴾ : (i : Ix °) → (F : Containerᴾ Ix) → Containerᴾ Ix ∂ᴾ = ParametrizedDerivative.∂
Shorthands for the derivative of unary containers (∂ᴾ tt°),
and the two derivatives of binary containers.
open ParametrizedDerivative using (∂• ; ∂₀ ; ∂₁)
Problem 5.4: The chain rule for binary containers.
open import Derivative.Parametrized.ChainRule as ParametrizedChainRule renaming (isContainerEmbeddingChainRule to isContainerEmbeddingChainRuleᴾ) _ : ∀ (F : Containerᴾ 𝟚) → (G : Containerᴾ _) → ((∂₀ F [ G ]ᴾ) ⊕ᴾ ((∂₁ F [ G ]ᴾ) ⊗ᴾ ∂• G)) ⊸ᴾ ∂• (F [ G ]ᴾ) _ = binary-chain-rule
Proposition 5.5: The binary chain rule is an embedding.
_ : (F : Containerᴾ 𝟚) (G : Containerᴾ 𝟙) → isContainerEmbeddingᴾ (binary-chain-rule F G) _ = isContainerEmbeddingChainRuleᴾ
Proposition 5.6:
Like for unary containers, the binary chain rule is an equivalence iff Σ-isolate is.
_ : (F : Containerᴾ 𝟚) (G : Containerᴾ 𝟙) → isContainerEquivᴾ (binary-chain-rule F G) ≃ (∀ s f → isEquiv (Σ-isolate (F .Pos ₁ s) (G .Pos _ ∘ f))) _ = isEquivBinaryChainRule≃isEquiv-Σ-isolate
Proposition 5.7: For discrete containers, the binary chain rule is an equivalence.
_ : (F : Containerᴾ 𝟚) (G : Containerᴾ 𝟙) → (∀ s → Discrete (Pos F ₁ s)) → (∀ t → Discrete (Pos G • t)) → isContainerEquivᴾ (binary-chain-rule F G) _ = DiscreteContainer→isEquivBinaryChainRule
Fixed Points of Containers
open import Derivative.Parametrized.Mu
Problem 5.8: Substitution \( F[\_] \) is a (wild) endofunctor.
_ : (F : Containerᴾ (Maybe Ix)) {G G′ : Containerᴾ Ix} → G ⊸ᴾ G′ → (F [ G ]ᴾ) ⊸ᴾ (F [ G′ ]ᴾ) _ = [_]-map _ = Containerᴾ.[-]-map-id _ = Containerᴾ.[-]-map-⋆
Problem 5.9: \( F[\_] \)-algebras form a wild category.
private module _ (F : Containerᴾ (Maybe Ix)) where Alg : Type _ Alg = Σ[ X ∈ Containerᴾ Ix ] (F [ X ]ᴾ ⊸ᴾ X) AlgHom : Alg → Alg → Type _ AlgHom (X , f) (Y , g) = Σ[ h ∈ X ⊸ᴾ Y ] f ⋆ᴾ h ≡ [ F ]-map h ⋆ᴾ g
Note
We chose to omit the proof that \( F[\_] \)-algebras form a wild category from the formalization. Defining the necessary coherence between commutative squares is challenging for technical reasons; a formal proof only obscures the intuition that \( F[\_] \) acts coherently also on homotopies of container morphisms. At the same time, no further construction depends on these coherences.
Definition 5.10: A (least) container fixpoint is an initial \( F[\_] \)-algebra.
isLeastFixpoint : (μ : Alg) → Type _ isLeastFixpoint μ = ∀ h → isContr (AlgHom μ h)
Definition 5.11: For any \( I+1 \)-parametrized container \( F \) there is an \( I \)-parametrized fixed point container \( μ F \).
_ : (F : Containerᴾ (Maybe Ix)) → Containerᴾ Ix _ = μ
Example 5.12: Lists can be described as a fixpoint.
open import Derivative.Examples.List using (μL⧟List)
Problem 5.13: Define an equivalence of containers \( F [ {μ F} ] ⧟ μ F \).
_ : (F : Containerᴾ (Maybe Ix)) → (F [ μ F ]ᴾ) ⧟ (μ F) _ = μ-in-equiv
Problem 5.14: Derive a recursion principle for fixed-point containers.
module _ (F : Containerᴾ (Maybe Ix)) (G : Containerᴾ Ix) (α : F [ G ]ᴾ ⊸ᴾ G) where _ : μ F ⊸ᴾ G _ = μ-rec F G α _ : μ-in F ⋆ᴾ μ-rec F G α ≡ [ F ]-map (μ-rec F G α) ⋆ᴾ α _ = μ-rec-β F G α
Proposition 5.15: The recursion principle for containers is unique as a coalgebra-to-algebra morphism.
_ : ∃![ α* ∈ μ F ⊸ᴾ G ] α* ≡ μ-out F ⋆ᴾ [ F ]-map α* ⋆ᴾ α _ = μ-rec-coalgebra-to-algebra.unique F G α
Theorem 5.16: Every container admits a least fixed point in the wild category of containers. For any \( F[\_]\)-algebra \( α : F[G] ⊸ G \), there is a unique algebra map \( α^* : μ F ⊸ G \):
_ : ∃![ α* ∈ μ F ⊸ᴾ G ] μ-in F ⋆ᴾ α* ≡ [ F ]-map α* ⋆ᴾ α _ = μ-rec-unique F G α _ : (F : Containerᴾ (Maybe Ix)) → isLeastFixpoint F (μ F , μ-in F) _ = uncurry ∘ μ-rec-unique
The Fixed Point Rule
open import Derivative.Parametrized.MuRule
Problem 5.17: The lax \( μ \)-rule.
_ : (F : Containerᴾ 𝟚) → μ (↑ (∂₀ F [ μ F ]ᴾ) ⊕ᴾ (↑ (∂₁ F [ μ F ]ᴾ) ⊗ᴾ π₁)) ⊸ᴾ ∂• (μ F) _ = μ-rule
Lemma 5.18: The μ-recursor reflects equivalences:
_ : (F : Containerᴾ (Maybe Ix)) (G : Containerᴾ Ix) → (φ : (F [ G ]ᴾ) ⊸ᴾ G) → isContainerEquivᴾ (μ-rec F G φ) → isContainerEquivᴾ φ _ = isEquivFrom-μ-rec
Proposition 5.19: If the \( μ \)-rule is an equivalence, then so is the corresponding chain rule.
_ : (F : Containerᴾ 𝟚) → isContainerEquivᴾ (μ-rule F) → isContainerEquivᴾ (binary-chain-rule F (μ F)) _ = StrongFixRule.isEquiv-chain-rule
Lemma 5.20: The \( μ \)-recursor preserves embeddings.
_ : (F : Containerᴾ (Maybe Ix)) (G : Containerᴾ Ix) → (φ : (F [ G ]ᴾ) ⊸ᴾ G) → isContainerEmbeddingᴾ φ → isContainerEmbeddingᴾ (μ-rec F G φ) _ = isEmbedding-μ-rec
Problem 5.21: If the algebra \( \mathsf{sup}^* \) is an embedding, the fibers of the \( \mathsf{W} \)-recursor over its own image can be characterized recursively: a fiber over a node is the product of the fibers over its children.
_ : {S : Type} {P : S → Type} {A : Type} → (sup* : (Σ[ s ∈ S ] (P s → A)) → A) → isEmbedding sup* → (s : S) (f : P s → W S P) → fiber (W-rec sup*) (W-rec sup* (sup s f)) ≃ ((p : P s) → fiber (W-rec sup*) (W-rec sup* (f p))) _ = isEmbedding→W-rec-fiber-equiv
Lemma 5.22: The recursor for \( \mathsf{W} \)-types preserves embeddings.
_ : {S : Type} {P : S → Type} {A : Type} → (sup* : (Σ[ s ∈ S ] (P s → A)) → A) → isEmbedding sup* → isEmbedding (W-rec sup*) _ = isEmbedding-W-rec
Lemma 5.23: The lax \( μ \)-rule is an embedding of containers.
_ : (F : Containerᴾ 𝟚) → isContainerEmbeddingᴾ (μ-rule F) _ = isContainerEmbedding-μ-rule
Proposition 5.24: If the chain rule is an equivalence, so is the μ-rule.
_ : (F : Containerᴾ 𝟚) → isContainerEquivᴾ (binary-chain-rule F (μ F)) → isContainerEquivᴾ (μ-rule F) _ = StrongChainRule.isEquiv-μ-rule
Theorem 5.25: The \( μ \)-rule is an equivalence if and only if the corresponding chain rule is.
_ : (F : Containerᴾ 𝟚) → isContainerEquivᴾ (μ-rule F) ≃ isContainerEquivᴾ (binary-chain-rule F (μ F)) _ = isContainerEquiv-μ-rule≃isContainerEquiv-binary-chain-rule
Given a tree \( x : \mathsf{W}(S, P) \), the type of \( Q \)-labelled finite paths into \( x \) is \( \bar{\mathsf{W}}_{S,P,Q}(x) \), written here as
_ : (S : Type) (P Q : S → Type) → W S P → Type _ = Wᴰ
Lemma 5.26: If both branching \( P : S → \mathsf{Type} \) and labeling of nodes \( Q : S → \mathsf{Type} \) are discrete, then paths into any \( x : \mathsf{W}(S, P) \) are discrete:
_ : (S : Type) (P Q : S → Type) → (∀ s → Discrete (P s)) → (∀ s → Discrete (Q s)) → (x : W S P) → Discrete (Wᴰ S P Q x) _ = discrete-Wᴰ
Lemma 5.27: If \( F \) is a discrete container, then so is \( μ F \):
_ : (F : Containerᴾ 𝟚) → (∀ ix s → Discrete (F .Pos ix s)) → (∀ w → Discrete (μ F .Pos • w)) _ = μ-discrete
Proposition 5.28: For discrete containers the \( μ \)-rule is an equivalence.
_ : (F : Containerᴾ 𝟚) → (∀ ix s → Discrete (F .Pos ix s)) → isContainerEquivᴾ (μ-rule F) _ = Discrete.isEquiv-μ-rule
Future work
In the conclusion of the paper, we conjecture that \( \_ ⊗ \mathsf{y}(H) \) has a (wild) right-adjoint for arbitrary types \( H \). This is indeed the case. We decided not to include this fact in the main body of the paper in order not to make it longer than it needs to be.
We define a notion of higher derivative relative to some type \( H \) of holes.
import Derivative.Relative as Rel
Instead of considering isolated positions, we notice that isolated points are exactly decidable embeddings of the point \( 1 \):
open import Derivative.Basics.DecidableEmbedding as DecEmb using (_↪°_ ; isDecEmbedding ; Isolated≃DecEmbUnit ; _-_) _ : A ° ≃ (𝟙 ↪° A) _ = Isolated≃DecEmbUnit
This yields a notion of a derivative operation \( ∂^H \) that captures the intuition of "context with a \( H \)-shaped hole": Shapes of \( ∂^H(S \lhd P) \) are a shape \( s : S \) together with a decidable embedding \( H ↪° P_s \):
_ : (H : Type) (S : Type) (P : S → Type) → Shape (Rel.∂ H (S ◁ P)) ≡ (Σ[ s ∈ S ] (H ↪° P s)) _ = λ H S P → refl
For \( H = 1 \), this corresponds exactly to the ordinary ("first") derivative:
_ : (F : Container ℓ-zero ℓ-zero) → Equiv (∂ F) (Rel.∂ 𝟙 F) _ = Rel.firstDerivativeEquiv
The proof that \( ∂^H \) is right-adjoint to \( \_ ⊗ 𝕪(H) \) is largely like that of Problem 3.16 above. An isolated point splits a type into two disconnected components: if \( a : A \) is isolated, then \( A \simeq (A ∖ a) + 1 \). Similarly, if \( H \) embeds decidably into \( A \), then it splits \( A \) into two components — the image of \( h \) and its complement.
_ : {H : Type} → (h : H → A) → DecEmb.isDecEmbedding h → (A - h) ⊎ H ≃ A _ = curry DecEmb.remove-sum-left-equiv _ : A ≃ (A ⊎ B) - inr _ = DecEmb.sum-inr-remove-equiv
This lets us construct a wild adjunction following essentially the same argument as before:
module _ (H : Type) (F G : Container ℓ-zero ℓ-zero) where open Rel using () renaming (∂[_] to ∂-map) _ : F ⊸ Rel.∂ H (F ⊗ 𝕪 H) _ = Rel.unit H F _ : (Rel.∂ H G ⊗ 𝕪 H) ⊸ G _ = Rel.counit H G _ = Rel.is-natural-unit H _ = Rel.is-natural-counit H _ : ([ Rel.unit H F ]⊗ (𝕪 H)) ⋆ Rel.counit H (F ⊗ 𝕪 H) ≡ id (F ⊗ 𝕪 H) _ = Rel.zig≡ H F _ : Rel.unit H (Rel.∂ H G) ⋆ ∂-map H (Rel.counit H G) ≡ id (Rel.∂ H G) _ = Rel.zag≡ H G