completed More
This commit is contained in:
parent
6f446bcec7
commit
6f7d009bd4
3 changed files with 198 additions and 89 deletions
|
@ -18,6 +18,13 @@ inherently typed. Our new presentation is more compact, using
|
||||||
less than half the lines of code required previously to do
|
less than half the lines of code required previously to do
|
||||||
cover the same ground.
|
cover the same ground.
|
||||||
|
|
||||||
|
The inherently typed representation was first proposed by
|
||||||
|
Thorsten Altenkirch and Bernhard Reus.
|
||||||
|
The formalisation of renaming and substitution
|
||||||
|
we use is due to Conor McBride.
|
||||||
|
Related work has been carried out by
|
||||||
|
James Chapman, James McKinna, and many others.
|
||||||
|
|
||||||
## Imports
|
## Imports
|
||||||
|
|
||||||
\begin{code}
|
\begin{code}
|
||||||
|
@ -185,42 +192,12 @@ shadowing: with variable names, there is no way to refer to
|
||||||
the former binding in the scope of the latter, but with de
|
the former binding in the scope of the latter, but with de
|
||||||
Bruijn indices it could be referred to as `# 2`.
|
Bruijn indices it could be referred to as `# 2`.
|
||||||
|
|
||||||
|
|
||||||
## Order of presentation
|
## Order of presentation
|
||||||
|
|
||||||
The presentation in the previous two chapters was ordered as
|
|
||||||
follows, where the first chapter introduces raw terms, and the
|
|
||||||
second proves their properties.
|
|
||||||
|
|
||||||
* Lambda: Introduction to Lambda Calculus
|
|
||||||
+ 1.1 Syntax
|
|
||||||
+ 1.2 Values
|
|
||||||
+ 1.3 Substitution
|
|
||||||
+ 1.4 Reduction
|
|
||||||
+ 1.5 Typing
|
|
||||||
* Properties: Progress and Preservation
|
|
||||||
+ 2.1 Canonical forms lemma
|
|
||||||
+ 2.2 Progress
|
|
||||||
+ 2.3 Renaming lemma
|
|
||||||
+ 2.4 Substitution preserves types
|
|
||||||
+ 2.5 Preservation
|
|
||||||
+ 2.6 Evaluation
|
|
||||||
|
|
||||||
In the current chapter, the use of inherently-typed terms
|
In the current chapter, the use of inherently-typed terms
|
||||||
necessitates that we cannot introduce operations such as
|
necessitates that we cannot introduce operations such as
|
||||||
substitution or reduction without also showing that they
|
substitution or reduction without also showing that they
|
||||||
preserve types. Hence, the order of presentation must change.
|
preserve types. Hence, the order of presentation must change.
|
||||||
For each new section, we show the corresponding old section or
|
|
||||||
sections.
|
|
||||||
|
|
||||||
* DeBruijn: Inherently typed de Bruijn representation
|
|
||||||
+ Syntax (1.1, 1.5)
|
|
||||||
+ Values (1.2, 2.1)
|
|
||||||
+ Renaming (2.3)
|
|
||||||
+ Substitution (1.3, 2.3)
|
|
||||||
+ Reduction (1.3, 2.4)
|
|
||||||
+ Progress (2.2)
|
|
||||||
+ Evaluation (2.6)
|
|
||||||
|
|
||||||
The syntax of terms now incorporates their typing rules, and the
|
The syntax of terms now incorporates their typing rules, and the
|
||||||
definition of values now incorporates the Canonical Forms lemma. The
|
definition of values now incorporates the Canonical Forms lemma. The
|
||||||
|
@ -505,19 +482,7 @@ As before we generalise everything save `2+2ᶜ` to arbitary
|
||||||
contexts. While we are at it, we also generalise `twoᶜ` and
|
contexts. While we are at it, we also generalise `twoᶜ` and
|
||||||
`plusᶜ` to Church numerals over arbitrary types.
|
`plusᶜ` to Church numerals over arbitrary types.
|
||||||
|
|
||||||
## Substitution
|
## Renaming
|
||||||
|
|
||||||
With terms in hand, we turn to substitution.
|
|
||||||
Whereas before we had to restrict our
|
|
||||||
attention to substituting only one variable at a time and
|
|
||||||
could only substitute closed terms, here we can consider
|
|
||||||
simultaneous subsitution of open terms. The
|
|
||||||
definition of substitution we consider is due to Conor
|
|
||||||
McBride. Whereas before we defined substitution in one
|
|
||||||
chapter and showed it preserved types in the next chapter,
|
|
||||||
here we write code that does both at once.
|
|
||||||
|
|
||||||
### Renaming
|
|
||||||
|
|
||||||
Renaming is a necessary prelude to substitution, enabling us
|
Renaming is a necessary prelude to substitution, enabling us
|
||||||
to "rebase" a term from one context to another. It
|
to "rebase" a term from one context to another. It
|
||||||
|
@ -620,7 +585,7 @@ typing, and hence the Agda code for inherently-typed de Bruijn
|
||||||
terms is inherently reliable.
|
terms is inherently reliable.
|
||||||
|
|
||||||
|
|
||||||
### Simultaneous Substitution
|
## Simultaneous Substitution
|
||||||
|
|
||||||
Because de Bruijn indices free us of concerns with renaming,
|
Because de Bruijn indices free us of concerns with renaming,
|
||||||
it becomes easy to provide a definition of substitution that
|
it becomes easy to provide a definition of substitution that
|
||||||
|
@ -695,7 +660,7 @@ The remaining cases are similar, recursing on each subterm,
|
||||||
and extending the map whenever the construct introduces a
|
and extending the map whenever the construct introduces a
|
||||||
bound variable.
|
bound variable.
|
||||||
|
|
||||||
### Single substitution
|
## Single substitution
|
||||||
|
|
||||||
From the general case of substitution for multiple free
|
From the general case of substitution for multiple free
|
||||||
variables in is easy to define the special case of
|
variables in is easy to define the special case of
|
||||||
|
@ -773,12 +738,7 @@ And combining definition with proof makes it harder for errors
|
||||||
to sneak in.
|
to sneak in.
|
||||||
|
|
||||||
|
|
||||||
## Reduction
|
## Values
|
||||||
|
|
||||||
With substitution out of the way, it is straightforward to
|
|
||||||
define values and reduction.
|
|
||||||
|
|
||||||
### Value
|
|
||||||
|
|
||||||
The definition of value is much as before, save that the
|
The definition of value is much as before, save that the
|
||||||
added types incorporate the same information found in the
|
added types incorporate the same information found in the
|
||||||
|
@ -804,7 +764,8 @@ Here `zero` requires an implicit parameter to aid inference,
|
||||||
much in the same way that `[]` did in
|
much in the same way that `[]` did in
|
||||||
[Lists]({{ site.baseurl }}{% link out/plfa/Lists.md %})).
|
[Lists]({{ site.baseurl }}{% link out/plfa/Lists.md %})).
|
||||||
|
|
||||||
### Reduction step
|
|
||||||
|
## Reduction
|
||||||
|
|
||||||
The reduction rules are the same as those given earlier, save
|
The reduction rules are the same as those given earlier, save
|
||||||
that for each term we must specify its types. As before, we
|
that for each term we must specify its types. As before, we
|
||||||
|
@ -867,7 +828,7 @@ preserves types, which we previously is built-in to our
|
||||||
definition of substitution.
|
definition of substitution.
|
||||||
|
|
||||||
|
|
||||||
### Reflexive and transitive closure
|
## Reflexive and transitive closure
|
||||||
|
|
||||||
The reflexive and transitive closure is exactly as before.
|
The reflexive and transitive closure is exactly as before.
|
||||||
We simply cut-and-paste the previous definition.
|
We simply cut-and-paste the previous definition.
|
||||||
|
|
|
@ -12,6 +12,7 @@ So far, we have focussed on a relatively minimal language, based on
|
||||||
Plotkin's PCF, which supports functions, naturals, and fixpoints. In
|
Plotkin's PCF, which supports functions, naturals, and fixpoints. In
|
||||||
this chapter we extend our calculus to support the following:
|
this chapter we extend our calculus to support the following:
|
||||||
|
|
||||||
|
* primitive numbers
|
||||||
* _let_ bindings
|
* _let_ bindings
|
||||||
* products
|
* products
|
||||||
* an alternative formulation of products
|
* an alternative formulation of products
|
||||||
|
@ -24,7 +25,7 @@ this chapter we extend our calculus to support the following:
|
||||||
All of the data types should be familiar from Part I of this textbook.
|
All of the data types should be familiar from Part I of this textbook.
|
||||||
For _let_ and the alternative formulations we show how they translate
|
For _let_ and the alternative formulations we show how they translate
|
||||||
to other constructs in the calculus. Most of the description will be
|
to other constructs in the calculus. Most of the description will be
|
||||||
informal. We show how to formalise the first three constructs and leave
|
informal. We show how to formalise the first four constructs and leave
|
||||||
the rest as an exercise for the reader.
|
the rest as an exercise for the reader.
|
||||||
|
|
||||||
Our informal descriptions will be in the style of
|
Our informal descriptions will be in the style of
|
||||||
|
@ -40,6 +41,58 @@ For each construct, we give syntax, typing, reductions, and an example.
|
||||||
We also give translations where relevant; formally establishing the
|
We also give translations where relevant; formally establishing the
|
||||||
correctness of translations will be the subject of the next chapter.
|
correctness of translations will be the subject of the next chapter.
|
||||||
|
|
||||||
|
## Primitive numbers
|
||||||
|
|
||||||
|
We define a `Num` type equivalent to the built-in natural number type
|
||||||
|
with multiplication as a primitive operation on numbers.
|
||||||
|
|
||||||
|
### Syntax
|
||||||
|
|
||||||
|
L, M, N ::= ... Terms
|
||||||
|
con c constant
|
||||||
|
L `* M multiplication
|
||||||
|
|
||||||
|
### Typing
|
||||||
|
|
||||||
|
The hypothesis of the `con` rule is unusual, in that
|
||||||
|
it refers to a typing judgement of Agda rather than a
|
||||||
|
typing judgement of the defined calculus.
|
||||||
|
|
||||||
|
c : ℕ
|
||||||
|
--------------- con
|
||||||
|
Γ ⊢ con c : Nat
|
||||||
|
|
||||||
|
Γ ⊢ L : Nat
|
||||||
|
Γ ⊢ M : Nat
|
||||||
|
---------------- _`*_
|
||||||
|
Γ ⊢ L `* M : Nat
|
||||||
|
|
||||||
|
### Reduction
|
||||||
|
|
||||||
|
A rule that defines a primitive directly, such as the last rule below,
|
||||||
|
is called a δ rule. Here the δ rule defines multiplication of
|
||||||
|
primitive numbers in terms of multiplication of naturals as given
|
||||||
|
by the Agda standard prelude.
|
||||||
|
|
||||||
|
L —→ L′
|
||||||
|
----------------- ξ-*₁
|
||||||
|
L `* M —→ L′ `* M
|
||||||
|
|
||||||
|
M —→ M′
|
||||||
|
----------------- ξ-*₂
|
||||||
|
V `* M —→ V `* M′
|
||||||
|
|
||||||
|
----------------------------- δ-*
|
||||||
|
con c `* con d —→ con (c * d)
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
Here is a function to cube a primitive number.
|
||||||
|
|
||||||
|
cube : ∅ ⊢ Nat ⇒ Nat
|
||||||
|
cube = ƛ x ⇒ x `* x `* x
|
||||||
|
|
||||||
|
|
||||||
## Let bindings
|
## Let bindings
|
||||||
|
|
||||||
Let bindings affect only the syntax of terms; they introduce no new
|
Let bindings affect only the syntax of terms; they introduce no new
|
||||||
|
@ -68,15 +121,13 @@ types or values.
|
||||||
|
|
||||||
### Example
|
### Example
|
||||||
|
|
||||||
Let _`*_ : ∅ ⊢ `ℕ ⇒ `ℕ ⇒ `ℕ represent multiplication of naturals.
|
Here is a function to raise a primitive number to the tenth power.
|
||||||
Then raising a natural to the tenth power can be defined as follows.
|
|
||||||
|
|
||||||
exp10 : ∅ ⊢ `ℕ ⇒ `ℕ
|
exp10 : ∅ ⊢ Nat ⇒ Nat
|
||||||
exp10 = ƛ x ⇒ `let x2 `= x `* x `in
|
exp10 = ƛ x ⇒ `let x2 `= x `* x `in
|
||||||
`let x4 `= x2 `* x2 `in
|
`let x4 `= x2 `* x2 `in
|
||||||
`let x5 `= x4 `* x `in
|
`let x5 `= x4 `* x `in
|
||||||
`let x10 `= x5 `* x5 `in
|
x5 `* x5
|
||||||
x10
|
|
||||||
|
|
||||||
### Translation
|
### Translation
|
||||||
|
|
||||||
|
@ -141,7 +192,7 @@ We can translate each _let_ term into an application of an abstraction.
|
||||||
|
|
||||||
### Example
|
### Example
|
||||||
|
|
||||||
Here is the definition of a function to swap the components of a pair.
|
Here is a function to swap the components of a pair.
|
||||||
|
|
||||||
swap× : ∅ ⊢ A `× B ⇒ B `× A
|
swap× : ∅ ⊢ A `× B ⇒ B `× A
|
||||||
swap× = ƛ z ⇒ `⟨ proj₂ z , proj₁ z ⟩
|
swap× = ƛ z ⇒ `⟨ proj₂ z , proj₁ z ⟩
|
||||||
|
@ -190,7 +241,7 @@ and reduction rules.
|
||||||
|
|
||||||
### Example
|
### Example
|
||||||
|
|
||||||
Function to swap the components of a pair rewritten in the new notation.
|
Here is a function to swap the components of a pair rewritten in the new notation.
|
||||||
|
|
||||||
swap×-case : ∅ ⊢ A `× B ⇒ B `× A
|
swap×-case : ∅ ⊢ A `× B ⇒ B `× A
|
||||||
swap×-case = ƛ z ⇒ case× z
|
swap×-case = ƛ z ⇒ case× z
|
||||||
|
@ -274,7 +325,7 @@ We can also translate back the other way.
|
||||||
|
|
||||||
### Example
|
### Example
|
||||||
|
|
||||||
Here is the definition of a function to swap the components of a sum.
|
Here is a function to swap the components of a sum.
|
||||||
|
|
||||||
swap⊎ : ∅ ⊢ A `⊎ B ⇒ B `⊎ A
|
swap⊎ : ∅ ⊢ A `⊎ B ⇒ B `⊎ A
|
||||||
swap⊎ = ƛ z ⇒ case⊎ z
|
swap⊎ = ƛ z ⇒ case⊎ z
|
||||||
|
@ -496,6 +547,7 @@ Here is the map function for lists.
|
||||||
|
|
||||||
We now show how to formalise
|
We now show how to formalise
|
||||||
|
|
||||||
|
* primitive numbers
|
||||||
* _let_ bindings
|
* _let_ bindings
|
||||||
* products
|
* products
|
||||||
* an alternative formulation of products
|
* an alternative formulation of products
|
||||||
|
@ -509,7 +561,7 @@ and leave formalisation of the remaining constructs as an exercise.
|
||||||
import Relation.Binary.PropositionalEquality as Eq
|
import Relation.Binary.PropositionalEquality as Eq
|
||||||
open Eq using (_≡_; refl; sym; trans; cong)
|
open Eq using (_≡_; refl; sym; trans; cong)
|
||||||
open import Data.Empty using (⊥; ⊥-elim)
|
open import Data.Empty using (⊥; ⊥-elim)
|
||||||
open import Data.Nat using (ℕ; zero; suc; _+_; _∸_)
|
open import Data.Nat using (ℕ; zero; suc; _*_)
|
||||||
open import Data.Product using (_×_) renaming (_,_ to ⟨_,_⟩)
|
open import Data.Product using (_×_) renaming (_,_ to ⟨_,_⟩)
|
||||||
open import Data.Unit using (⊤; tt)
|
open import Data.Unit using (⊤; tt)
|
||||||
open import Function using (_∘_)
|
open import Function using (_∘_)
|
||||||
|
@ -533,6 +585,7 @@ infix 5 ƛ_
|
||||||
infix 5 μ_
|
infix 5 μ_
|
||||||
infixr 6 _`∷_
|
infixr 6 _`∷_
|
||||||
infixl 7 _·_
|
infixl 7 _·_
|
||||||
|
infixl 8 _`*_
|
||||||
infix 8 `suc_
|
infix 8 `suc_
|
||||||
infix 9 `_
|
infix 9 `_
|
||||||
infix 9 S_
|
infix 9 S_
|
||||||
|
@ -548,6 +601,7 @@ infix 8 V-suc_
|
||||||
data Type : Set where
|
data Type : Set where
|
||||||
`ℕ : Type
|
`ℕ : Type
|
||||||
_⇒_ : Type → Type → Type
|
_⇒_ : Type → Type → Type
|
||||||
|
Nat : Type
|
||||||
_`×_ : Type → Type → Type
|
_`×_ : Type → Type → Type
|
||||||
_`⊎_ : Type → Type → Type
|
_`⊎_ : Type → Type → Type
|
||||||
`⊤ : Type
|
`⊤ : Type
|
||||||
|
@ -628,6 +682,19 @@ data _⊢_ : Context → Type → Set where
|
||||||
----------
|
----------
|
||||||
→ Γ ⊢ A
|
→ Γ ⊢ A
|
||||||
|
|
||||||
|
-- primitive
|
||||||
|
|
||||||
|
con : ∀ {Γ}
|
||||||
|
→ ℕ
|
||||||
|
-------
|
||||||
|
→ Γ ⊢ Nat
|
||||||
|
|
||||||
|
_`*_ : ∀ {Γ}
|
||||||
|
→ Γ ⊢ Nat
|
||||||
|
→ Γ ⊢ Nat
|
||||||
|
-------
|
||||||
|
→ Γ ⊢ Nat
|
||||||
|
|
||||||
-- let
|
-- let
|
||||||
|
|
||||||
`let : ∀ {Γ A B}
|
`let : ∀ {Γ A B}
|
||||||
|
@ -722,7 +789,7 @@ data _⊢_ : Context → Type → Set where
|
||||||
→ Γ ⊢ B
|
→ Γ ⊢ B
|
||||||
\end{code}
|
\end{code}
|
||||||
|
|
||||||
## Abbreviating de Bruijn indices
|
### Abbreviating de Bruijn indices
|
||||||
|
|
||||||
\begin{code}
|
\begin{code}
|
||||||
lookup : Context → ℕ → Type
|
lookup : Context → ℕ → Type
|
||||||
|
@ -741,9 +808,7 @@ count {∅} _ = ⊥-elim impossible
|
||||||
# n = ` count n
|
# n = ` count n
|
||||||
\end{code}
|
\end{code}
|
||||||
|
|
||||||
## Substitution
|
## Renaming
|
||||||
|
|
||||||
### Renaming
|
|
||||||
|
|
||||||
\begin{code}
|
\begin{code}
|
||||||
ext : ∀ {Γ Δ} → (∀ {A} → Γ ∋ A → Δ ∋ A) → (∀ {A B} → Γ , A ∋ B → Δ , A ∋ B)
|
ext : ∀ {Γ Δ} → (∀ {A} → Γ ∋ A → Δ ∋ A) → (∀ {A B} → Γ , A ∋ B → Δ , A ∋ B)
|
||||||
|
@ -758,6 +823,9 @@ rename ρ (`zero) = `zero
|
||||||
rename ρ (`suc M) = `suc (rename ρ M)
|
rename ρ (`suc M) = `suc (rename ρ M)
|
||||||
rename ρ (case L M N) = case (rename ρ L) (rename ρ M) (rename (ext ρ) N)
|
rename ρ (case L M N) = case (rename ρ L) (rename ρ M) (rename (ext ρ) N)
|
||||||
rename ρ (μ N) = μ (rename (ext ρ) N)
|
rename ρ (μ N) = μ (rename (ext ρ) N)
|
||||||
|
rename ρ (con n) = con n
|
||||||
|
rename ρ (M `* N) = rename ρ M `* rename ρ N
|
||||||
|
rename ρ (`let M N) = `let (rename ρ M) (rename (ext ρ) N)
|
||||||
rename ρ `⟨ M , N ⟩ = `⟨ rename ρ M , rename ρ N ⟩
|
rename ρ `⟨ M , N ⟩ = `⟨ rename ρ M , rename ρ N ⟩
|
||||||
rename ρ (`proj₁ L) = `proj₁ (rename ρ L)
|
rename ρ (`proj₁ L) = `proj₁ (rename ρ L)
|
||||||
rename ρ (`proj₂ L) = `proj₂ (rename ρ L)
|
rename ρ (`proj₂ L) = `proj₂ (rename ρ L)
|
||||||
|
@ -771,10 +839,9 @@ rename ρ (case⊥ L) = case⊥ (rename ρ L)
|
||||||
rename ρ `[] = `[]
|
rename ρ `[] = `[]
|
||||||
rename ρ (M `∷ N) = (rename ρ M) `∷ (rename ρ N)
|
rename ρ (M `∷ N) = (rename ρ M) `∷ (rename ρ N)
|
||||||
rename ρ (caseL L M N) = caseL (rename ρ L) (rename ρ M) (rename (ext (ext ρ)) N)
|
rename ρ (caseL L M N) = caseL (rename ρ L) (rename ρ M) (rename (ext (ext ρ)) N)
|
||||||
rename ρ (`let M N) = `let (rename ρ M) (rename (ext ρ) N)
|
|
||||||
\end{code}
|
\end{code}
|
||||||
|
|
||||||
### Simultaneous Substitution
|
## Simultaneous Substitution
|
||||||
|
|
||||||
\begin{code}
|
\begin{code}
|
||||||
exts : ∀ {Γ Δ} → (∀ {A} → Γ ∋ A → Δ ⊢ A) → (∀ {A B} → Γ , A ∋ B → Δ , A ⊢ B)
|
exts : ∀ {Γ Δ} → (∀ {A} → Γ ∋ A → Δ ⊢ A) → (∀ {A B} → Γ , A ∋ B → Δ , A ⊢ B)
|
||||||
|
@ -789,6 +856,9 @@ subst σ (`zero) = `zero
|
||||||
subst σ (`suc M) = `suc (subst σ M)
|
subst σ (`suc M) = `suc (subst σ M)
|
||||||
subst σ (case L M N) = case (subst σ L) (subst σ M) (subst (exts σ) N)
|
subst σ (case L M N) = case (subst σ L) (subst σ M) (subst (exts σ) N)
|
||||||
subst σ (μ N) = μ (subst (exts σ) N)
|
subst σ (μ N) = μ (subst (exts σ) N)
|
||||||
|
subst σ (con n) = con n
|
||||||
|
subst σ (M `* N) = subst σ M `* subst σ N
|
||||||
|
subst σ (`let M N) = `let (subst σ M) (subst (exts σ) N)
|
||||||
subst σ `⟨ M , N ⟩ = `⟨ subst σ M , subst σ N ⟩
|
subst σ `⟨ M , N ⟩ = `⟨ subst σ M , subst σ N ⟩
|
||||||
subst σ (`proj₁ L) = `proj₁ (subst σ L)
|
subst σ (`proj₁ L) = `proj₁ (subst σ L)
|
||||||
subst σ (`proj₂ L) = `proj₂ (subst σ L)
|
subst σ (`proj₂ L) = `proj₂ (subst σ L)
|
||||||
|
@ -802,10 +872,9 @@ subst σ (case⊥ L) = case⊥ (subst σ L)
|
||||||
subst σ `[] = `[]
|
subst σ `[] = `[]
|
||||||
subst σ (M `∷ N) = (subst σ M) `∷ (subst σ N)
|
subst σ (M `∷ N) = (subst σ M) `∷ (subst σ N)
|
||||||
subst σ (caseL L M N) = caseL (subst σ L) (subst σ M) (subst (exts (exts σ)) N)
|
subst σ (caseL L M N) = caseL (subst σ L) (subst σ M) (subst (exts (exts σ)) N)
|
||||||
subst σ (`let M N) = `let (subst σ M) (subst (exts σ) N)
|
|
||||||
\end{code}
|
\end{code}
|
||||||
|
|
||||||
### Single and double substitution
|
## Single and double substitution
|
||||||
|
|
||||||
\begin{code}
|
\begin{code}
|
||||||
_[_] : ∀ {Γ A B}
|
_[_] : ∀ {Γ A B}
|
||||||
|
@ -833,9 +902,7 @@ _[_][_] {Γ} {A} {B} N V W = subst {Γ , A , B} {Γ} σ N
|
||||||
σ (S (S x)) = ` x
|
σ (S (S x)) = ` x
|
||||||
\end{code}
|
\end{code}
|
||||||
|
|
||||||
## Reduction
|
## Values
|
||||||
|
|
||||||
### Value
|
|
||||||
|
|
||||||
\begin{code}
|
\begin{code}
|
||||||
data Value : ∀ {Γ A} → Γ ⊢ A → Set where
|
data Value : ∀ {Γ A} → Γ ⊢ A → Set where
|
||||||
|
@ -857,6 +924,12 @@ data Value : ∀ {Γ A} → Γ ⊢ A → Set where
|
||||||
--------------
|
--------------
|
||||||
→ Value (`suc V)
|
→ Value (`suc V)
|
||||||
|
|
||||||
|
-- primitives
|
||||||
|
|
||||||
|
V-con : ∀ {Γ n}
|
||||||
|
---------------------
|
||||||
|
→ Value {Γ = Γ} (con n)
|
||||||
|
|
||||||
-- products
|
-- products
|
||||||
|
|
||||||
V-⟨_,_⟩ : ∀ {Γ A B} {V : Γ ⊢ A} {W : Γ ⊢ B}
|
V-⟨_,_⟩ : ∀ {Γ A B} {V : Γ ⊢ A} {W : Γ ⊢ B}
|
||||||
|
@ -899,7 +972,7 @@ data Value : ∀ {Γ A} → Γ ⊢ A → Set where
|
||||||
Implicit arguments need to be supplied when they are
|
Implicit arguments need to be supplied when they are
|
||||||
not fixed by the given arguments.
|
not fixed by the given arguments.
|
||||||
|
|
||||||
### Reduction step
|
## Reduction
|
||||||
|
|
||||||
\begin{code}
|
\begin{code}
|
||||||
infix 2 _—→_
|
infix 2 _—→_
|
||||||
|
@ -951,6 +1024,23 @@ data _—→_ : ∀ {Γ A} → (Γ ⊢ A) → (Γ ⊢ A) → Set where
|
||||||
----------------
|
----------------
|
||||||
→ μ N —→ N [ μ N ]
|
→ μ N —→ N [ μ N ]
|
||||||
|
|
||||||
|
-- primitives
|
||||||
|
|
||||||
|
ξ-*₁ : ∀ {Γ} {L L′ M : Γ ⊢ Nat}
|
||||||
|
→ L —→ L′
|
||||||
|
-----------------
|
||||||
|
→ L `* M —→ L′ `* M
|
||||||
|
|
||||||
|
ξ-*₂ : ∀ {Γ} {V M M′ : Γ ⊢ Nat}
|
||||||
|
→ Value V
|
||||||
|
→ M —→ M′
|
||||||
|
-----------------
|
||||||
|
→ V `* M —→ V `* M′
|
||||||
|
|
||||||
|
δ-* : ∀ {Γ c d}
|
||||||
|
-------------------------------------
|
||||||
|
→ con {Γ = Γ} c `* con d —→ con (c * d)
|
||||||
|
|
||||||
-- let
|
-- let
|
||||||
|
|
||||||
ξ-let : ∀ {Γ A B} {M M′ : Γ ⊢ A} {N : Γ , A ⊢ B}
|
ξ-let : ∀ {Γ A B} {M M′ : Γ ⊢ A} {N : Γ , A ⊢ B}
|
||||||
|
@ -1086,7 +1176,7 @@ data _—→_ : ∀ {Γ A} → (Γ ⊢ A) → (Γ ⊢ A) → Set where
|
||||||
→ caseL (V `∷ W) M N —→ N [ V ][ W ]
|
→ caseL (V `∷ W) M N —→ N [ V ][ W ]
|
||||||
\end{code}
|
\end{code}
|
||||||
|
|
||||||
### Reflexive and transitive closure
|
## Reflexive and transitive closure
|
||||||
|
|
||||||
\begin{code}
|
\begin{code}
|
||||||
infix 2 _—↠_
|
infix 2 _—↠_
|
||||||
|
@ -1116,7 +1206,6 @@ begin M—↠N = M—↠N
|
||||||
|
|
||||||
## Values do not reduce
|
## Values do not reduce
|
||||||
|
|
||||||
Values do not reduce.
|
|
||||||
\begin{code}
|
\begin{code}
|
||||||
V¬—→ : ∀ {Γ A} {M N : Γ ⊢ A}
|
V¬—→ : ∀ {Γ A} {M N : Γ ⊢ A}
|
||||||
→ Value M
|
→ Value M
|
||||||
|
@ -1125,6 +1214,7 @@ V¬—→ : ∀ {Γ A} {M N : Γ ⊢ A}
|
||||||
V¬—→ V-ƛ ()
|
V¬—→ V-ƛ ()
|
||||||
V¬—→ V-zero ()
|
V¬—→ V-zero ()
|
||||||
V¬—→ (V-suc VM) (ξ-suc M—→M′) = V¬—→ VM M—→M′
|
V¬—→ (V-suc VM) (ξ-suc M—→M′) = V¬—→ VM M—→M′
|
||||||
|
V¬—→ V-con ()
|
||||||
V¬—→ V-⟨ VM , _ ⟩ (ξ-⟨,⟩₁ M—→M′) = V¬—→ VM M—→M′
|
V¬—→ V-⟨ VM , _ ⟩ (ξ-⟨,⟩₁ M—→M′) = V¬—→ VM M—→M′
|
||||||
V¬—→ V-⟨ _ , VN ⟩ (ξ-⟨,⟩₂ _ N—→N′) = V¬—→ VN N—→N′
|
V¬—→ V-⟨ _ , VN ⟩ (ξ-⟨,⟩₂ _ N—→N′) = V¬—→ VN N—→N′
|
||||||
V¬—→ (V-inj₁ VM) (ξ-inj₁ M—→M′) = V¬—→ VM M—→M′
|
V¬—→ (V-inj₁ VM) (ξ-inj₁ M—→M′) = V¬—→ VM M—→M′
|
||||||
|
@ -1135,15 +1225,6 @@ V¬—→ (VM V-∷ _) (ξ-∷₁ M—→M′) = V¬—→ VM M—→M
|
||||||
V¬—→ (_ V-∷ VN) (ξ-∷₂ _ N—→N′) = V¬—→ VN N—→N′
|
V¬—→ (_ V-∷ VN) (ξ-∷₂ _ N—→N′) = V¬—→ VN N—→N′
|
||||||
\end{code}
|
\end{code}
|
||||||
|
|
||||||
As a corollary, terms that reduce are not values.
|
|
||||||
\begin{code}
|
|
||||||
—→¬V : ∀ {Γ A} {M N : Γ ⊢ A}
|
|
||||||
→ M —→ N
|
|
||||||
---------
|
|
||||||
→ ¬ Value M
|
|
||||||
—→¬V M—→N VM = V¬—→ VM M—→N
|
|
||||||
\end{code}
|
|
||||||
|
|
||||||
|
|
||||||
## Progress
|
## Progress
|
||||||
|
|
||||||
|
@ -1175,6 +1256,12 @@ progress (`zero) = done V-zero
|
||||||
progress (`suc M) with progress M
|
progress (`suc M) with progress M
|
||||||
... | step M—→M′ = step (ξ-suc M—→M′)
|
... | step M—→M′ = step (ξ-suc M—→M′)
|
||||||
... | done VM = done (V-suc VM)
|
... | done VM = done (V-suc VM)
|
||||||
|
progress (con n) = done V-con
|
||||||
|
progress (L `* M) with progress L
|
||||||
|
... | step L—→L′ = step (ξ-*₁ L—→L′)
|
||||||
|
... | done V-con with progress M
|
||||||
|
... | step M—→M′ = step (ξ-*₂ V-con M—→M′)
|
||||||
|
... | done V-con = step δ-*
|
||||||
progress (case L M N) with progress L
|
progress (case L M N) with progress L
|
||||||
... | step L—→L′ = step (ξ-case L—→L′)
|
... | step L—→L′ = step (ξ-case L—→L′)
|
||||||
... | done V-zero = step β-zero
|
... | done V-zero = step β-zero
|
||||||
|
@ -1268,6 +1355,49 @@ eval (gas (suc m)) L with progress L
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
\begin{code}
|
\begin{code}
|
||||||
|
cube : ∅ ⊢ Nat ⇒ Nat
|
||||||
|
cube = ƛ (# 0 `* # 0 `* # 0)
|
||||||
|
|
||||||
|
_ : cube · con 2 —↠ con 8
|
||||||
|
_ =
|
||||||
|
begin
|
||||||
|
cube · con 2
|
||||||
|
—→⟨ β-ƛ V-con ⟩
|
||||||
|
con 2 `* con 2 `* con 2
|
||||||
|
—→⟨ ξ-*₁ δ-* ⟩
|
||||||
|
con 4 `* con 2
|
||||||
|
—→⟨ δ-* ⟩
|
||||||
|
con 8
|
||||||
|
∎
|
||||||
|
|
||||||
|
exp10 : ∅ ⊢ Nat ⇒ Nat
|
||||||
|
exp10 = ƛ (`let (# 0 `* # 0)
|
||||||
|
(`let (# 0 `* # 0)
|
||||||
|
(`let (# 0 `* # 2)
|
||||||
|
(# 0 `* # 0))))
|
||||||
|
|
||||||
|
_ : exp10 · con 2 —↠ con 1024
|
||||||
|
_ =
|
||||||
|
begin
|
||||||
|
exp10 · con 2
|
||||||
|
—→⟨ β-ƛ V-con ⟩
|
||||||
|
`let (con 2 `* con 2) (`let (# 0 `* # 0) (`let (# 0 `* con 2) (# 0 `* # 0)))
|
||||||
|
—→⟨ ξ-let δ-* ⟩
|
||||||
|
`let (con 4) (`let (# 0 `* # 0) (`let (# 0 `* con 2) (# 0 `* # 0)))
|
||||||
|
—→⟨ β-let V-con ⟩
|
||||||
|
`let (con 4 `* con 4) (`let (# 0 `* con 2) (# 0 `* # 0))
|
||||||
|
—→⟨ ξ-let δ-* ⟩
|
||||||
|
`let (con 16) (`let (# 0 `* con 2) (# 0 `* # 0))
|
||||||
|
—→⟨ β-let V-con ⟩
|
||||||
|
`let (con 16 `* con 2) (# 0 `* # 0)
|
||||||
|
—→⟨ ξ-let δ-* ⟩
|
||||||
|
`let (con 32) (# 0 `* # 0)
|
||||||
|
—→⟨ β-let V-con ⟩
|
||||||
|
con 32 `* con 32
|
||||||
|
—→⟨ δ-* ⟩
|
||||||
|
con 1024
|
||||||
|
∎
|
||||||
|
|
||||||
swap× : ∀ {A B} → ∅ ⊢ A `× B ⇒ B `× A
|
swap× : ∀ {A B} → ∅ ⊢ A `× B ⇒ B `× A
|
||||||
swap× = ƛ `⟨ `proj₂ (# 0) , `proj₁ (# 0) ⟩
|
swap× = ƛ `⟨ `proj₂ (# 0) , `proj₁ (# 0) ⟩
|
||||||
|
|
||||||
|
@ -1283,6 +1413,22 @@ _ =
|
||||||
`⟨ `zero , `tt ⟩
|
`⟨ `zero , `tt ⟩
|
||||||
∎
|
∎
|
||||||
|
|
||||||
|
swap×-case : ∀ {A B} → ∅ ⊢ A `× B ⇒ B `× A
|
||||||
|
swap×-case = ƛ case× (# 0) `⟨ # 0 , # 1 ⟩
|
||||||
|
|
||||||
|
_ : swap×-case · `⟨ `tt , `zero ⟩ —↠ `⟨ `zero , `tt ⟩
|
||||||
|
_ =
|
||||||
|
begin
|
||||||
|
swap×-case · `⟨ `tt , `zero ⟩
|
||||||
|
—→⟨ β-ƛ V-⟨ V-tt , V-zero ⟩ ⟩
|
||||||
|
case× `⟨ `tt , `zero ⟩ `⟨ # 0 , # 1 ⟩
|
||||||
|
—→⟨ β-case× V-tt V-zero ⟩
|
||||||
|
`⟨ `zero , `tt ⟩
|
||||||
|
∎
|
||||||
|
\end{code}
|
||||||
|
|
||||||
|
|
||||||
|
\begin{code}
|
||||||
swap⊎ : ∀ {A B} → ∅ ⊢ A `⊎ B ⇒ B `⊎ A
|
swap⊎ : ∀ {A B} → ∅ ⊢ A `⊎ B ⇒ B `⊎ A
|
||||||
swap⊎ = ƛ (case⊎ (# 0) (`inj₂ (# 0)) (`inj₁ (# 0)))
|
swap⊎ = ƛ (case⊎ (# 0) (`inj₂ (# 0)) (`inj₁ (# 0)))
|
||||||
|
|
||||||
|
@ -1298,3 +1444,6 @@ _ =
|
||||||
\end{code}
|
\end{code}
|
||||||
|
|
||||||
|
|
||||||
|
#### Exercise (`More`)
|
||||||
|
|
||||||
|
Formalise the remaining constructs defined in this chapter.
|
||||||
|
|
|
@ -352,9 +352,8 @@ postulate
|
||||||
## Prelude to preservation
|
## Prelude to preservation
|
||||||
|
|
||||||
The other property we wish to prove, preservation of typing under
|
The other property we wish to prove, preservation of typing under
|
||||||
reduction, turns out to require considerably more work. Our proof
|
reduction, turns out to require considerably more work. The proof has
|
||||||
draws on a line of work by Thorsten Altenkirch, Conor McBride,
|
three key steps.
|
||||||
James McKinna, and others. The proof has three key steps.
|
|
||||||
|
|
||||||
The first step is to show that types are preserved by _renaming_.
|
The first step is to show that types are preserved by _renaming_.
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue