added Darais

This commit is contained in:
wadler 2018-02-23 14:50:29 +01:00
parent c75cd9dc06
commit 543017049d

215
src/extra/Darais.agda Normal file
View file

@ -0,0 +1,215 @@
-- Author: David Darais
--
-- This is a dependent de Bruijn encoding of STLC with proofs for
-- progress and preservation. This file has zero dependencies and is
-- 100% self-contained.
--
-- Because there is only a notion of well-typed terms (non-well-typed
-- terms do not exist), preservation is merely by observation that
-- substitution (i.e., cut) can be defined.
--
-- A small-step evaluation semantics is defined after the definition of cut.
--
-- Progress is proved w.r.t. the evaluation semantics.
--
-- Some ideas for extensions or homeworks are given at the end.
--
-- A few helper definitions are required.
-- * Basic Agda constructions (like booleans, products, dependent sums,
-- and lists) are defined first in a Prelude module which is
-- immediately opened.
-- * Binders (x : τ ∈ Γ) are proofs that the element τ is contained in
-- the list of types Γ. Helper functions for weakening and
-- introducing variables into contexts which are reusable are
-- defined in the Prelude. Helpers for weakening terms are defined
-- below. Some of the non-general helpers (like cut[∈]) could be
-- defined in a generic way to be reusable, but I decided against
-- this to keep things simple.
module Darais where
open import Agda.Primitive using (_⊔_)
module Prelude where
infixr 3 ∃𝑠𝑡
infixl 5 __
infix 10 _∈_
infixl 15 _⧺_
infixl 15 _⊟_
infixl 15 _∾_
infixr 20 _∷_
data 𝔹 : Set where
T : 𝔹
F : 𝔹
data __ {ℓ₁ ℓ₂} (A : Set ℓ₁) (B : Set ℓ₂) : Set (ℓ₁ ℓ₂) where
Inl : A A B
Inr : B A B
syntax ∃𝑠𝑡 A (λ x B) = x A 𝑠𝑡 B
data ∃𝑠𝑡 {ℓ₁ ℓ₂} (A : Set ℓ₁) (B : A Set ℓ₂) : Set (ℓ₁ ℓ₂) where
⟨∃_,_⟩ : (x : A) B x x A 𝑠𝑡 B x
data ⟬_⟭ {} (A : Set ) : Set where
[] : A
_∷_ : A A A
_⧺_ : {} {A : Set } A A A
[] ys = ys
x xs ys = x (xs ys)
_∾_ : {} {A : Set } A A A
[] ys = ys
(x xs) ys = xs x ys
data _∈_ {} {A : Set } (x : A) : (xs : A ) Set where
Z : {xs} x x xs
S : {x xs} x xs x x xs
_⊟_ : {} {A : Set } (xs : A ) {x} x xs A
x xs Z = xs
x xs S ε = x (xs ε)
wk[∈] : {} {A : Set } {xs : A } {x : A} xs x xs x xs xs
wk[∈] [] x = x
wk[∈] (x xs) x = wk[∈] xs (S x)
i[∈][_] : {} {A : Set } {xs : A } {x x : A} (ε′ : x xs) x xs ε′ x xs
i[∈][ Z ] x = S x
i[∈][ S ε′ ] Z = Z
i[∈][ S ε′ ] (S x) = S (i[∈][ ε′ ] x)
open Prelude
-- ============================ --
-- Simply Typed Lambda Calculus --
-- ============================ --
-- A dependent de Bruijn encoding
-- Or, the dynamic semantics of natural deduction as seen through Curry-Howard
-- types --
data type : Set where
⟨𝔹⟩ : type
_⟨→⟩_ : type type type
-- terms --
infix 10 _⊢_
data _⊢_ : (Γ : type ) (τ : type) Set where
⟨𝔹⟩ : {Γ}
(b : 𝔹)
Γ ⟨𝔹⟩
⟨if⟩___ : {Γ τ}
(e₁ : Γ ⟨𝔹⟩)
(e₂ : Γ τ)
(e₃ : Γ τ)
Γ τ
Var : {Γ τ}
(x : τ Γ)
Γ τ
⟨λ⟩ : {Γ τ₁ τ₂}
(e : τ₁ Γ τ₂)
Γ τ₁ ⟨→⟩ τ₂
_⟨⋅⟩_ : {Γ τ₁ τ₂}
(e₁ : Γ τ₁ ⟨→⟩ τ₂)
(e₂ : Γ τ₁)
Γ τ₂
-- introducing a new variable to the context --
i[⊢][_] : {Γ τ τ′} (x : τ′ Γ) Γ x τ Γ τ
i[⊢][ x ] (⟨𝔹⟩ b) = ⟨𝔹⟩ b
i[⊢][ x ] ⟨if⟩ e₁ e₂ e₃ = ⟨if⟩ i[⊢][ x ] e₁ i[⊢][ x ] e₂ i[⊢][ x ] e₃
i[⊢][ x ] (Var x) = Var (i[∈][ x ] x)
i[⊢][ x ] (⟨λ⟩ e) = ⟨λ⟩ (i[⊢][ S x ] e)
i[⊢][ x ] (e₁ ⟨⋅⟩ e₂) = i[⊢][ x ] e₁ ⟨⋅⟩ i[⊢][ x ] e₂
i[⊢] : {Γ τ τ′} Γ τ τ′ Γ τ
i[⊢] = i[⊢][ Z ]
-- substitution for variables --
cut[∈]<_>[_] : {Γ τ₁ τ₂} (x : τ₁ Γ) Γ′ Γ′ (Γ x) τ₁ τ₂ Γ Γ′ (Γ x) τ₂
cut[∈]< Z >[ Γ′ ] e Z = e
cut[∈]< Z >[ Γ′ ] e (S y) = Var (wk[∈] Γ′ y)
cut[∈]< S x >[ Γ′ ] e Z = Var (wk[∈] Γ′ Z)
cut[∈]< S x >[ Γ′ ] e (S x) = cut[∈]< x >[ _ Γ′ ] e x
cut[∈]<_> : {Γ τ₁ τ₂} (x : τ₁ Γ) Γ x τ₁ τ₂ Γ Γ x τ₂
cut[∈]< x > = cut[∈]< x >[ [] ]
-- substitution for terms --
cut[⊢][_] : {Γ τ₁ τ₂} (x : τ₁ Γ) Γ x τ₁ Γ τ₂ Γ x τ₂
cut[⊢][ x ] e (⟨𝔹⟩ b) = ⟨𝔹⟩ b
cut[⊢][ x ] e ⟨if⟩ e₁ e₂ e₃ = ⟨if⟩ cut[⊢][ x ] e e₁ cut[⊢][ x ] e e₂ cut[⊢][ x ] e e₃
cut[⊢][ x ] e (Var x) = cut[∈]< x > e x
cut[⊢][ x ] e (⟨λ⟩ e) = ⟨λ⟩ (cut[⊢][ S x ] (i[⊢] e) e)
cut[⊢][ x ] e (e₁ ⟨⋅⟩ e₂) = cut[⊢][ x ] e e₁ ⟨⋅⟩ cut[⊢][ x ] e e₂
cut[⊢] : {Γ τ₁ τ₂} Γ τ₁ τ₁ Γ τ₂ Γ τ₂
cut[⊢] = cut[⊢][ Z ]
-- values --
data value {Γ} : {τ} Γ τ Set where
⟨𝔹⟩ : b value (⟨𝔹⟩ b)
⟨λ⟩ : {τ τ′} (e : τ′ Γ τ) value (⟨λ⟩ e)
-- CBV evaluation for terms --
-- (borrowing some notation and style from Wadler: https://wenkokke.github.io/sf/Stlc)
infix 10 _↝_
data _↝_ {Γ τ} : Γ τ Γ τ Set where
ξ⋅₁ : {τ′} {e₁ e₁ : Γ τ′ ⟨→⟩ τ} {e₂ : Γ τ′}
e₁ e₁
e₁ ⟨⋅⟩ e₂ e₁ ⟨⋅⟩ e₂
ξ⋅₂ : {τ′} {e₁ : Γ τ′ ⟨→⟩ τ} {e₂ e₂ : Γ τ′}
value e₁
e₂ e₂
e₁ ⟨⋅⟩ e₂ e₁ ⟨⋅⟩ e₂
βλ : {τ′} {e₁ : τ′ Γ τ} {e₂ : Γ τ′}
value e₂
⟨λ⟩ e₁ ⟨⋅⟩ e₂ cut[⊢] e₂ e₁
ξif : {e₁ e₁ : Γ ⟨𝔹⟩} {e₂ e₃ : Γ τ}
e₁ e₁
⟨if⟩ e₁ e₂ e₃ ⟨if⟩ e₁ e₂ e₃
ξif-T : {e₂ e₃ : Γ τ}
⟨if⟩ ⟨𝔹⟩ T e₂ e₃ e₂
ξif-F : {e₂ e₃ : Γ τ}
⟨if⟩ ⟨𝔹⟩ F e₂ e₃ e₃
-- progress --
progress : {τ} (e : [] τ) value e ( e [] τ 𝑠𝑡 e e)
progress (⟨𝔹⟩ b) = Inl (⟨𝔹⟩ b)
progress ⟨if⟩ e e₁ e₂ with progress e
| Inl (⟨𝔹⟩ T) = Inr ⟨∃ e₁ , ξif-T
| Inl (⟨𝔹⟩ F) = Inr ⟨∃ e₂ , ξif-F
| Inr ⟨∃ e , ε = Inr ⟨∃ ⟨if⟩ e e₁ e₂ , ξif ε
progress (Var ())
progress (⟨λ⟩ e) = Inl (⟨λ⟩ e)
progress (e₁ ⟨⋅⟩ e₂) with progress e₁
| Inr ⟨∃ e₁ , ε = Inr ⟨∃ e₁ ⟨⋅⟩ e₂ , ξ⋅₁ ε
| Inl (⟨λ⟩ e) with progress e₂
| Inl x = Inr ⟨∃ cut[⊢] e₂ e , βλ x
| Inr ⟨∃ e₂ , ε = Inr ⟨∃ e₁ ⟨⋅⟩ e₂ , ξ⋅₂ (⟨λ⟩ e) ε
-- Some ideas for possible extensions or homework assignments
-- 1. A. Write a conversion from the dependent de Bruijn encoding (e : Γ ⊢ τ)
-- to the untyped lambda calculus (e : term).
-- B. Prove that the image of this conversion is well typed.
-- C. Write a conversion from well-typed untyped lambda calculus
-- terms ([e : term] and [ε : (Γ ⊢ e ⦂ τ)] into the dependent de
-- Bruijn encoding (e : Γ ⊢ τ)
-- 2. A. Write a predicate analogous to 'value' for strongly reduced
-- terms (reduction under lambda)
-- B. Prove "strong" progress: A term is either fully beta-reduced
-- (including under lambda) or it can take a step
-- 3. Relate this semantics to a big-step semantics.
-- 4. Prove strong normalization.
-- 5. Relate this semantics to a definitional interpreter into Agda's Set.