1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431
|
------------------------------------------------------------------------
-- The Agda standard library
--
-- Example of multi-sorted algebras as indexed containers
------------------------------------------------------------------------
{-# OPTIONS --safe --cubical-compatible #-}
module README.Data.Container.Indexed.MultiSortedAlgebraExample where
------------------------------------------------------------------------
-- Preliminaries
------------------------------------------------------------------------
-- We import library content for indexed containers, standard types,
-- and setoids.
open import Level
open import Data.Container.Indexed.Core using (Container; ⟦_⟧; _◃_/_)
open import Data.Container.Indexed.FreeMonad using (_⋆C_)
open import Data.W.Indexed using (W; sup)
open import Data.Product using (Σ; _×_; _,_; Σ-syntax)
open import Data.Sum using (_⊎_; inj₁; inj₂; [_,_])
open import Data.Empty.Polymorphic using (⊥; ⊥-elim)
open import Function using (_∘_)
open import Function.Bundles using (Func)
open import Relation.Binary using (Setoid; IsEquivalence)
open import Relation.Binary.PropositionalEquality using (_≡_; refl)
import Data.Container.Indexed.Relation.Binary.Equality.Setoid as ICSetoid
import Relation.Binary.Reasoning.Setoid as SetoidReasoning
open Setoid using (Carrier; _≈_; isEquivalence)
open Func renaming (to to apply)
-- Letter ℓ denotes universe levels.
variable
ℓ ℓ' ℓˢ ℓᵒ ℓᵃ ℓᵐ ℓᵉ ℓⁱ : Level
I : Set ℓⁱ
S : Set ℓˢ
------------------------------------------------------------------------
-- The interpretation of a container (Op ◃ Ar / sort) is
--
-- ⟦ Op ◃ Ar / sort ⟧ X s = Σ[ o ∈ Op s ] ((i : Ar o) → X (sort o i))
--
-- which contains pairs consisting of an operator $o$ and its collection
-- of arguments. The least fixed point of (X ↦ ⟦ C ⟧ X) is the indexed
-- W-type given by C, and it contains closed first-order terms of the
-- multi-sorted algebra C.
-- We need to interpret indexed containers on Setoids.
-- This definition is missing from the standard library v1.7.
⟦_⟧s : (C : Container I S ℓᵒ ℓᵃ) (ξ : I → Setoid ℓᵐ ℓᵉ) → S → Setoid _ _
⟦ C ⟧s ξ = ICSetoid.setoid ξ C
------------------------------------------------------------------------
-- Multi-sorted algebras
--------------------------------------------------------------------------
-- A multi-sorted algebra is an indexed container.
--
-- * Sorts are indexes.
--
-- * Operators are commands/shapes.
--
-- * Arities/argument are responses/positions.
--
-- Closed terms (initial model) are given by the W type for a container,
-- renamed to μ here (for least fixed-point).
-- We assume a fixed signature (Sort, Ops).
module _ (Sort : Set ℓˢ) (Ops : Container Sort Sort ℓᵒ ℓᵃ) where
open Container Ops renaming
( Command to Op
; Response to Arity
; next to sort
)
-- We let letter $s$ range over sorts and $\mathit{op}$ over operators.
variable
s s' : Sort
op op' : Op s
------------------------------------------------------------------------
-- Models
-- A model is given by an interpretation (Den $s$) for each sort $s$
-- plus an interpretation (den $o$) for each operator $o$.
record SetModel ℓᵐ : Set (ℓˢ ⊔ ℓᵒ ⊔ ℓᵃ ⊔ suc ℓᵐ) where
field
Den : Sort → Set ℓᵐ
den : {s : Sort} → ⟦ Ops ⟧ Den s → Den s
-- The setoid model requires operators to respect equality.
-- The Func record packs a function (apply) with a proof (cong)
-- that the function maps equals to equals.
record SetoidModel ℓᵐ ℓᵉ : Set (ℓˢ ⊔ ℓᵒ ⊔ ℓᵃ ⊔ suc (ℓᵐ ⊔ ℓᵉ)) where
field
Den : Sort → Setoid ℓᵐ ℓᵉ
den : {s : Sort} → Func (⟦ Ops ⟧s Den s) (Den s)
------------------------------------------------------------------------
-- Terms
-- To obtain terms with free variables, we add additional nullary
-- operators, each representing a variable.
--
-- These are covered in the standard library FreeMonad module,
-- albeit with the restriction that the operator and variable sets
-- have the same size.
Cxt = Sort → Set ℓᵒ
variable
Γ Δ : Cxt
-- Terms with free variables in Var.
module _ (Var : Cxt) where
-- We keep the same sorts, but add a nullary operator for each variable.
Ops⁺ : Container Sort Sort ℓᵒ ℓᵃ
Ops⁺ = Ops ⋆C Var
-- Terms with variables are then given by the W-type for the extended container.
Tm = W Ops⁺
-- We define nice constructors for variables and operator application
-- via pattern synonyms.
-- Note that the $f$ in constructor var' is a function from the empty set,
-- so it should be uniquely determined. However, Agda's equality is
-- more intensional and will not identify all functions from the empty set.
-- Since we do not make use of the axiom of function extensionality,
-- we sometimes have to consult the extensional equality of the
-- function setoid.
pattern _∙_ op args = sup (inj₂ op , args)
pattern var' x f = sup (inj₁ x , f )
pattern var x = var' x _
-- Letter $t$ ranges over terms, and $\mathit{ts}$ over argument vectors.
variable
t t' t₁ t₂ t₃ : Tm Γ s
ts ts' : (i : Arity op) → Tm Γ (sort _ i)
------------------------------------------------------------------------
-- Parallel substitutions
-- A substitution from Δ to Γ holds a term in Γ for each variable in Δ.
Sub : (Γ Δ : Cxt) → Set _
Sub Γ Δ = ∀{s} (x : Δ s) → Tm Γ s
-- Application of a substitution.
_[_] : (t : Tm Δ s) (σ : Sub Γ Δ) → Tm Γ s
(var x ) [ σ ] = σ x
(op ∙ ts) [ σ ] = op ∙ λ i → ts i [ σ ]
-- Letter $σ$ ranges over substitutions.
variable
σ σ' : Sub Γ Δ
------------------------------------------------------------------------
-- Interpretation of terms in a model
------------------------------------------------------------------------
-- Given an algebra $M$ of set-size $ℓ^m$ and equality-size $ℓ^e$,
-- we define the interpretation of an $s$-sorted term $t$ as element
-- of $M(s)$ according to an environment $ρ$ that maps each variable
-- of sort $s'$ to an element of $M(s')$.
module _ {M : SetoidModel ℓᵐ ℓᵉ} where
open SetoidModel M
-- Equality in $M$'s interpretation of sort $s$.
_≃_ : Den s .Carrier → Den s .Carrier → Set _
_≃_ {s = s} = Den s ._≈_
-- An environment for Γ maps each variable $x : Γ(s)$ to an element of $M(s)$.
-- Equality of environments is defined pointwise.
Env : Cxt → Setoid _ _
Env Γ .Carrier = {s : Sort} (x : Γ s) → Den s .Carrier
Env Γ ._≈_ ρ ρ' = {s : Sort} (x : Γ s) → ρ x ≃ ρ' x
Env Γ .isEquivalence .IsEquivalence.refl {s = s} x = Den s .Setoid.refl
Env Γ .isEquivalence .IsEquivalence.sym h {s} x = Den s .Setoid.sym (h x)
Env Γ .isEquivalence .IsEquivalence.trans g h {s} x = Den s .Setoid.trans (g x) (h x)
-- Interpretation of terms is iteration on the W-type.
-- The standard library offers `iter' (on sets), but we need this to be a Func (on setoids).
⦅_⦆ : ∀{s} (t : Tm Γ s) → Func (Env Γ) (Den s)
⦅ var x ⦆ .apply ρ = ρ x
⦅ var x ⦆ .cong ρ=ρ' = ρ=ρ' x
⦅ op ∙ args ⦆ .apply ρ = den .apply (op , λ i → ⦅ args i ⦆ .apply ρ)
⦅ op ∙ args ⦆ .cong ρ=ρ' = den .cong (refl , λ i → ⦅ args i ⦆ .cong ρ=ρ')
-- An equality between two terms holds in a model
-- if the two terms are equal under all valuations of their free variables.
Equal : ∀ {Γ s} (t t' : Tm Γ s) → Set _
Equal {Γ} {s} t t' = ∀ (ρ : Env Γ .Carrier) → ⦅ t ⦆ .apply ρ ≃ ⦅ t' ⦆ .apply ρ
-- This notion is an equivalence relation.
isEquiv : IsEquivalence (Equal {Γ = Γ} {s = s})
isEquiv {s = s} .IsEquivalence.refl ρ = Den s .Setoid.refl
isEquiv {s = s} .IsEquivalence.sym e ρ = Den s .Setoid.sym (e ρ)
isEquiv {s = s} .IsEquivalence.trans e e' ρ = Den s .Setoid.trans (e ρ) (e' ρ)
------------------------------------------------------------------------
-- Substitution lemma
-- Evaluation of a substitution gives an environment.
⦅_⦆s : Sub Γ Δ → Env Γ .Carrier → Env Δ .Carrier
⦅ σ ⦆s ρ x = ⦅ σ x ⦆ .apply ρ
-- Substitution lemma: ⦅t[σ]⦆ρ ≃ ⦅t⦆⦅σ⦆ρ
substitution : (t : Tm Δ s) (σ : Sub Γ Δ) (ρ : Env Γ .Carrier) →
⦅ t [ σ ] ⦆ .apply ρ ≃ ⦅ t ⦆ .apply (⦅ σ ⦆s ρ)
substitution (var x) σ ρ = Den _ .Setoid.refl
substitution (op ∙ ts) σ ρ = den .cong (refl , λ i → substitution (ts i) σ ρ)
------------------------------------------------------------------------
-- Equations
-- An equation is a pair $t ≐ t'$ of terms of the same sort in the same context.
record Eq : Set (ℓˢ ⊔ suc ℓᵒ ⊔ ℓᵃ) where
constructor _≐_
field
{cxt} : Sort → Set ℓᵒ
{srt} : Sort
lhs : Tm cxt srt
rhs : Tm cxt srt
-- Equation $t ≐ t'$ holding in model $M$.
_⊧_ : (M : SetoidModel ℓᵐ ℓᵉ) (eq : Eq) → Set _
M ⊧ (t ≐ t') = Equal {M = M} t t'
-- Sets of equations are presented as collection E : I → Eq
-- for some index set I : Set ℓⁱ.
-- An entailment/consequence $E ⊃ t ≐ t'$ is valid
-- if $t ≐ t'$ holds in all models that satify equations $E$.
module _ {ℓᵐ ℓᵉ} where
_⊃_ : (E : I → Eq) (eq : Eq) → Set _
E ⊃ eq = ∀ (M : SetoidModel ℓᵐ ℓᵉ) → (∀ i → M ⊧ E i) → M ⊧ eq
-- Derivations
--------------
-- Equalitional logic allows us to prove entailments via the
-- inference rules for the judgment $E ⊢ Γ ▹ t ≡ t'$.
-- This could be coined as equational theory over a given
-- set of equations $E$.
-- Relation $E ⊢ Γ ▹ \_ ≡ \_$ is the least congruence over the equations $E$.
data _⊢_▹_≡_ {I : Set ℓⁱ}
(E : I → Eq) : (Γ : Cxt) (t t' : Tm Γ s) → Set (ℓˢ ⊔ suc ℓᵒ ⊔ ℓᵃ ⊔ ℓⁱ) where
hyp : ∀ i → let t ≐ t' = E i in
E ⊢ _ ▹ t ≡ t'
base : ∀ (x : Γ s) {f f' : (i : ⊥) → Tm _ (⊥-elim i)} →
E ⊢ Γ ▹ var' x f ≡ var' x f'
app : (∀ i → E ⊢ Γ ▹ ts i ≡ ts' i) →
E ⊢ Γ ▹ (op ∙ ts) ≡ (op ∙ ts')
sub : E ⊢ Δ ▹ t ≡ t' →
∀ (σ : Sub Γ Δ) →
E ⊢ Γ ▹ (t [ σ ]) ≡ (t' [ σ ])
refl : ∀ (t : Tm Γ s) →
E ⊢ Γ ▹ t ≡ t
sym : E ⊢ Γ ▹ t ≡ t' →
E ⊢ Γ ▹ t' ≡ t
trans : E ⊢ Γ ▹ t₁ ≡ t₂ →
E ⊢ Γ ▹ t₂ ≡ t₃ →
E ⊢ Γ ▹ t₁ ≡ t₃
------------------------------------------------------------------------
-- Soundness of the inference rules
-- We assume a model $M$ that validates all equations in $E$.
module Soundness {I : Set ℓⁱ} (E : I → Eq) (M : SetoidModel ℓᵐ ℓᵉ)
(V : ∀ i → M ⊧ E i) where
open SetoidModel M
-- In any model $M$ that satisfies the equations $E$,
-- derived equality is actual equality.
sound : E ⊢ Γ ▹ t ≡ t' → M ⊧ (t ≐ t')
sound (hyp i) = V i
sound (app {op = op} es) ρ = den .cong (refl , λ i → sound (es i) ρ)
sound (sub {t = t} {t' = t'} e σ) ρ = begin
⦅ t [ σ ] ⦆ .apply ρ ≈⟨ substitution {M = M} t σ ρ ⟩
⦅ t ⦆ .apply ρ' ≈⟨ sound e ρ' ⟩
⦅ t' ⦆ .apply ρ' ≈⟨ substitution {M = M} t' σ ρ ⟨
⦅ t' [ σ ] ⦆ .apply ρ ∎
where
open SetoidReasoning (Den _)
ρ' = ⦅ σ ⦆s ρ
sound (base x {f} {f'}) = isEquiv {M = M} .IsEquivalence.refl {var' x λ()}
sound (refl t) = isEquiv {M = M} .IsEquivalence.refl {t}
sound (sym {t = t} {t' = t'} e) = isEquiv {M = M} .IsEquivalence.sym
{x = t} {y = t'} (sound e)
sound (trans {t₁ = t₁} {t₂ = t₂}
{t₃ = t₃} e e') = isEquiv {M = M} .IsEquivalence.trans
{i = t₁} {j = t₂} {k = t₃} (sound e) (sound e')
------------------------------------------------------------------------
-- Birkhoff's completeness theorem
------------------------------------------------------------------------
-- Birkhoff proved that any equation $t ≐ t'$ is derivable from $E$
-- when it is valid in all models satisfying $E$. His proof (for
-- single-sorted algebras) is a blue print for many more
-- completeness proofs. They all proceed by constructing a
-- universal model aka term model. In our case, it is terms
-- quotiented by derivable equality $E ⊢ Γ ▹ \_ ≡ \_$. It then
-- suffices to prove that this model satisfies all equations in $E$.
------------------------------------------------------------------------
-- Universal model
-- A term model for $E$ and $Γ$ interprets sort $s$ by (Tm Γ s) quotiented by $E ⊢ Γ ▹ \_ ≡ \_$.
module TermModel {I : Set ℓⁱ} (E : I → Eq) where
open SetoidModel
-- Tm Γ s quotiented by E⊢Γ▹·≡·.
TmSetoid : Cxt → Sort → Setoid _ _
TmSetoid Γ s .Carrier = Tm Γ s
TmSetoid Γ s ._≈_ = E ⊢ Γ ▹_≡_
TmSetoid Γ s .isEquivalence .IsEquivalence.refl = refl _
TmSetoid Γ s .isEquivalence .IsEquivalence.sym = sym
TmSetoid Γ s .isEquivalence .IsEquivalence.trans = trans
-- The interpretation of an operator is simply the operator.
-- This works because $E⊢Γ▹\_≡\_$ is a congruence.
tmInterp : ∀ {Γ s} → Func (⟦ Ops ⟧s (TmSetoid Γ) s) (TmSetoid Γ s)
tmInterp .apply (op , ts) = op ∙ ts
tmInterp .cong (refl , h) = app h
-- The term model per context Γ.
M : Cxt → SetoidModel _ _
M Γ .Den = TmSetoid Γ
M Γ .den = tmInterp
-- The identity substitution σ₀ maps variables to themselves.
σ₀ : {Γ : Cxt} → Sub Γ Γ
σ₀ x = var' x λ()
-- σ₀ acts indeed as identity.
identity : (t : Tm Γ s) → E ⊢ Γ ▹ t [ σ₀ ] ≡ t
identity (var x) = base x
identity (op ∙ ts) = app λ i → identity (ts i)
-- Evaluation in the term model is substitution $E ⊢ Γ ▹ ⦅t⦆σ ≡ t[σ]$.
-- This would even hold "up to the nose" if we had function extensionality.
evaluation : (t : Tm Δ s) (σ : Sub Γ Δ) → E ⊢ Γ ▹ (⦅_⦆ {M = M Γ} t .apply σ) ≡ (t [ σ ])
evaluation (var x) σ = refl (σ x)
evaluation (op ∙ ts) σ = app (λ i → evaluation (ts i) σ)
-- The term model satisfies all the equations it started out with.
satisfies : ∀ i → M Γ ⊧ E i
satisfies i σ = begin
⦅ tₗ ⦆ .apply σ ≈⟨ evaluation tₗ σ ⟩
tₗ [ σ ] ≈⟨ sub (hyp i) σ ⟩
tᵣ [ σ ] ≈⟨ evaluation tᵣ σ ⟨
⦅ tᵣ ⦆ .apply σ ∎
where
open SetoidReasoning (TmSetoid _ _)
tₗ = E i .Eq.lhs
tᵣ = E i .Eq.rhs
------------------------------------------------------------------------
-- Completeness
-- Birkhoff's completeness theorem \citeyearpar{birkhoff:1935}:
-- Any valid consequence is derivable in the equational theory.
module Completeness {I : Set ℓⁱ} (E : I → Eq) {Γ s} {t t' : Tm Γ s} where
open TermModel E
completeness : E ⊃ (t ≐ t') → E ⊢ Γ ▹ t ≡ t'
completeness V = begin
t ≈˘⟨ identity t ⟩
t [ σ₀ ] ≈˘⟨ evaluation t σ₀ ⟩
⦅ t ⦆ .apply σ₀ ≈⟨ V (M Γ) satisfies σ₀ ⟩
⦅ t' ⦆ .apply σ₀ ≈⟨ evaluation t' σ₀ ⟩
t' [ σ₀ ] ≈⟨ identity t' ⟩
t' ∎
where open SetoidReasoning (TmSetoid Γ s)
|