Defining substitution for a language with binders like the simply typed $λ$-calculus requires repetition, defining substitution and renaming separately. To verify the categorical properties of this calculus, we must repeat the same argument many times. We present a lightweight method that avoids repetition and that gives rise to a simply typed category with families (CwF) isomorphic to the initial simply typed CwF. Our paper is a literate Agda script.
Authors: Thorsten Altenkirch (University of Nottingham), Nathaniel Burke (Imperial College London), Philip Wadler (University of Edinburgh and Input Output)
Classification: cs.LO (Logic in Computer Science)
Conference: LFMTP 2025 (International Workshop on Logical Frameworks and Meta-Languages: Theory and Practice)
When defining substitution operations for languages with binders (such as simply-typed λ-calculus), it is customary to separately define substitution and renaming operations, resulting in substantial code duplication. To verify the categorical properties of the calculus, identical arguments must be repeated multiple times. This paper proposes a lightweight approach to avoid such duplication and constructs a simply-typed Contextual Families (CwF) isomorphic to the initial simply-typed CwF family. The paper is presented as an Agda literate programming script.
Unified framework: Proposes a unified substitution operation based on Sort parameterization, merging variable and term handling into a single definition
Termination guarantee: Cleverly leverages Agda's structural recursion and lexicographic termination checking to ensure well-foundedness of definitions
Categorical verification: Proves that recursive substitution definitions satisfy all laws of simply-typed CwF
Initiality result: Establishes an isomorphism between recursive substitution syntax and the initial CwF
Normalization theorem: Substitution normal form of λ-terms corresponds to λ-terms without explicit substitutions
data _ ⊢ [_]_ : Con → Sort → Ty → Set where
zero : Γ ▷ A ⊢ [ V ] A
suc : Γ ⊢ [ V ] A → (B : Ty) → Γ ▷ B ⊢ [ V ] A
`_ : Γ ⊢ [ V ] A → Γ ⊢ [ T ] A
_ ·_ : Γ ⊢ [ T ] A ⇒ B → Γ ⊢ [ T ] A → Γ ⊢ [ T ] B
λ_ : Γ ▷ A ⊢ [ T ] B → Γ ⊢ [ T ] A ⇒ B
Where Γ ⊢ [ V ] A corresponds to variables and Γ ⊢ [ T ] A corresponds to terms.
_[_] : Γ ⊢ [ q ] A → ∆ ⊩ [ r ] Γ → ∆ ⊢ [ q ⊔ r ] A
Key insight: The result sort is the least upper bound of input sorts, ensuring that the result is a variable only when both inputs are variables/renamings.