------------------------------------------------------------------------ -- Contexts, variables, substitutions, etc. ------------------------------------------------------------------------ {-# OPTIONS --universe-polymorphism #-} -- Based on Conor McBride's "Outrageous but Meaningful Coincidences: -- Dependent type-safe syntax and evaluation". -- The contexts and variables are parametrised by a universe. open import Universe module Data.Context {u e} (Uni : Universe u e) where open Universe.Universe Uni open import Data.Product as Prod open import Data.Unit open import Function open import Level ------------------------------------------------------------------------ -- Contexts and "types" mutual -- Contexts. infixl 5 _▻_ data Ctxt : Set (u ⊔ e) where ε : Ctxt _▻_ : (Γ : Ctxt) (σ : Type Γ) → Ctxt -- Semantic types: maps from environments to universe codes. Type : Ctxt → Set (u ⊔ e) Type Γ = Env Γ → U -- Interpretation of contexts: environments. Env : Ctxt → Set e Env ε = Lift ⊤ Env (Γ ▻ σ) = Σ (Env Γ) λ γ → El (σ γ) -- Type signature for variables, terms, etc. Term-like : (ℓ : Level) → Set _ Term-like ℓ = (Γ : Ctxt) → Type Γ → Set ℓ -- Semantic values: maps from environments to universe values. Value : Term-like _ Value Γ σ = (γ : Env Γ) → El (σ γ) ------------------------------------------------------------------------ -- "Substitutions" -- Semantic substitutions or context morphisms: maps from environments -- to environments. infixr 4 _⇨_ _⇨_ : Ctxt → Ctxt → Set _ Γ ⇨ Δ = Env Δ → Env Γ -- Maps between types. infixr 4 _⇨₁_ _⇨₁_ : ∀ {Γ} → Type Γ → Type Γ → Set _ σ ⇨₁ τ = ∀ {γ} → El (τ γ) → El (σ γ) -- Application of substitutions to types. -- -- Note that this operation is composition of functions. I have chosen -- not to give a separate name to the identity substitution, which is -- simply the identity function, nor to reverse composition of -- substitutions, which is composition of functions. infixl 8 _/_ _/_ : ∀ {Γ Δ} → Type Γ → Γ ⇨ Δ → Type Δ σ / ρ = σ ∘ ρ -- Application of substitutions to values. infixl 8 _/v_ _/v_ : ∀ {Γ Δ σ} → Value Γ σ → (ρ : Γ ⇨ Δ) → Value Δ (σ / ρ) v /v ρ = v ∘ ρ -- Weakening. wk : ∀ {Γ σ} → Γ ⇨ Γ ▻ σ wk = proj₁ -- Extends a substitution with another value. infixl 5 _►_ _►_ : ∀ {Γ Δ σ} (ρ : Γ ⇨ Δ) → Value Δ (σ / ρ) → Γ ▻ σ ⇨ Δ _►_ = <_,_> -- A substitution which only replaces the first "variable". sub : ∀ {Γ σ} → Value Γ σ → Γ ▻ σ ⇨ Γ sub v = id ► v -- One can construct a substitution between two non-empty contexts by -- supplying two functions, one which handles the last element and one -- which handles the rest. infixl 10 _↑_ _↑_ : ∀ {Γ Δ σ τ} (ρ : Γ ⇨ Δ) → σ / ρ ⇨₁ τ → Γ ▻ σ ⇨ Δ ▻ τ _↑_ = Prod.map -- Lifting. infix 10 _↑ _↑ : ∀ {Γ Δ σ} (ρ : Γ ⇨ Δ) → Γ ▻ σ ⇨ Δ ▻ σ / ρ ρ ↑ = ρ ↑ id ------------------------------------------------------------------------ -- Variables -- Variables (de Bruijn indices). infix 4 _∋_ data _∋_ : Term-like (u ⊔ e) where zero : ∀ {Γ σ} → Γ ▻ σ ∋ σ / wk suc : ∀ {Γ σ τ} (x : Γ ∋ σ) → Γ ▻ τ ∋ σ / wk -- Interpretation of variables: a lookup function. lookup : ∀ {Γ σ} → Γ ∋ σ → Value Γ σ lookup zero (γ , v) = v lookup (suc x) (γ , v) = lookup x γ -- Application of substitutions to variables. infixl 8 _/∋_ _/∋_ : ∀ {Γ Δ σ} → Γ ∋ σ → (ρ : Γ ⇨ Δ) → Value Δ (σ / ρ) x /∋ ρ = lookup x /v ρ ------------------------------------------------------------------------ -- Context extensions mutual -- Context extensions. infixl 5 _▻_ data Ctxt⁺ (Γ : Ctxt) : Set (u ⊔ e) where ε : Ctxt⁺ Γ _▻_ : (Γ⁺ : Ctxt⁺ Γ) (σ : Type (Γ ++ Γ⁺)) → Ctxt⁺ Γ -- Appends a context extension to a context. infixl 5 _++_ _++_ : (Γ : Ctxt) → Ctxt⁺ Γ → Ctxt Γ ++ ε = Γ Γ ++ (Γ⁺ ▻ σ) = (Γ ++ Γ⁺) ▻ σ mutual -- Application of substitutions to context extensions. infixl 8 _/⁺_ _/⁺_ : ∀ {Γ Δ} → Ctxt⁺ Γ → Γ ⇨ Δ → Ctxt⁺ Δ ε /⁺ ρ = ε (Γ⁺ ▻ σ) /⁺ ρ = Γ⁺ /⁺ ρ ▻ σ / ρ ↑⋆ Γ⁺ -- N-ary lifting of substitutions. infixl 10 _↑⋆_ _↑⋆_ : ∀ {Γ Δ} (ρ : Γ ⇨ Δ) → ∀ Γ⁺ → Γ ++ Γ⁺ ⇨ Δ ++ Γ⁺ /⁺ ρ ρ ↑⋆ ε = ρ ρ ↑⋆ (Γ⁺ ▻ σ) = (ρ ↑⋆ Γ⁺) ↑