first draft of Subtyping, still needs some text
This commit is contained in:
parent
a79af92920
commit
f14ddf42ec
1 changed files with 850 additions and 0 deletions
850
src/plfa/part2/Subtyping.lagda.md
Normal file
850
src/plfa/part2/Subtyping.lagda.md
Normal file
|
@ -0,0 +1,850 @@
|
|||
---
|
||||
title : "Subtyping: records"
|
||||
layout : page
|
||||
prev : /More/
|
||||
permalink : /Subtyping/
|
||||
next : /Bisimulation/
|
||||
---
|
||||
|
||||
```
|
||||
module plfa.part2.Subtyping where
|
||||
```
|
||||
|
||||
## Imports
|
||||
|
||||
```
|
||||
open import Data.Empty using (⊥; ⊥-elim)
|
||||
open import Data.Empty.Irrelevant renaming (⊥-elim to ⊥-elimi)
|
||||
open import Data.Fin using (Fin; zero; suc)
|
||||
open import Data.Nat using (ℕ; zero; suc; _≤_; z≤n; s≤s; _<_; _+_)
|
||||
open import Data.Nat.Properties using (m+n≤o⇒m≤o; m+n≤o⇒n≤o; n≤0⇒n≡0; ≤-pred; ≤-refl)
|
||||
open import Data.Product using (_×_; proj₁; proj₂; Σ-syntax) renaming (_,_ to ⟨_,_⟩)
|
||||
open import Data.String using (String; _≟_)
|
||||
open import Data.Unit using (⊤; tt)
|
||||
open import Data.Vec using (Vec; []; _∷_; lookup)
|
||||
open import Data.Vec.Membership.Propositional using (_∈_)
|
||||
open import Data.Vec.Membership.DecPropositional _≟_ using (_∈?_)
|
||||
open import Data.Vec.Membership.Propositional.Properties using (∈-lookup)
|
||||
open import Data.Vec.Relation.Unary.Any using (here; there)
|
||||
import Relation.Binary.PropositionalEquality as Eq
|
||||
open Eq using (_≡_; _≢_; refl; sym; trans; cong)
|
||||
open import Relation.Nullary using (Dec; yes; no; ¬_)
|
||||
```
|
||||
|
||||
## Syntax
|
||||
|
||||
```
|
||||
infix 4 _⊢_⦂_
|
||||
infix 4 _∋_⦂_
|
||||
infixl 5 _,_
|
||||
|
||||
infixr 7 _⇒_
|
||||
|
||||
infix 5 ƛ_
|
||||
infix 5 μ_
|
||||
infixl 7 _·_
|
||||
infix 8 `suc_
|
||||
infix 9 `_
|
||||
infixl 7 _#_
|
||||
```
|
||||
|
||||
|
||||
## Record Field Names, Functions and Properties
|
||||
|
||||
We represent field identifiers (aka. names) as strings.
|
||||
|
||||
```
|
||||
Name : Set
|
||||
Name = String
|
||||
```
|
||||
|
||||
The field identifiers of a record will be stored in a sequence,
|
||||
specifically Agda's `Vec` type. We require that the field names of a
|
||||
record be distinct, which we define as follows.
|
||||
|
||||
```
|
||||
distinct : ∀{A : Set}{n} → Vec A n → Set
|
||||
distinct [] = ⊤
|
||||
distinct (x ∷ xs) = ¬ (x ∈ xs) × distinct xs
|
||||
```
|
||||
|
||||
For vectors of distinct elements, lookup is injective.
|
||||
|
||||
```
|
||||
distinct-lookup-inj : ∀ {n}{ls : Vec Name n}{i j : Fin n}
|
||||
→ distinct ls → lookup ls i ≡ lookup ls j
|
||||
→ i ≡ j
|
||||
distinct-lookup-inj {.(suc _)} {x ∷ ls} {zero} {zero} ⟨ x∉ls , dls ⟩ lsij = refl
|
||||
distinct-lookup-inj {.(suc _)} {x ∷ ls} {zero} {suc j} ⟨ x∉ls , dls ⟩ refl =
|
||||
⊥-elim (x∉ls (∈-lookup j ls))
|
||||
distinct-lookup-inj {.(suc _)} {x ∷ ls} {suc i} {zero} ⟨ x∉ls , dls ⟩ refl =
|
||||
⊥-elim (x∉ls (∈-lookup i ls))
|
||||
distinct-lookup-inj {.(suc _)} {x ∷ ls} {suc i} {suc j} ⟨ x∉ls , dls ⟩ lsij =
|
||||
cong suc (distinct-lookup-inj dls lsij)
|
||||
```
|
||||
|
||||
We shall need to convert from an irrelevent proof of distinctness to a
|
||||
relevant one. In general, this can be accomplished for any decidable
|
||||
predicate. The following is a decision procedure for whether a vector
|
||||
is distinct.
|
||||
|
||||
```
|
||||
distinct? : ∀{n} → (xs : Vec Name n) → Dec (distinct xs)
|
||||
distinct? [] = yes tt
|
||||
distinct? (x ∷ xs)
|
||||
with x ∈? xs
|
||||
... | yes x∈xs = no λ z → proj₁ z x∈xs
|
||||
... | no x∉xs
|
||||
with distinct? xs
|
||||
... | yes dxs = yes ⟨ x∉xs , dxs ⟩
|
||||
... | no ¬dxs = no λ x₁ → ¬dxs (proj₂ x₁)
|
||||
```
|
||||
|
||||
With the decision procedure in hand, we can launder an irrelevant
|
||||
proof into a relevant one.
|
||||
|
||||
```
|
||||
distinct-relevant : ∀ {n}{fs : Vec Name n} .(d : distinct fs) → distinct fs
|
||||
distinct-relevant {n}{fs} d
|
||||
with distinct? fs
|
||||
... | yes dfs = dfs
|
||||
... | no ¬dfs = ⊥-elimi (¬dfs d)
|
||||
```
|
||||
|
||||
The fields of one record are a subset of the fields of another record
|
||||
if every field of the first is also a field of the second.
|
||||
|
||||
```
|
||||
_⊆_ : ∀{n m} → Vec Name n → Vec Name m → Set
|
||||
xs ⊆ ys = (x : Name) → x ∈ xs → x ∈ ys
|
||||
```
|
||||
|
||||
This subset relation is reflexive.
|
||||
|
||||
```
|
||||
⊆-refl : ∀{n}{ls : Vec Name n} → ls ⊆ ls
|
||||
⊆-refl {n}{ls} = λ x x∈ls → x∈ls
|
||||
```
|
||||
|
||||
It is also transitive.
|
||||
|
||||
```
|
||||
⊆-trans : ∀{l n m}{ns : Vec Name n}{ms : Vec Name m}{ls : Vec Name l}
|
||||
→ ns ⊆ ms → ms ⊆ ls
|
||||
→ ns ⊆ ls
|
||||
⊆-trans {l}{n}{m}{ns}{ms}{ls} ns⊆ms ms⊆ls = λ x z → ms⊆ls x (ns⊆ms x z)
|
||||
```
|
||||
|
||||
|
||||
|
||||
If `y` is an element of vector `xs`, then `y` is at some index `i` of
|
||||
the vector.
|
||||
|
||||
```
|
||||
lookup-∈ : ∀{ℓ}{A : Set ℓ}{n} {xs : Vec A n}{y}
|
||||
→ y ∈ xs
|
||||
→ Σ[ i ∈ Fin n ] lookup xs i ≡ y
|
||||
lookup-∈ {xs = x ∷ xs} (here refl) = ⟨ zero , refl ⟩
|
||||
lookup-∈ {xs = x ∷ xs} (there y∈xs)
|
||||
with lookup-∈ y∈xs
|
||||
... | ⟨ i , xs[i]=y ⟩ = ⟨ (suc i) , xs[i]=y ⟩
|
||||
```
|
||||
|
||||
If one vector `ns` is a subset of another `ms`, then for any element
|
||||
`lookup ns i`, there is an equal element in `ms` at some index.
|
||||
|
||||
```
|
||||
lookup-⊆ : ∀{n m : ℕ}{ns : Vec Name n}{ms : Vec Name m}{i : Fin n}
|
||||
→ ns ⊆ ms
|
||||
→ Σ[ k ∈ Fin m ] lookup ns i ≡ lookup ms k
|
||||
lookup-⊆ {suc n} {m} {x ∷ ns} {ms} {zero} ns⊆ms
|
||||
with lookup-∈ (ns⊆ms x (here refl))
|
||||
... | ⟨ k , ms[k]=x ⟩ =
|
||||
⟨ k , (sym ms[k]=x) ⟩
|
||||
lookup-⊆ {suc n} {m} {x ∷ ns} {ms} {suc i} x∷ns⊆ms =
|
||||
lookup-⊆ {n} {m} {ns} {ms} {i} (λ x z → x∷ns⊆ms x (there z))
|
||||
```
|
||||
|
||||
## Types
|
||||
|
||||
```
|
||||
infix 5 {_⦂_}
|
||||
|
||||
data Type : Set where
|
||||
_⇒_ : Type → Type → Type
|
||||
`ℕ : Type
|
||||
{_⦂_} : {n : ℕ} (ls : Vec Name n) (As : Vec Type n) → .{d : distinct ls} → Type
|
||||
```
|
||||
|
||||
We do not want the details of the proof of distinctness to affect
|
||||
whether two record types are equal, so we declare that parameter to be
|
||||
irrelevant by placing a `.` in front of it.
|
||||
|
||||
|
||||
## Subtyping
|
||||
|
||||
```
|
||||
infix 5 _<:_
|
||||
|
||||
data _<:_ : Type → Type → Set where
|
||||
<:-nat : `ℕ <: `ℕ
|
||||
|
||||
<:-fun : ∀{A B C D : Type}
|
||||
→ C <: A → B <: D
|
||||
----------------
|
||||
→ A ⇒ B <: C ⇒ D
|
||||
|
||||
<:-rcd : ∀{m}{ks : Vec Name m}{Ss : Vec Type m}.{d1 : distinct ks}
|
||||
{n}{ls : Vec Name n}{Ts : Vec Type n}.{d2 : distinct ls}
|
||||
→ ls ⊆ ks
|
||||
→ (∀{i : Fin n}{j : Fin m} → lookup ks j ≡ lookup ls i
|
||||
→ lookup Ss j <: lookup Ts i)
|
||||
------------------------------------------------------
|
||||
→ { ks ⦂ Ss } {d1} <: { ls ⦂ Ts } {d2}
|
||||
```
|
||||
|
||||
The first premise of the record subtyping rule (`<:-rcd`) expresses
|
||||
_width subtyping_ by requiring that all the labels in `ls` are also in
|
||||
`ks`. So it allows the hiding of fields when going from a subtype to a
|
||||
supertype.
|
||||
|
||||
The second premise of the record subtyping rule (`<:-rcd`) expresses
|
||||
_depth subtyping_, that is, it allows the types of the fields to
|
||||
change according to subtyping. The following is an abbreviation for
|
||||
this premise.
|
||||
|
||||
```
|
||||
_⦂_<:_⦂_ : ∀ {m n} → Vec Name m → Vec Type m → Vec Name n → Vec Type n → Set
|
||||
_⦂_<:_⦂_ {m}{n} ks Ss ls Ts = (∀{i : Fin n}{j : Fin m}
|
||||
→ lookup ks j ≡ lookup ls i → lookup Ss j <: lookup Ts i)
|
||||
```
|
||||
|
||||
## Subtyping is Reflexive
|
||||
|
||||
The proof that subtyping is reflexive does not go by induction on the
|
||||
type because of the `<:-rcd` rule. We instead use induction on the
|
||||
size of the type. So we first define size of a type, and the size of a
|
||||
vector of types, as follows.
|
||||
|
||||
```
|
||||
ty-size : (A : Type) → ℕ
|
||||
vec-ty-size : ∀ {n : ℕ} → (As : Vec Type n) → ℕ
|
||||
|
||||
ty-size (A ⇒ B) = suc (ty-size A + ty-size B)
|
||||
ty-size `ℕ = 1
|
||||
ty-size { ls ⦂ As } = suc (vec-ty-size As)
|
||||
|
||||
vec-ty-size {n} [] = 0
|
||||
vec-ty-size {n} (x ∷ xs) = ty-size x + vec-ty-size xs
|
||||
```
|
||||
|
||||
The size of a type is always positive.
|
||||
|
||||
```
|
||||
ty-size-pos : ∀ {A} → 0 < ty-size A
|
||||
ty-size-pos {A ⇒ B} = s≤s z≤n
|
||||
ty-size-pos {`ℕ} = s≤s z≤n
|
||||
ty-size-pos {{ fs ⦂ As } } = s≤s z≤n
|
||||
```
|
||||
|
||||
If a vector of types has a size smaller than `n`, then so is any type
|
||||
in the vector.
|
||||
|
||||
```
|
||||
lookup-vec-ty-size : ∀{n}{k} {As : Vec Type k} {j}
|
||||
→ vec-ty-size As ≤ n
|
||||
→ ty-size (lookup As j) ≤ n
|
||||
lookup-vec-ty-size {n} {suc k} {A ∷ As} {zero} As≤n = m+n≤o⇒m≤o (ty-size A) As≤n
|
||||
lookup-vec-ty-size {n} {suc k} {A ∷ As} {suc j} As≤n =
|
||||
lookup-vec-ty-size {n} {k} {As} (m+n≤o⇒n≤o (ty-size A) As≤n)
|
||||
```
|
||||
|
||||
Here is the proof of reflexivity, by induction on the size of the type.
|
||||
|
||||
```
|
||||
<:-refl-aux : ∀{n}{A}{m : ty-size A ≤ n} → A <: A
|
||||
<:-refl-aux {0}{A}{m}
|
||||
with ty-size-pos {A}
|
||||
... | pos rewrite n≤0⇒n≡0 m
|
||||
with pos
|
||||
... | ()
|
||||
<:-refl-aux {suc n}{`ℕ}{m} = <:-nat
|
||||
<:-refl-aux {suc n}{A ⇒ B}{m} =
|
||||
let a = ≤-pred m in
|
||||
<:-fun (<:-refl-aux{n}{A}{m+n≤o⇒m≤o (ty-size A) a })
|
||||
(<:-refl-aux{n}{B}{m+n≤o⇒n≤o (ty-size A) a})
|
||||
<:-refl-aux {suc n}{{ fs ⦂ As } {d} }{m} = <:-rcd {d1 = d}{d2 = d} ⊆-refl G
|
||||
where
|
||||
G : fs ⦂ As <: fs ⦂ As
|
||||
G {i}{j} lij rewrite distinct-lookup-inj (distinct-relevant d) lij =
|
||||
let As[i]≤n = lookup-vec-ty-size {As = As}{i} (≤-pred m) in
|
||||
<:-refl-aux {n}{lookup As i}{As[i]≤n}
|
||||
```
|
||||
|
||||
```
|
||||
<:-refl : ∀{A} → A <: A
|
||||
<:-refl {A} = <:-refl-aux {ty-size A}{A}{≤-refl}
|
||||
```
|
||||
|
||||
## Subtyping is transitive
|
||||
|
||||
The proof of transitivity is straightforward, given that we've
|
||||
already proved the two lemmas needed in the case for `<:-rcd`:
|
||||
`⊆-trans` and `lookup-⊆`.
|
||||
|
||||
```
|
||||
<:-trans : ∀{A B C}
|
||||
→ A <: B → B <: C
|
||||
-------------------
|
||||
→ A <: C
|
||||
<:-trans {A₁ ⇒ A₂} {B₁ ⇒ B₂} {C₁ ⇒ C₂} (<:-fun A<:B A<:B₁) (<:-fun B<:C B<:C₁) =
|
||||
<:-fun (<:-trans B<:C A<:B) (<:-trans A<:B₁ B<:C₁)
|
||||
<:-trans {.`ℕ} {`ℕ} {.`ℕ} <:-nat <:-nat = <:-nat
|
||||
<:-trans {{ ls ⦂ As }{d1} } {{ ms ⦂ Bs } {d2} } {{ ns ⦂ Cs } {d3} }
|
||||
(<:-rcd ms⊆ls As<:Bs) (<:-rcd ns⊆ms Bs<:Cs) =
|
||||
<:-rcd (⊆-trans ns⊆ms ms⊆ls) G
|
||||
where
|
||||
G : ls ⦂ As <: ns ⦂ Cs
|
||||
G {i}{j} lij
|
||||
with lookup-⊆ {i = i} ns⊆ms
|
||||
... | ⟨ k , lik ⟩
|
||||
with lookup-⊆ {i = k} ms⊆ls
|
||||
... | ⟨ j' , lkj' ⟩ rewrite sym lkj' | lij | sym lik =
|
||||
let ab = As<:Bs {k}{j} (trans lij lik) in
|
||||
let bc = Bs<:Cs {i}{k} (sym lik) in
|
||||
<:-trans ab bc
|
||||
```
|
||||
|
||||
## Contexts
|
||||
|
||||
```
|
||||
data Context : Set where
|
||||
∅ : Context
|
||||
_,_ : Context → Type → Context
|
||||
```
|
||||
|
||||
## Variables and the lookup judgment
|
||||
|
||||
```
|
||||
data _∋_⦂_ : Context → ℕ → Type → Set where
|
||||
|
||||
Z : ∀ {Γ A}
|
||||
------------------
|
||||
→ Γ , A ∋ 0 ⦂ A
|
||||
|
||||
S : ∀ {Γ x A B}
|
||||
→ Γ ∋ x ⦂ A
|
||||
------------------
|
||||
→ Γ , B ∋ (suc x) ⦂ A
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Terms and the typing judgment
|
||||
|
||||
```
|
||||
Id : Set
|
||||
Id = ℕ
|
||||
|
||||
data Term : Set where
|
||||
`_ : Id → Term
|
||||
ƛ_ : Term → Term
|
||||
_·_ : Term → Term → Term
|
||||
`zero : Term
|
||||
`suc_ : Term → Term
|
||||
case_[zero⇒_|suc⇒_] : Term → Term → Term → Term
|
||||
μ_ : Term → Term
|
||||
{_:=_} : {n : ℕ} (ls : Vec Name n) (Ms : Vec Term n) → Term
|
||||
_#_ : Term → Name → Term
|
||||
```
|
||||
|
||||
```
|
||||
data _⊢*_⦂_ : Context → ∀ {n} → Vec Term n → Vec Type n → Set
|
||||
|
||||
data _⊢_⦂_ : Context → Term → Type → Set where
|
||||
|
||||
⊢` : ∀ {Γ x A}
|
||||
→ Γ ∋ x ⦂ A
|
||||
-----------
|
||||
→ Γ ⊢ ` x ⦂ A
|
||||
|
||||
⊢ƛ : ∀ {Γ A B N}
|
||||
→ (Γ , A) ⊢ N ⦂ B
|
||||
---------------
|
||||
→ Γ ⊢ (ƛ N) ⦂ A ⇒ B
|
||||
|
||||
⊢· : ∀ {Γ A B L M}
|
||||
→ Γ ⊢ L ⦂ A ⇒ B
|
||||
→ Γ ⊢ M ⦂ A
|
||||
-------------
|
||||
→ Γ ⊢ L · M ⦂ B
|
||||
|
||||
⊢zero : ∀ {Γ}
|
||||
--------------
|
||||
→ Γ ⊢ `zero ⦂ `ℕ
|
||||
|
||||
⊢suc : ∀ {Γ M}
|
||||
→ Γ ⊢ M ⦂ `ℕ
|
||||
---------------
|
||||
→ Γ ⊢ `suc M ⦂ `ℕ
|
||||
|
||||
⊢case : ∀ {Γ A L M N}
|
||||
→ Γ ⊢ L ⦂ `ℕ
|
||||
→ Γ ⊢ M ⦂ A
|
||||
→ Γ , `ℕ ⊢ N ⦂ A
|
||||
---------------------------------
|
||||
→ Γ ⊢ case L [zero⇒ M |suc⇒ N ] ⦂ A
|
||||
|
||||
⊢μ : ∀ {Γ A M}
|
||||
→ Γ , A ⊢ M ⦂ A
|
||||
-------------
|
||||
→ Γ ⊢ μ M ⦂ A
|
||||
|
||||
⊢rcd : ∀ {Γ n}{Ms : Vec Term n}{As : Vec Type n}{ls : Vec Name n}
|
||||
→ Γ ⊢* Ms ⦂ As
|
||||
→ (d : distinct ls)
|
||||
→ Γ ⊢ { ls := Ms } ⦂ { ls ⦂ As } {d}
|
||||
|
||||
|
||||
⊢# : ∀ {n : ℕ}{Γ A M l}{ls : Vec Name n}{As : Vec Type n}{i}{d}
|
||||
→ Γ ⊢ M ⦂ { ls ⦂ As }{d}
|
||||
→ lookup ls i ≡ l
|
||||
→ lookup As i ≡ A
|
||||
→ Γ ⊢ M # l ⦂ A
|
||||
|
||||
⊢<: : ∀{Γ M A B}
|
||||
→ Γ ⊢ M ⦂ A → A <: B
|
||||
--------------------
|
||||
→ Γ ⊢ M ⦂ B
|
||||
|
||||
data _⊢*_⦂_ where
|
||||
⊢*-[] : ∀{Γ} → Γ ⊢* [] ⦂ []
|
||||
|
||||
⊢*-∷ : ∀ {n}{Γ M}{Ms : Vec Term n}{A}{As : Vec Type n}
|
||||
→ Γ ⊢ M ⦂ A
|
||||
→ Γ ⊢* Ms ⦂ As
|
||||
→ Γ ⊢* (M ∷ Ms) ⦂ (A ∷ As)
|
||||
```
|
||||
|
||||
|
||||
## Renaming and Substitution
|
||||
|
||||
```
|
||||
ext : (Id → Id) → (Id → Id)
|
||||
ext ρ 0 = 0
|
||||
ext ρ (suc x) = suc (ρ x)
|
||||
```
|
||||
|
||||
```
|
||||
rename-vec : (Id → Id) → ∀{n} → Vec Term n → Vec Term n
|
||||
|
||||
rename : (Id → Id) → (Term → Term)
|
||||
rename ρ (` x) = ` (ρ x)
|
||||
rename ρ (ƛ N) = ƛ (rename (ext ρ) N)
|
||||
rename ρ (L · M) = (rename ρ L) · (rename ρ M)
|
||||
rename ρ (`zero) = `zero
|
||||
rename ρ (`suc M) = `suc (rename ρ M)
|
||||
rename ρ (case L [zero⇒ M |suc⇒ N ]) =
|
||||
case (rename ρ L) [zero⇒ rename ρ M |suc⇒ rename (ext ρ) N ]
|
||||
rename ρ (μ N) = μ (rename (ext ρ) N)
|
||||
rename ρ { ls := Ms } = { ls := rename-vec ρ Ms }
|
||||
rename ρ (M # l) = (rename ρ M) # l
|
||||
|
||||
rename-vec ρ [] = []
|
||||
rename-vec ρ (M ∷ Ms) = rename ρ M ∷ rename-vec ρ Ms
|
||||
```
|
||||
|
||||
```
|
||||
exts : (Id → Term) → (Id → Term)
|
||||
exts σ 0 = ` 0
|
||||
exts σ (suc x) = rename suc (σ x)
|
||||
```
|
||||
|
||||
```
|
||||
subst-vec : (Id → Term) → ∀{n} → Vec Term n → Vec Term n
|
||||
|
||||
subst : (Id → Term) → (Term → Term)
|
||||
subst σ (` k) = σ k
|
||||
subst σ (ƛ N) = ƛ (subst (exts σ) N)
|
||||
subst σ (L · M) = (subst σ L) · (subst σ M)
|
||||
subst σ (`zero) = `zero
|
||||
subst σ (`suc M) = `suc (subst σ M)
|
||||
subst σ (case L [zero⇒ M |suc⇒ N ])
|
||||
= case (subst σ L) [zero⇒ subst σ M |suc⇒ subst (exts σ) N ]
|
||||
subst σ (μ N) = μ (subst (exts σ) N)
|
||||
subst σ { ls := Ms } = { ls := subst-vec σ Ms }
|
||||
subst σ (M # l) = (subst σ M) # l
|
||||
|
||||
subst-vec σ [] = []
|
||||
subst-vec σ (M ∷ Ms) = (subst σ M) ∷ (subst-vec σ Ms)
|
||||
```
|
||||
|
||||
```
|
||||
subst-zero : Term → Id → Term
|
||||
subst-zero M 0 = M
|
||||
subst-zero M (suc x) = ` x
|
||||
|
||||
_[_] : Term → Term → Term
|
||||
_[_] N M = subst (subst-zero M) N
|
||||
```
|
||||
|
||||
## Values
|
||||
|
||||
```
|
||||
data Value : Term → Set where
|
||||
|
||||
V-ƛ : ∀ {N}
|
||||
-----------
|
||||
→ Value (ƛ N)
|
||||
|
||||
V-zero :
|
||||
-------------
|
||||
Value (`zero)
|
||||
|
||||
V-suc : ∀ {V}
|
||||
→ Value V
|
||||
--------------
|
||||
→ Value (`suc V)
|
||||
|
||||
V-rcd : ∀{n}{ls : Vec Name n}{Ms : Vec Term n}
|
||||
→ Value { ls := Ms }
|
||||
```
|
||||
|
||||
## Reduction
|
||||
|
||||
```
|
||||
infix 2 _—→_
|
||||
|
||||
data _—→_ : Term → Term → Set where
|
||||
|
||||
ξ-·₁ : ∀ {L L′ M : Term}
|
||||
→ L —→ L′
|
||||
---------------
|
||||
→ L · M —→ L′ · M
|
||||
|
||||
ξ-·₂ : ∀ {V M M′ : Term}
|
||||
→ Value V
|
||||
→ M —→ M′
|
||||
---------------
|
||||
→ V · M —→ V · M′
|
||||
|
||||
β-ƛ : ∀ {N W : Term}
|
||||
→ Value W
|
||||
--------------------
|
||||
→ (ƛ N) · W —→ N [ W ]
|
||||
|
||||
ξ-suc : ∀ {M M′ : Term}
|
||||
→ M —→ M′
|
||||
-----------------
|
||||
→ `suc M —→ `suc M′
|
||||
|
||||
ξ-case : ∀ {L L′ M N : Term}
|
||||
→ L —→ L′
|
||||
-------------------------------------------------------
|
||||
→ case L [zero⇒ M |suc⇒ N ] —→ case L′ [zero⇒ M |suc⇒ N ]
|
||||
|
||||
β-zero : ∀ {M N : Term}
|
||||
----------------------------------
|
||||
→ case `zero [zero⇒ M |suc⇒ N ] —→ M
|
||||
|
||||
β-suc : ∀ {V M N : Term}
|
||||
→ Value V
|
||||
-------------------------------------------
|
||||
→ case (`suc V) [zero⇒ M |suc⇒ N ] —→ N [ V ]
|
||||
|
||||
β-μ : ∀ {N : Term}
|
||||
----------------
|
||||
→ μ N —→ N [ μ N ]
|
||||
|
||||
ξ-# : ∀ {M M′ : Term}{l}
|
||||
→ M —→ M′
|
||||
→ M # l —→ M′ # l
|
||||
|
||||
β-# : ∀ {n}{ls : Vec Name n}{vs : Vec Term n} {lⱼ}{j : Fin n}
|
||||
→ lookup ls j ≡ lⱼ
|
||||
---------------------------------
|
||||
→ { ls := vs } # lⱼ —→ lookup vs j
|
||||
|
||||
|
||||
```
|
||||
|
||||
## Canonical Forms
|
||||
|
||||
```
|
||||
infix 4 Canonical_⦂_
|
||||
|
||||
data Canonical_⦂_ : Term → Type → Set where
|
||||
|
||||
C-ƛ : ∀ {N A B C D}
|
||||
→ ∅ , A ⊢ N ⦂ B
|
||||
→ A ⇒ B <: C ⇒ D
|
||||
-------------------------
|
||||
→ Canonical (ƛ N) ⦂ (C ⇒ D)
|
||||
|
||||
C-zero :
|
||||
--------------------
|
||||
Canonical `zero ⦂ `ℕ
|
||||
|
||||
C-suc : ∀ {V}
|
||||
→ Canonical V ⦂ `ℕ
|
||||
---------------------
|
||||
→ Canonical `suc V ⦂ `ℕ
|
||||
|
||||
C-rcd : ∀{n m}{ls : Vec Name n}{ks : Vec Name m}{Ms As Bs}{dls}
|
||||
→ ∅ ⊢* Ms ⦂ As
|
||||
→ (dks : distinct ks)
|
||||
→ { ks ⦂ As }{dks} <: { ls ⦂ Bs }{dls}
|
||||
→ Canonical { ks := Ms } ⦂ { ls ⦂ Bs } {dls}
|
||||
```
|
||||
|
||||
Every closed, well-typed value is canonical:
|
||||
```
|
||||
canonical : ∀ {V A}
|
||||
→ ∅ ⊢ V ⦂ A
|
||||
→ Value V
|
||||
-----------
|
||||
→ Canonical V ⦂ A
|
||||
canonical (⊢` ()) ()
|
||||
canonical (⊢ƛ ⊢N) V-ƛ = C-ƛ ⊢N <:-refl
|
||||
canonical (⊢· ⊢L ⊢M) ()
|
||||
canonical ⊢zero V-zero = C-zero
|
||||
canonical (⊢suc ⊢V) (V-suc VV) = C-suc (canonical ⊢V VV)
|
||||
canonical (⊢case ⊢L ⊢M ⊢N) ()
|
||||
canonical (⊢μ ⊢M) ()
|
||||
canonical (⊢rcd ⊢Ms d) VV = C-rcd {dls = d} ⊢Ms d <:-refl
|
||||
canonical (⊢<: ⊢M <:-nat) VV = canonical ⊢M VV
|
||||
canonical (⊢<: ⊢M (<:-fun A<:B A<:B₁)) VV
|
||||
with canonical ⊢M VV
|
||||
... | C-ƛ ⊢N AB<:CD = C-ƛ ⊢N (<:-trans AB<:CD (<:-fun A<:B A<:B₁))
|
||||
canonical (⊢<: ⊢M (<:-rcd {d2 = dls} ls⊆ks ls⦂Ss<:ks⦂Ts)) VV
|
||||
with canonical ⊢M VV
|
||||
... | C-rcd {dls = d} ⊢Ms dks As<:Ss =
|
||||
C-rcd {dls = distinct-relevant dls} ⊢Ms dks (<:-trans As<:Ss (<:-rcd ls⊆ks ls⦂Ss<:ks⦂Ts))
|
||||
```
|
||||
|
||||
```
|
||||
value : ∀ {M A}
|
||||
→ Canonical M ⦂ A
|
||||
----------------
|
||||
→ Value M
|
||||
value (C-ƛ _ _) = V-ƛ
|
||||
value C-zero = V-zero
|
||||
value (C-suc CM) = V-suc (value CM)
|
||||
value (C-rcd _ _ _) = V-rcd
|
||||
```
|
||||
|
||||
```
|
||||
typed : ∀ {M A}
|
||||
→ Canonical M ⦂ A
|
||||
---------------
|
||||
→ ∅ ⊢ M ⦂ A
|
||||
typed (C-ƛ ⊢N AB<:CD) = ⊢<: (⊢ƛ ⊢N) AB<:CD
|
||||
typed C-zero = ⊢zero
|
||||
typed (C-suc c) = ⊢suc (typed c)
|
||||
typed (C-rcd ⊢Ms dks As<:Bs) = ⊢<: (⊢rcd ⊢Ms dks) As<:Bs
|
||||
```
|
||||
|
||||
## Progress
|
||||
|
||||
```
|
||||
data Progress (M : Term) : Set where
|
||||
|
||||
step : ∀ {N}
|
||||
→ M —→ N
|
||||
----------
|
||||
→ Progress M
|
||||
|
||||
done :
|
||||
Value M
|
||||
----------
|
||||
→ Progress M
|
||||
```
|
||||
|
||||
```
|
||||
progress : ∀ {M A}
|
||||
→ ∅ ⊢ M ⦂ A
|
||||
----------
|
||||
→ Progress M
|
||||
progress (⊢` ())
|
||||
progress (⊢ƛ ⊢N) = done V-ƛ
|
||||
progress (⊢· ⊢L ⊢M)
|
||||
with progress ⊢L
|
||||
... | step L—→L′ = step (ξ-·₁ L—→L′)
|
||||
... | done VL
|
||||
with progress ⊢M
|
||||
... | step M—→M′ = step (ξ-·₂ VL M—→M′)
|
||||
... | done VM
|
||||
with canonical ⊢L VL
|
||||
... | C-ƛ ⊢N _ = step (β-ƛ VM)
|
||||
progress ⊢zero = done V-zero
|
||||
progress (⊢suc ⊢M) with progress ⊢M
|
||||
... | step M—→M′ = step (ξ-suc M—→M′)
|
||||
... | done VM = done (V-suc VM)
|
||||
progress (⊢case ⊢L ⊢M ⊢N) with progress ⊢L
|
||||
... | step L—→L′ = step (ξ-case L—→L′)
|
||||
... | done VL with canonical ⊢L VL
|
||||
... | C-zero = step β-zero
|
||||
... | C-suc CL = step (β-suc (value CL))
|
||||
progress (⊢μ ⊢M) = step β-μ
|
||||
progress (⊢# {Γ}{A}{M}{n}{fs}{As}{d}{i}{f} ⊢R lif liA)
|
||||
with progress ⊢R
|
||||
... | step R—→R′ = step (ξ-# R—→R′)
|
||||
... | done VR
|
||||
with canonical ⊢R VR
|
||||
... | C-rcd ⊢Ms dks (<:-rcd fs⊆fs' _)
|
||||
with lookup-⊆ {i = i} fs⊆fs'
|
||||
... | ⟨ k , eq ⟩ rewrite eq = step (β-# {j = k} lif)
|
||||
progress (⊢rcd x d) = done V-rcd
|
||||
progress (⊢<: {A = A}{B} ⊢M A<:B) = progress ⊢M
|
||||
```
|
||||
|
||||
|
||||
## Preservation
|
||||
|
||||
|
||||
```
|
||||
_⦂ᵣ_⇒_ : (Id → Id) → Context → Context → Set
|
||||
ρ ⦂ᵣ Γ ⇒ Δ = ∀ {x A} → Γ ∋ x ⦂ A → Δ ∋ ρ x ⦂ A
|
||||
```
|
||||
|
||||
```
|
||||
ext-pres : ∀ {Γ Δ ρ B}
|
||||
→ ρ ⦂ᵣ Γ ⇒ Δ
|
||||
--------------------------------
|
||||
→ ext ρ ⦂ᵣ (Γ , B) ⇒ (Δ , B)
|
||||
ext-pres {ρ = ρ } ρ⦂ Z = Z
|
||||
ext-pres {ρ = ρ } ρ⦂ (S {x = x} ∋x) = S (ρ⦂ ∋x)
|
||||
```
|
||||
|
||||
```
|
||||
ren-vec-pres : ∀ {Γ Δ ρ}{n}{Ms : Vec Term n}{As : Vec Type n}
|
||||
→ ρ ⦂ᵣ Γ ⇒ Δ
|
||||
→ Γ ⊢* Ms ⦂ As
|
||||
---------------------
|
||||
→ Δ ⊢* rename-vec ρ Ms ⦂ As
|
||||
|
||||
rename-pres : ∀ {Γ Δ ρ M A}
|
||||
→ ρ ⦂ᵣ Γ ⇒ Δ
|
||||
→ Γ ⊢ M ⦂ A
|
||||
------------------
|
||||
→ Δ ⊢ rename ρ M ⦂ A
|
||||
rename-pres ρ⦂ (⊢` ∋w) = ⊢` (ρ⦂ ∋w)
|
||||
rename-pres {ρ = ρ} ρ⦂ (⊢ƛ ⊢N) = ⊢ƛ (rename-pres {ρ = ext ρ} (ext-pres {ρ = ρ} ρ⦂) ⊢N)
|
||||
rename-pres {ρ = ρ} ρ⦂ (⊢· ⊢L ⊢M)= ⊢· (rename-pres {ρ = ρ} ρ⦂ ⊢L) (rename-pres {ρ = ρ} ρ⦂ ⊢M)
|
||||
rename-pres {ρ = ρ} ρ⦂ (⊢μ ⊢M) = ⊢μ (rename-pres {ρ = ext ρ} (ext-pres {ρ = ρ} ρ⦂) ⊢M)
|
||||
rename-pres ρ⦂ (⊢rcd ⊢Ms dfs) = ⊢rcd (ren-vec-pres ρ⦂ ⊢Ms ) dfs
|
||||
rename-pres {ρ = ρ} ρ⦂ (⊢# {d = d} ⊢R lif liA) = ⊢# {d = d}(rename-pres {ρ = ρ} ρ⦂ ⊢R) lif liA
|
||||
rename-pres {ρ = ρ} ρ⦂ (⊢<: ⊢M lt) = ⊢<: (rename-pres {ρ = ρ} ρ⦂ ⊢M) lt
|
||||
rename-pres ρ⦂ ⊢zero = ⊢zero
|
||||
rename-pres ρ⦂ (⊢suc ⊢M) = ⊢suc (rename-pres ρ⦂ ⊢M)
|
||||
rename-pres ρ⦂ (⊢case ⊢L ⊢M ⊢N) =
|
||||
⊢case (rename-pres ρ⦂ ⊢L) (rename-pres ρ⦂ ⊢M) (rename-pres (ext-pres ρ⦂) ⊢N)
|
||||
|
||||
ren-vec-pres ρ⦂ ⊢*-[] = ⊢*-[]
|
||||
ren-vec-pres {ρ = ρ} ρ⦂ (⊢*-∷ ⊢M ⊢Ms) =
|
||||
let IH = ren-vec-pres {ρ = ρ} ρ⦂ ⊢Ms in
|
||||
⊢*-∷ (rename-pres {ρ = ρ} ρ⦂ ⊢M) IH
|
||||
```
|
||||
|
||||
```
|
||||
_⦂_⇒_ : (Id → Term) → Context → Context → Set
|
||||
σ ⦂ Γ ⇒ Δ = ∀ {A x} → Γ ∋ x ⦂ A → Δ ⊢ subst σ (` x) ⦂ A
|
||||
```
|
||||
|
||||
```
|
||||
exts-pres : ∀ {Γ Δ σ B}
|
||||
→ σ ⦂ Γ ⇒ Δ
|
||||
--------------------------------
|
||||
→ exts σ ⦂ (Γ , B) ⇒ (Δ , B)
|
||||
exts-pres {σ = σ} σ⦂ Z = ⊢` Z
|
||||
exts-pres {σ = σ} σ⦂ (S {x = x} ∋x) = rename-pres {ρ = suc} S (σ⦂ ∋x)
|
||||
```
|
||||
|
||||
|
||||
```
|
||||
subst-vec-pres : ∀ {Γ Δ σ}{n}{Ms : Vec Term n}{A}
|
||||
→ σ ⦂ Γ ⇒ Δ
|
||||
→ Γ ⊢* Ms ⦂ A
|
||||
-----------------
|
||||
→ Δ ⊢* subst-vec σ Ms ⦂ A
|
||||
|
||||
subst-pres : ∀ {Γ Δ σ N A}
|
||||
→ σ ⦂ Γ ⇒ Δ
|
||||
→ Γ ⊢ N ⦂ A
|
||||
-----------------
|
||||
→ Δ ⊢ subst σ N ⦂ A
|
||||
subst-pres σ⦂ (⊢` eq) = σ⦂ eq
|
||||
subst-pres {σ = σ} σ⦂ (⊢ƛ ⊢N) = ⊢ƛ (subst-pres{σ = exts σ}(exts-pres {σ = σ} σ⦂) ⊢N)
|
||||
subst-pres {σ = σ} σ⦂ (⊢· ⊢L ⊢M) = ⊢· (subst-pres{σ = σ} σ⦂ ⊢L) (subst-pres{σ = σ} σ⦂ ⊢M)
|
||||
subst-pres {σ = σ} σ⦂ (⊢μ ⊢M) = ⊢μ (subst-pres{σ = exts σ} (exts-pres{σ = σ} σ⦂) ⊢M)
|
||||
subst-pres σ⦂ (⊢rcd ⊢Ms dfs) = ⊢rcd (subst-vec-pres σ⦂ ⊢Ms ) dfs
|
||||
subst-pres {σ = σ} σ⦂ (⊢# {d = d} ⊢R lif liA) =
|
||||
⊢# {d = d} (subst-pres {σ = σ} σ⦂ ⊢R) lif liA
|
||||
subst-pres {σ = σ} σ⦂ (⊢<: ⊢N lt) = ⊢<: (subst-pres {σ = σ} σ⦂ ⊢N) lt
|
||||
subst-pres σ⦂ ⊢zero = ⊢zero
|
||||
subst-pres σ⦂ (⊢suc ⊢M) = ⊢suc (subst-pres σ⦂ ⊢M)
|
||||
subst-pres σ⦂ (⊢case ⊢L ⊢M ⊢N) =
|
||||
⊢case (subst-pres σ⦂ ⊢L) (subst-pres σ⦂ ⊢M) (subst-pres (exts-pres σ⦂) ⊢N)
|
||||
|
||||
subst-vec-pres σ⦂ ⊢*-[] = ⊢*-[]
|
||||
subst-vec-pres {σ = σ} σ⦂ (⊢*-∷ ⊢M ⊢Ms) =
|
||||
⊢*-∷ (subst-pres {σ = σ} σ⦂ ⊢M) (subst-vec-pres σ⦂ ⊢Ms)
|
||||
```
|
||||
|
||||
```
|
||||
substitution : ∀{Γ A B M N}
|
||||
→ Γ ⊢ M ⦂ A
|
||||
→ (Γ , A) ⊢ N ⦂ B
|
||||
---------------
|
||||
→ Γ ⊢ N [ M ] ⦂ B
|
||||
substitution {Γ}{A}{B}{M}{N} ⊢M ⊢N = subst-pres {σ = subst-zero M} G ⊢N
|
||||
where
|
||||
G : ∀ {C : Type} {x : ℕ}
|
||||
→ (Γ , A) ∋ x ⦂ C → Γ ⊢ subst (subst-zero M) (` x) ⦂ C
|
||||
G {C} {zero} Z = ⊢M
|
||||
G {C} {suc x} (S ∋x) = ⊢` ∋x
|
||||
```
|
||||
|
||||
```
|
||||
field-pres : ∀{n}{As : Vec Type n}{A}{Ms : Vec Term n}{i : Fin n}
|
||||
→ ∅ ⊢* Ms ⦂ As
|
||||
→ lookup As i ≡ A
|
||||
→ ∅ ⊢ lookup Ms i ⦂ A
|
||||
field-pres {i = zero} (⊢*-∷ ⊢M ⊢Ms) refl = ⊢M
|
||||
field-pres {i = suc i} (⊢*-∷ ⊢M ⊢Ms) As[i]=A = field-pres ⊢Ms As[i]=A
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
preserve : ∀ {M N A}
|
||||
→ ∅ ⊢ M ⦂ A
|
||||
→ M —→ N
|
||||
----------
|
||||
→ ∅ ⊢ N ⦂ A
|
||||
preserve (⊢` ())
|
||||
preserve (⊢ƛ ⊢N) ()
|
||||
preserve (⊢· ⊢L ⊢M) (ξ-·₁ L—→L′) = ⊢· (preserve ⊢L L—→L′) ⊢M
|
||||
preserve (⊢· ⊢L ⊢M) (ξ-·₂ VL M—→M′) = ⊢· ⊢L (preserve ⊢M M—→M′)
|
||||
preserve (⊢· ⊢L ⊢M) (β-ƛ VL)
|
||||
with canonical ⊢L V-ƛ
|
||||
... | C-ƛ ⊢N (<:-fun CA BC) = ⊢<: (substitution (⊢<: ⊢M CA) ⊢N) BC
|
||||
preserve ⊢zero ()
|
||||
preserve (⊢suc ⊢M) (ξ-suc M—→M′) = ⊢suc (preserve ⊢M M—→M′)
|
||||
preserve (⊢case ⊢L ⊢M ⊢N) (ξ-case L—→L′) = ⊢case (preserve ⊢L L—→L′) ⊢M ⊢N
|
||||
preserve (⊢case ⊢L ⊢M ⊢N) (β-zero) = ⊢M
|
||||
preserve (⊢case ⊢L ⊢M ⊢N) (β-suc VV)
|
||||
with canonical ⊢L (V-suc VV)
|
||||
... | C-suc CV = substitution (typed CV) ⊢N
|
||||
preserve (⊢μ ⊢M) (β-μ) = substitution (⊢μ ⊢M) ⊢M
|
||||
preserve (⊢# {d = d} ⊢M lsi Asi) (ξ-# M—→M′) = ⊢# {d = d} (preserve ⊢M M—→M′) lsi Asi
|
||||
preserve (⊢# {ls = ls′}{i = i} ⊢M refl refl) (β-# {ls = ks}{Ms}{j = j} ks[j]=l)
|
||||
with canonical ⊢M V-rcd
|
||||
... | C-rcd ⊢Ms dks (<:-rcd {ks = ks}{ls} ls⊆ks As<:Bs)
|
||||
with lookup-⊆ {i = i} ls⊆ks
|
||||
... | ⟨ k , ls′[i]=ks[k] ⟩
|
||||
with field-pres {i = k} ⊢Ms refl
|
||||
... | ⊢Ms[k]
|
||||
rewrite distinct-lookup-inj dks (trans ks[j]=l ls′[i]=ks[k]) =
|
||||
⊢<: ⊢Ms[k] (As<:Bs (sym ls′[i]=ks[k]))
|
||||
preserve (⊢<: ⊢M A<:B) M—→N = ⊢<: (preserve ⊢M M—→N) A<:B
|
||||
```
|
Loading…
Reference in a new issue