Remove tick from constructors

This commit is contained in:
wadler 2019-09-02 19:15:50 +01:00
parent f68782dccb
commit 07894d0d79
6 changed files with 535 additions and 550 deletions

View file

@ -116,7 +116,7 @@ that it is _intrinsically typed_. In the previous two chapters,
the definition of terms and the definition of types are
completely separate. All terms have type `Term`, and nothing
in Agda prevents one from writing a nonsense term such as
`` `zero · `suc `zero `` which has no type. Such terms that
`` zero · suc zero `` which has no type. Such terms that
exist independent of types are sometimes called _preterms_ or
_raw terms_. Here we are going to replace the type `Term` of
raw terms by the type `Γ ⊢ A` of intrinsically-typed terms
@ -140,7 +140,7 @@ the term that adds two naturals:
plus = μ "+" ⇒ ƛ "m" ⇒ ƛ "n" ⇒
case ` "m"
[zero⇒ ` "n"
|suc "m" ⇒ `suc (` "+" · ` "m" · ` "n") ]
|suc "m" ⇒ suc (` "+" · ` "m" · ` "n") ]
Note variable `"m"` is bound twice, once in a lambda abstraction
and once in the successor branch of the case. Any appearance
@ -162,8 +162,8 @@ Here is its corresponding type derivation:
The two definitions are in close correspondence, where in
addition to the previous correspondences we have:
* `` `zero `` corresponds to `⊢zero`
* `` `suc_ `` corresponds to `⊢suc`
* `` zero `` corresponds to `⊢zero`
* `` suc `` corresponds to `⊢suc`
* `` case_[zero⇒_|suc_⇒_] `` corresponds to `⊢case`
* `μ_⇒_` corresponds to `⊢μ`
@ -177,7 +177,7 @@ of `"n"` but accessed in different contexts, the first where
Here is the term and its type derivation in the notation of this chapter:
plus : ∀ {Γ} → Γ ⊢ ` ⇒ ` ⇒ `
plus = μ ƛ ƛ case (# 1) (# 0) (`suc (# 3 · # 0 · # 1))
plus = μ ƛ ƛ case (# 1) (# 0) (suc (# 3 · # 0 · # 1))
Reading from left to right, each de Bruijn index corresponds
to a lookup derivation:
@ -230,7 +230,6 @@ infixr 7 _⇒_
infix 5 ƛ_
infix 5 μ_
infixl 7 _·_
infix 8 `suc_
infix 9 `_
infix 9 S_
infix 9 #_
@ -300,7 +299,7 @@ Constructor `S` no longer requires an additional parameter,
since without names shadowing is no longer an issue. Now
constructors `Z` and `S` correspond even more closely to the
constructors `here` and `there` for the element-of relation
`_∈_` on lists, as well as to constructors `zero` and `suc`
`_∈_` on lists, as well as to constructors zero` and suc`
for natural numbers.
For example, consider the following old-style lookup
@ -353,11 +352,11 @@ data _⊢_ : Context → Type → Set where
---------
→ Γ ⊢ B
`zero : ∀ {Γ}
zero : ∀ {Γ}
---------
→ Γ ⊢ `
`suc_ : ∀ {Γ}
suc : ∀ {Γ}
→ Γ ⊢ `
------
→ Γ ⊢ `
@ -460,10 +459,10 @@ for comparison.
First, computing two plus two on naturals:
```
two : ∀ {Γ} → Γ ⊢ `
two = `suc `suc `zero
two = suc (suc zero)
plus : ∀ {Γ} → Γ ⊢ ` ⇒ ` ⇒ `
plus = μ ƛ ƛ (case (# 1) (# 0) (`suc (# 3 · # 0 · # 1)))
plus = μ ƛ ƛ (case (# 1) (# 0) (suc (# 3 · # 0 · # 1)))
2+2 : ∀ {Γ} → Γ ⊢ `
2+2 = plus · two · two
@ -483,10 +482,10 @@ plusᶜ : ∀ {Γ A} → Γ ⊢ Ch A ⇒ Ch A ⇒ Ch A
plusᶜ = ƛ ƛ ƛ ƛ (# 3 · # 1 · (# 2 · # 1 · # 0))
sucᶜ : ∀ {Γ} → Γ ⊢ ` ⇒ `
sucᶜ = ƛ `suc (# 0)
sucᶜ = ƛ suc (# 0)
2+2ᶜ : ∀ {Γ} → Γ ⊢ `
2+2ᶜ = plusᶜ · twoᶜ · twoᶜ · sucᶜ · `zero
2+2ᶜ = plusᶜ · twoᶜ · twoᶜ · sucᶜ · zero
```
As before we generalise everything to arbitrary
contexts. While we are at it, we also generalise `twoᶜ` and
@ -550,8 +549,8 @@ rename : ∀ {Γ Δ}
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 ρ (zero) = zero
rename ρ (suc M) = suc (rename ρ M)
rename ρ (case L M N) = case (rename ρ L) (rename ρ M) (rename (ext ρ) N)
rename ρ (μ N) = μ (rename (ext ρ) N)
```
@ -664,8 +663,8 @@ subst : ∀ {Γ Δ}
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 σ (zero) = zero
subst σ (suc M) = suc (subst σ M)
subst σ (case L M N) = case (subst σ L) (subst σ M) (subst (exts σ) N)
subst σ (μ N) = μ (subst (exts σ) N)
```
@ -719,10 +718,10 @@ M₂ : ∅ , ` ⇒ ` ⊢ ` ⇒ `
M₂ = ƛ # 1 · (# 1 · # 0)
M₃ : ∅ ⊢ ` ⇒ `
M₃ = ƛ `suc # 0
M₃ = ƛ suc (# 0)
M₄ : ∅ ⊢ ` ⇒ `
M₄ = ƛ (ƛ `suc # 0) · ((ƛ `suc # 0) · # 0)
M₄ = ƛ (ƛ suc (# 0)) · ((ƛ suc (# 0)) · # 0)
_ : M₂ [ M₃ ] ≡ M₄
_ = refl
@ -732,8 +731,8 @@ Previously, we presented an example of substitution that we
did not implement, since it needed to rename the bound
variable to avoid capture:
* `` (ƛ "x" ⇒ ` "x" · ` "y") [ "y" := ` "x" · `zero ] `` should yield
`` ƛ "z" ⇒ ` "z" · (` "x" · `zero) ``
* `` (ƛ "x" ⇒ ` "x" · ` "y") [ "y" := ` "x" · zero ] `` should yield
`` ƛ "z" ⇒ ` "z" · (` "x" · zero) ``
Say the bound `"x"` has type `` ` ⇒ ` ``, the substituted
`"y"` has type `` ` ``, and the free `"x"` also has type ``
@ -743,10 +742,10 @@ M₅ : ∅ , ` ⇒ ` , ` ⊢ (` ⇒ `) ⇒ `
M₅ = ƛ # 0 · # 1
M₆ : ∅ , ` ⇒ ` ⊢ `
M₆ = # 0 · `zero
M₆ = # 0 · zero
M₇ : ∅ , ` ⇒ ` ⊢ (``) ⇒ `
M₇ = ƛ (# 0 · (# 1 · `zero))
M₇ = ƛ (# 0 · (# 1 · zero))
_ : M₅ [ M₆ ] ≡ M₇
_ = refl
@ -777,15 +776,15 @@ data Value : ∀ {Γ A} → Γ ⊢ A → Set where
V-zero : ∀ {Γ}
-----------------
→ Value (`zero {Γ})
→ Value (zero {Γ})
V-suc : ∀ {Γ} {V : Γ ⊢ `}
→ Value V
--------------
→ Value (`suc V)
→ Value (suc V)
```
Here `zero` requires an implicit parameter to aid inference,
Here zero` requires an implicit parameter to aid inference,
much in the same way that `[]` did in
[Lists]({{ site.baseurl }}/Lists/).
@ -822,7 +821,7 @@ data _—→_ : ∀ {Γ A} → (Γ ⊢ A) → (Γ ⊢ A) → Set where
ξ-suc : ∀ {Γ} {M M : Γ ⊢ `}
→ M —→ M
-----------------
`suc M —→ `suc M
→ suc M —→ suc M
ξ-case : ∀ {Γ A} {L L : Γ ⊢ `} {M : Γ ⊢ A} {N : Γ , ` ⊢ A}
→ L —→ L
@ -831,12 +830,12 @@ data _—→_ : ∀ {Γ A} → (Γ ⊢ A) → (Γ ⊢ A) → Set where
β-zero : ∀ {Γ A} {M : Γ ⊢ A} {N : Γ , ` ⊢ A}
-------------------
→ case `zero M N —→ M
→ case zero M N —→ M
β-suc : ∀ {Γ A} {V : Γ ⊢ `} {M : Γ ⊢ A} {N : Γ , ` ⊢ A}
→ Value V
----------------------------
→ case (`suc V) M N —→ N [ V ]
→ case (suc V) M N —→ N [ V ]
β-μ : ∀ {Γ A} {N : Γ , A ⊢ A}
----------------
@ -889,86 +888,86 @@ We reiterate each of our previous examples. First, the Church
numeral two applied to the successor function and zero yields
the natural number two:
```
_ : twoᶜ · sucᶜ · `zero {∅} —↠ `suc `suc `zero
_ : twoᶜ · sucᶜ · zero {∅} —↠ suc (suc zero)
_ =
begin
twoᶜ · sucᶜ · `zero
twoᶜ · sucᶜ · zero
—→⟨ ξ-·₁ (β-ƛ V-ƛ) ⟩
(ƛ (sucᶜ · (sucᶜ · # 0))) · `zero
(ƛ (sucᶜ · (sucᶜ · # 0))) · zero
—→⟨ β-ƛ V-zero ⟩
sucᶜ · (sucᶜ · `zero)
sucᶜ · (sucᶜ · zero)
—→⟨ ξ-·₂ V-ƛ (β-ƛ V-zero) ⟩
sucᶜ · `suc `zero
sucᶜ · suc zero
—→⟨ β-ƛ (V-suc V-zero) ⟩
`suc (`suc `zero)
suc (suc zero)
```
As before, we need to supply an explicit context to `` `zero ``.
As before, we need to supply an explicit context to `` zero ``.
Next, a sample reduction demonstrating that two plus two is four:
```
_ : plus {∅} · two · two —↠ `suc `suc `suc `suc `zero
_ : plus {∅} · two · two —↠ suc (suc (suc (suc zero)))
_ =
plus · two · two
—→⟨ ξ-·₁ (ξ-·₁ β-μ) ⟩
(ƛ ƛ case (` S Z) (` Z) (`suc (plus · ` Z · ` S Z))) · two · two
(ƛ ƛ case (` S Z) (` Z) (suc (plus · ` Z · ` S Z))) · two · two
—→⟨ ξ-·₁ (β-ƛ (V-suc (V-suc V-zero))) ⟩
(ƛ case two (` Z) (`suc (plus · ` Z · ` S Z))) · two
(ƛ case two (` Z) (suc (plus · ` Z · ` S Z))) · two
—→⟨ β-ƛ (V-suc (V-suc V-zero)) ⟩
case two two (`suc (plus · ` Z · two))
case two two (suc (plus · ` Z · two))
—→⟨ β-suc (V-suc V-zero) ⟩
`suc (plus · `suc `zero · two)
suc (plus · suc zero · two)
—→⟨ ξ-suc (ξ-·₁ (ξ-·₁ β-μ)) ⟩
`suc ((ƛ ƛ case (` S Z) (` Z) (`suc (plus · ` Z · ` S Z)))
· `suc `zero · two)
suc ((ƛ ƛ case (` S Z) (` Z) (suc (plus · ` Z · ` S Z)))
· suc zero · two)
—→⟨ ξ-suc (ξ-·₁ (β-ƛ (V-suc V-zero))) ⟩
`suc ((ƛ case (`suc `zero) (` Z) (`suc (plus · ` Z · ` S Z))) · two)
suc ((ƛ case (suc zero) (` Z) (suc (plus · ` Z · ` S Z))) · two)
—→⟨ ξ-suc (β-ƛ (V-suc (V-suc V-zero))) ⟩
`suc (case (`suc `zero) (two) (`suc (plus · ` Z · two)))
suc (case (suc zero) (two) (suc (plus · ` Z · two)))
—→⟨ ξ-suc (β-suc V-zero) ⟩
`suc (`suc (plus · `zero · two))
suc (suc (plus · zero · two))
—→⟨ ξ-suc (ξ-suc (ξ-·₁ (ξ-·₁ β-μ))) ⟩
`suc (`suc ((ƛ ƛ case (` S Z) (` Z) (`suc (plus · ` Z · ` S Z)))
· `zero · two))
suc (suc ((ƛ ƛ case (` S Z) (` Z) (suc (plus · ` Z · ` S Z)))
· zero · two))
—→⟨ ξ-suc (ξ-suc (ξ-·₁ (β-ƛ V-zero))) ⟩
`suc (`suc ((ƛ case `zero (` Z) (`suc (plus · ` Z · ` S Z))) · two))
suc (suc ((ƛ case zero (` Z) (suc (plus · ` Z · ` S Z))) · two))
—→⟨ ξ-suc (ξ-suc (β-ƛ (V-suc (V-suc V-zero)))) ⟩
`suc (`suc (case `zero (two) (`suc (plus · ` Z · two))))
suc (suc (case zero (two) (suc (plus · ` Z · two))))
—→⟨ ξ-suc (ξ-suc β-zero) ⟩
`suc (`suc (`suc (`suc `zero)))
suc (suc (suc (suc zero)))
```
And finally, a similar sample reduction for Church numerals:
```
_ : plusᶜ · twoᶜ · twoᶜ · sucᶜ · `zero —↠ `suc `suc `suc `suc `zero {∅}
_ : plusᶜ · twoᶜ · twoᶜ · sucᶜ · zero —↠ suc (suc (suc (suc (zero {∅}))))
_ =
begin
plusᶜ · twoᶜ · twoᶜ · sucᶜ · `zero
plusᶜ · twoᶜ · twoᶜ · sucᶜ · zero
—→⟨ ξ-·₁ (ξ-·₁ (ξ-·₁ (β-ƛ V-ƛ))) ⟩
(ƛ ƛ ƛ twoᶜ · ` S Z · (` S S Z · ` S Z · ` Z)) · twoᶜ · sucᶜ · `zero
(ƛ ƛ ƛ twoᶜ · ` S Z · (` S S Z · ` S Z · ` Z)) · twoᶜ · sucᶜ · zero
—→⟨ ξ-·₁ (ξ-·₁ (β-ƛ V-ƛ)) ⟩
(ƛ ƛ twoᶜ · ` S Z · (twoᶜ · ` S Z · ` Z)) · sucᶜ · `zero
(ƛ ƛ twoᶜ · ` S Z · (twoᶜ · ` S Z · ` Z)) · sucᶜ · zero
—→⟨ ξ-·₁ (β-ƛ V-ƛ) ⟩
(ƛ twoᶜ · sucᶜ · (twoᶜ · sucᶜ · ` Z)) · `zero
(ƛ twoᶜ · sucᶜ · (twoᶜ · sucᶜ · ` Z)) · zero
—→⟨ β-ƛ V-zero ⟩
twoᶜ · sucᶜ · (twoᶜ · sucᶜ · `zero)
twoᶜ · sucᶜ · (twoᶜ · sucᶜ · zero)
—→⟨ ξ-·₁ (β-ƛ V-ƛ) ⟩
(ƛ sucᶜ · (sucᶜ · ` Z)) · (twoᶜ · sucᶜ · `zero)
(ƛ sucᶜ · (sucᶜ · ` Z)) · (twoᶜ · sucᶜ · zero)
—→⟨ ξ-·₂ V-ƛ (ξ-·₁ (β-ƛ V-ƛ)) ⟩
(ƛ sucᶜ · (sucᶜ · ` Z)) · ((ƛ sucᶜ · (sucᶜ · ` Z)) · `zero)
(ƛ sucᶜ · (sucᶜ · ` Z)) · ((ƛ sucᶜ · (sucᶜ · ` Z)) · zero)
—→⟨ ξ-·₂ V-ƛ (β-ƛ V-zero) ⟩
(ƛ sucᶜ · (sucᶜ · ` Z)) · (sucᶜ · (sucᶜ · `zero))
(ƛ sucᶜ · (sucᶜ · ` Z)) · (sucᶜ · (sucᶜ · zero))
—→⟨ ξ-·₂ V-ƛ (ξ-·₂ V-ƛ (β-ƛ V-zero)) ⟩
(ƛ sucᶜ · (sucᶜ · ` Z)) · (sucᶜ · `suc `zero)
(ƛ sucᶜ · (sucᶜ · ` Z)) · (sucᶜ · suc zero)
—→⟨ ξ-·₂ V-ƛ (β-ƛ (V-suc V-zero)) ⟩
(ƛ sucᶜ · (sucᶜ · ` Z)) · `suc (`suc `zero)
(ƛ sucᶜ · (sucᶜ · ` Z)) · suc (suc zero)
—→⟨ β-ƛ (V-suc (V-suc V-zero)) ⟩
sucᶜ · (sucᶜ · `suc (`suc `zero))
sucᶜ · (sucᶜ · suc (suc zero))
—→⟨ ξ-·₂ V-ƛ (β-ƛ (V-suc (V-suc V-zero))) ⟩
sucᶜ · `suc (`suc (`suc `zero))
sucᶜ · suc (suc (suc zero))
—→⟨ β-ƛ (V-suc (V-suc (V-suc V-zero))) ⟩
`suc (`suc (`suc (`suc `zero)))
suc (suc (suc (suc zero)))
```
@ -1023,8 +1022,8 @@ progress (L · M) with progress L
... | done V-ƛ with progress M
... | step M—→M = step (ξ-·₂ V-ƛ M—→M)
... | done VM = step (β-ƛ VM)
progress (`zero) = done V-zero
progress (`suc M) with progress M
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
@ -1091,23 +1090,23 @@ to invoke preservation.
## Examples
We reiterate each of our previous examples. We re-define the term
`sucμ` that loops forever:
sucμ` that loops forever:
```
sucμ : ∅ ⊢ `
sucμ = μ (`suc (# 0))
sucμ = μ (suc (# 0))
```
To compute the first three steps of the infinite reduction sequence,
we evaluate with three steps worth of gas:
```
_ : eval (gas 3) sucμ ≡
steps
`suc ` Z
(μ suc (` Z)
—→⟨ β-μ ⟩
`suc (μ `suc ` Z)
suc (μ suc (` Z))
—→⟨ ξ-suc β-μ ⟩
`suc (`suc (μ `suc ` Z))
suc (suc (μ suc (` Z)))
—→⟨ ξ-suc (ξ-suc β-μ) ⟩
`suc (`suc (`suc (μ `suc ` Z)))
suc (suc (suc (μ suc (` Z))))
∎)
out-of-gas
_ = refl
@ -1115,17 +1114,17 @@ _ = refl
The Church numeral two applied to successor and zero:
```
_ : eval (gas 100) (twoᶜ · sucᶜ · `zero) ≡
_ : eval (gas 100) (twoᶜ · sucᶜ · zero) ≡
steps
((ƛ (ƛ ` (S Z) · (` (S Z) · ` Z))) · (ƛ `suc ` Z) · `zero
((ƛ (ƛ ` (S Z) · (` (S Z) · ` Z))) · (ƛ suc (` Z)) · zero
—→⟨ ξ-·₁ (β-ƛ V-ƛ) ⟩
(ƛ (ƛ `suc ` Z) · ((ƛ `suc ` Z) · ` Z)) · `zero
(ƛ (ƛ suc (` Z)) · ((ƛ suc (` Z)) · ` Z)) · zero
—→⟨ β-ƛ V-zero ⟩
`suc ` Z) · ((ƛ `suc ` Z) · `zero)
(ƛ suc (` Z)) · ((ƛ suc (` Z)) · zero)
—→⟨ ξ-·₂ V-ƛ (β-ƛ V-zero) ⟩
`suc ` Z) · `suc `zero
(ƛ suc (` Z)) · suc zero
—→⟨ β-ƛ (V-suc V-zero) ⟩
`suc (`suc `zero)
suc (suc zero)
∎)
(done (V-suc (V-suc V-zero)))
_ = refl
@ -1135,155 +1134,141 @@ Two plus two is four:
```
_ : eval (gas 100) (plus · two · two) ≡
steps
((μ
case (` (S Z)) (` Z) (`suc (` (S (S (S Z))) · ` Z · ` (S Z))))))
· `suc (`suc `zero)
· `suc (`suc `zero)
((μ
(ƛ case (` (S Z)) (` Z) (suc (` (S (S (S Z))) · ` Z · ` (S Z))))))
· suc (suc zero)
· suc (suc zero)
—→⟨ ξ-·₁ (ξ-·₁ β-μ) ⟩
case (` (S Z)) (` Z)
(`suc
((μ
case (` (S Z)) (` Z) (`suc (` (S (S (S Z))) · ` Z · ` (S Z))))))
· ` Z
· ` (S Z)))))
· `suc (`suc `zero)
· `suc (`suc `zero)
—→⟨ ξ-·₁ (β-ƛ (V-suc (V-suc V-zero))) ⟩
case (`suc (`suc `zero)) (` Z)
(`suc
case (` (S Z)) (` Z)
(suc
((μ
case (` (S Z)) (` Z) (`suc (` (S (S (S Z))) · ` Z · ` (S Z))))))
(ƛ case (` (S Z)) (` Z) (suc (` (S (S (S Z))) · ` Z · ` (S Z))))))
· ` Z
· ` (S Z))))
· `suc (`suc `zero)
—→⟨ β-ƛ (V-suc (V-suc V-zero)) ⟩
case (`suc (`suc `zero)) (`suc (`suc `zero))
(`suc
· ` (S Z)))))
· suc (suc zero)
· suc (suc zero)
—→⟨ ξ-·₁ (β-ƛ (V-suc (V-suc V-zero))) ⟩
case (suc (suc zero)) (` Z)
(suc
((μ
case (` (S Z)) (` Z) (`suc (` (S (S (S Z))) · ` Z · ` (S Z))))))
(ƛ case (` (S Z)) (` Z) (suc (` (S (S (S Z))) · ` Z · ` (S Z))))))
· ` Z
· `suc (`suc `zero)))
—→⟨ β-suc (V-suc V-zero) ⟩
`suc
· ` (S Z))))
· suc (suc zero)
—→⟨ β-ƛ (V-suc (V-suc V-zero)) ⟩
case (suc (suc zero)) (suc (suc zero))
(suc
((μ
case (` (S Z)) (` Z) (`suc (` (S (S (S Z))) · ` Z · ` (S Z))))))
· `suc `zero
· `suc (`suc `zero))
(ƛ case (` (S Z)) (` Z) (suc (` (S (S (S Z))) · ` Z · ` (S Z))))))
· ` Z
· suc (suc zero)))
—→⟨ β-suc (V-suc V-zero) ⟩
suc
((μ
(ƛ case (` (S Z)) (` Z) (suc (` (S (S (S Z))) · ` Z · ` (S Z))))))
· suc zero
· suc (suc zero))
—→⟨ ξ-suc (ξ-·₁ (ξ-·₁ β-μ)) ⟩
`suc
suc
((ƛ
case (` (S Z)) (` Z)
(suc
((μ
(ƛ case (` (S Z)) (` Z) (suc (` (S (S (S Z))) · ` Z · ` (S Z))))))
· ` Z
· ` (S Z)))))
· suc zero
· suc (suc zero))
—→⟨ ξ-suc (ξ-·₁ (β-ƛ (V-suc V-zero))) ⟩
suc
((ƛ
case (suc zero) (` Z)
(suc
((μ
(ƛ case (` (S Z)) (` Z) (suc (` (S (S (S Z))) · ` Z · ` (S Z))))))
· ` Z
· ` (S Z))))
· suc (suc zero))
—→⟨ ξ-suc (β-ƛ (V-suc (V-suc V-zero))) ⟩
suc
(case (suc zero) (suc (suc zero))
(suc
((μ
(ƛ case (` (S Z)) (` Z) (suc (` (S (S (S Z))) · ` Z · ` (S Z))))))
· ` Z
· suc (suc zero))))
—→⟨ ξ-suc (β-suc V-zero) ⟩
suc
(suc
((μ
(ƛ case (` (S Z)) (` Z) (suc (` (S (S (S Z))) · ` Z · ` (S Z))))))
· zero
· suc (suc zero)))
—→⟨ ξ-suc (ξ-suc (ξ-·₁ (ξ-·₁ β-μ))) ⟩
suc
(suc
((ƛ
case (` (S Z)) (` Z)
(`suc
(suc
((μ
case (` (S Z)) (` Z) (`suc (` (S (S (S Z))) · ` Z · ` (S Z))))))
(ƛ case (` (S Z)) (` Z) (suc (` (S (S (S Z))) · ` Z · ` (S Z))))))
· ` Z
· ` (S Z)))))
· `suc `zero
· `suc (`suc `zero))
—→⟨ ξ-suc (ξ-·₁ (β-ƛ (V-suc V-zero))) ⟩
`suc
· zero
· suc (suc zero)))
—→⟨ ξ-suc (ξ-suc (ξ-·₁ (β-ƛ V-zero))) ⟩
suc
(suc
((ƛ
case (`suc `zero) (` Z)
(`suc
case zero (` Z)
(suc
((μ
case (` (S Z)) (` Z) (`suc (` (S (S (S Z))) · ` Z · ` (S Z))))))
(ƛ case (` (S Z)) (` Z) (suc (` (S (S (S Z))) · ` Z · ` (S Z))))))
· ` Z
· ` (S Z))))
· `suc (`suc `zero))
—→⟨ ξ-suc (β-ƛ (V-suc (V-suc V-zero))) ⟩
`suc
case (`suc `zero) (`suc (`suc `zero))
(`suc
((μ
case (` (S Z)) (` Z) (`suc (` (S (S (S Z))) · ` Z · ` (S Z))))))
· ` Z
· `suc (`suc `zero)))
—→⟨ ξ-suc (β-suc V-zero) ⟩
`suc
(`suc
((μ
case (` (S Z)) (` Z) (`suc (` (S (S (S Z))) · ` Z · ` (S Z))))))
· `zero
· `suc (`suc `zero)))
—→⟨ ξ-suc (ξ-suc (ξ-·₁ (ξ-·₁ β-μ))) ⟩
`suc
(`suc
((ƛ
case (` (S Z)) (` Z)
(`suc
((μ
case (` (S Z)) (` Z) (`suc (` (S (S (S Z))) · ` Z · ` (S Z))))))
· ` Z
· ` (S Z)))))
· `zero
· `suc (`suc `zero)))
—→⟨ ξ-suc (ξ-suc (ξ-·₁ (β-ƛ V-zero))) ⟩
`suc
(`suc
((ƛ
case `zero (` Z)
(`suc
((μ
case (` (S Z)) (` Z) (`suc (` (S (S (S Z))) · ` Z · ` (S Z))))))
· ` Z
· ` (S Z))))
· `suc (`suc `zero)))
· suc (suc zero)))
—→⟨ ξ-suc (ξ-suc (β-ƛ (V-suc (V-suc V-zero)))) ⟩
`suc
(`suc
case `zero (`suc (`suc `zero))
(`suc
suc
(suc
(case zero (suc (suc zero))
(suc
((μ
case (` (S Z)) (` Z) (`suc (` (S (S (S Z))) · ` Z · ` (S Z))))))
(ƛ case (` (S Z)) (` Z) (suc (` (S (S (S Z))) · ` Z · ` (S Z))))))
· ` Z
· `suc (`suc `zero))))
—→⟨ ξ-suc (ξ-suc β-zero) ⟩
`suc (`suc (`suc (`suc `zero)))
∎)
(done (V-suc (V-suc (V-suc (V-suc V-zero)))))
· suc (suc zero)))))
—→⟨ ξ-suc (ξ-suc β-zero) ⟩ suc (suc (suc (suc zero))) ∎)
(done (V-suc (V-suc (V-suc (V-suc V-zero)))))
_ = refl
```
And the corresponding term for Church numerals:
```
_ : eval (gas 100) (plusᶜ · twoᶜ · twoᶜ · sucᶜ · `zero) ≡
_ : eval (gas 100) (plusᶜ · twoᶜ · twoᶜ · sucᶜ · zero) ≡
steps
((ƛ
(ƛ (ƛ ` (S (S (S Z))) · ` (S Z) · (` (S (S Z)) · ` (S Z) · ` Z)))))
· (ƛ (ƛ ` (S Z) · (` (S Z) · ` Z)))
· (ƛ (ƛ ` (S Z) · (` (S Z) · ` Z)))
· (ƛ `suc ` Z)
· `zero
· (ƛ suc (` Z))
· zero
—→⟨ ξ-·₁ (ξ-·₁ (ξ-·₁ (β-ƛ V-ƛ))) ⟩
@ -1291,43 +1276,43 @@ _ : eval (gas 100) (plusᶜ · twoᶜ · twoᶜ · sucᶜ · `zero) ≡
(ƛ (ƛ ` (S Z) · (` (S Z) · ` Z))) · ` (S Z) ·
(` (S (S Z)) · ` (S Z) · ` Z))))
· (ƛ (ƛ ` (S Z) · (` (S Z) · ` Z)))
· (ƛ `suc ` Z)
· `zero
· (ƛ suc (` Z))
· zero
—→⟨ ξ-·₁ (ξ-·₁ (β-ƛ V-ƛ)) ⟩
(ƛ (ƛ ` (S Z) · (` (S Z) · ` Z))) · ` (S Z) ·
((ƛ (ƛ ` (S Z) · (` (S Z) · ` Z))) · ` (S Z) · ` Z)))
· (ƛ `suc ` Z)
· `zero
· (ƛ suc (` Z))
· zero
—→⟨ ξ-·₁ (β-ƛ V-ƛ) ⟩
(ƛ (ƛ ` (S Z) · (` (S Z) · ` Z))) · (ƛ `suc ` Z) ·
((ƛ (ƛ ` (S Z) · (` (S Z) · ` Z))) · (ƛ `suc ` Z) · ` Z))
· `zero
(ƛ (ƛ ` (S Z) · (` (S Z) · ` Z))) · (ƛ suc (` Z)) ·
((ƛ (ƛ ` (S Z) · (` (S Z) · ` Z))) · (ƛ suc (` Z)) · ` Z))
· zero
—→⟨ β-ƛ V-zero ⟩
(ƛ (ƛ ` (S Z) · (` (S Z) · ` Z))) · (ƛ `suc ` Z) ·
((ƛ (ƛ ` (S Z) · (` (S Z) · ` Z))) · (ƛ `suc ` Z) · `zero)
(ƛ (ƛ ` (S Z) · (` (S Z) · ` Z))) · (ƛ suc (` Z)) ·
((ƛ (ƛ ` (S Z) · (` (S Z) · ` Z))) · (ƛ suc (` Z)) · zero)
—→⟨ ξ-·₁ (β-ƛ V-ƛ) ⟩
(ƛ (ƛ `suc ` Z) · ((ƛ `suc ` Z) · ` Z)) ·
((ƛ (ƛ ` (S Z) · (` (S Z) · ` Z))) · (ƛ `suc ` Z) · `zero)
(ƛ (ƛ suc (` Z)) · ((ƛ suc (` Z)) · ` Z)) ·
((ƛ (ƛ ` (S Z) · (` (S Z) · ` Z))) · (ƛ suc (` Z)) · zero)
—→⟨ ξ-·₂ V-ƛ (ξ-·₁ (β-ƛ V-ƛ)) ⟩
(ƛ (ƛ `suc ` Z) · ((ƛ `suc ` Z) · ` Z)) ·
((ƛ (ƛ `suc ` Z) · ((ƛ `suc ` Z) · ` Z)) · `zero)
(ƛ (ƛ suc (` Z)) · ((ƛ suc (` Z)) · ` Z)) ·
((ƛ (ƛ suc (` Z)) · ((ƛ suc (` Z)) · ` Z)) · zero)
—→⟨ ξ-·₂ V-ƛ (β-ƛ V-zero) ⟩
(ƛ (ƛ `suc ` Z) · ((ƛ `suc ` Z) · ` Z)) ·
((ƛ `suc ` Z) · ((ƛ `suc ` Z) · `zero))
(ƛ (ƛ suc (` Z)) · ((ƛ suc (` Z)) · ` Z)) ·
((ƛ suc (` Z)) · ((ƛ suc (` Z)) · zero))
—→⟨ ξ-·₂ V-ƛ (ξ-·₂ V-ƛ (β-ƛ V-zero)) ⟩
(ƛ (ƛ `suc ` Z) · ((ƛ `suc ` Z) · ` Z)) ·
((ƛ `suc ` Z) · `suc `zero)
(ƛ (ƛ suc (` Z)) · ((ƛ suc (` Z)) · ` Z)) ·
((ƛ suc (` Z)) · suc zero)
—→⟨ ξ-·₂ V-ƛ (β-ƛ (V-suc V-zero)) ⟩
(ƛ (ƛ `suc ` Z) · ((ƛ `suc ` Z) · ` Z)) · `suc (`suc `zero)
(ƛ (ƛ suc (` Z)) · ((ƛ suc (` Z)) · ` Z)) · suc (suc zero)
—→⟨ β-ƛ (V-suc (V-suc V-zero)) ⟩
`suc ` Z) · ((ƛ `suc ` Z) · `suc (`suc `zero))
(ƛ suc (` Z)) · ((ƛ suc (` Z)) · suc (suc zero))
—→⟨ ξ-·₂ V-ƛ (β-ƛ (V-suc (V-suc V-zero))) ⟩
`suc ` Z) · `suc (`suc (`suc `zero))
(ƛ suc (` Z)) · suc (suc (suc zero))
—→⟨ β-ƛ (V-suc (V-suc (V-suc V-zero))) ⟩
`suc (`suc (`suc (`suc `zero)))
suc (suc (suc (suc zero)))
∎)
(done (V-suc (V-suc (V-suc (V-suc V-zero)))))
_ = refl

View file

@ -192,8 +192,8 @@ We can extract the grammar for terms from the above:
L⁻, M⁻, N⁻ ::= terms with inherited type
ƛ x ⇒ N abstraction
`zero zero
`suc M⁻ successor
zero zero
suc M⁻ successor
case L⁺ [zero⇒ M⁻ |suc x ⇒ N⁻ ] case
μ x ⇒ N fixpoint
M ↑ switch to synthesized
@ -290,7 +290,6 @@ infix 5 μ_⇒_
infix 6 _↑
infix 6 _↓_
infixl 7 _·_
infix 8 `suc_
infix 9 `_
```
@ -324,8 +323,8 @@ data Term⁺ where
data Term⁻ where
ƛ_⇒_ : Id → Term⁻ → Term⁻
`zero : Term⁻
`suc_ : Term⁻ → Term⁻
zero : Term⁻
suc : Term⁻ → Term⁻
`case_[zero⇒_|suc_⇒_] : Term⁺ → Term⁻ → Id → Term⁻ → Term⁻
μ_⇒_ : Id → Term⁻ → Term⁻
_↑ : Term⁺ → Term⁻
@ -342,12 +341,12 @@ We can recreate the examples from preceding chapters.
First, computing two plus two on naturals:
```
two : Term⁻
two = `suc (`suc `zero)
two = suc (suc zero)
plus : Term⁺
plus = (μ "p" ⇒ ƛ "m" ⇒ ƛ "n" ⇒
`case (` "m") [zero⇒ ` "n" ↑
|suc "m" ⇒ `suc (` "p" · (` "m" ↑) · (` "n" ↑) ↑) ])
|suc "m" ⇒ suc (` "p" · (` "m" ↑) · (` "n" ↑) ↑) ])
↓ (`` ⇒ `)
2+2 : Term⁺
@ -370,10 +369,10 @@ plusᶜ = (ƛ "m" ⇒ ƛ "n" ⇒ ƛ "s" ⇒ ƛ "z" ⇒
↓ (Ch ⇒ Ch ⇒ Ch)
sucᶜ : Term⁻
sucᶜ = ƛ "x" ⇒ `suc (` "x" ↑)
sucᶜ = ƛ "x" ⇒ suc (` "x" ↑)
2+2ᶜ : Term⁺
2+2ᶜ = plusᶜ · twoᶜ · twoᶜ · sucᶜ · `zero
2+2ᶜ = plusᶜ · twoᶜ · twoᶜ · sucᶜ · zero
```
The only type decoration required is for `plusᶜ`. One is not even
required for `sucᶜ`, which inherits its type as an argument of `plusᶜ`.
@ -429,12 +428,12 @@ data _⊢_↓_ where
⊢zero : ∀ {Γ}
--------------
→ Γ ⊢ `zero ↓ `
→ Γ ⊢ zero ↓ `
⊢suc : ∀ {Γ M}
→ Γ ⊢ M ↓ `
---------------
→ Γ ⊢ `suc M ↓ `
→ Γ ⊢ suc M ↓ `
⊢case : ∀ {Γ L M x N A}
→ Γ ⊢ L ↑ `
@ -763,12 +762,12 @@ inherit Γ (ƛ x ⇒ N) ` = no (λ())
inherit Γ (ƛ x ⇒ N) (A ⇒ B) with inherit (Γ , x ⦂ A) N B
... | no ¬⊢N = no (λ{ (⊢ƛ ⊢N) → ¬⊢N ⊢N })
... | yes ⊢N = yes (⊢ƛ ⊢N)
inherit Γ `zero ` = yes ⊢zero
inherit Γ `zero (A ⇒ B) = no (λ())
inherit Γ (`suc M) ` with inherit Γ M `
inherit Γ zero ` = yes ⊢zero
inherit Γ zero (A ⇒ B) = no (λ())
inherit Γ (suc M) ` with inherit Γ M `
... | no ¬⊢M = no (λ{ (⊢suc ⊢M) → ¬⊢M ⊢M })
... | yes ⊢M = yes (⊢suc ⊢M)
inherit Γ (`suc M) (A ⇒ B) = no (λ())
inherit Γ (suc M) (A ⇒ B) = no (λ())
inherit Γ (`case L [zero⇒ M |suc x ⇒ N ]) A with synthesize Γ L
... | no ¬∃ = no (λ{ (⊢case ⊢L _ _) → ¬∃ ⟨ ` , ⊢L ⟩})
... | yes ⟨ _ ⇒ _ , ⊢L ⟩ = no (λ{ (⊢case ⊢L _ _) → ℕ≢⇒ (uniq-↑ ⊢L ⊢L) })
@ -961,7 +960,7 @@ _ = refl
Zero inherits a function type:
```
_ : synthesize ∅ (`zero ↓ ` ⇒ `) ≡ no _
_ : synthesize ∅ (zero ↓ ` ⇒ `) ≡ no _
_ = refl
```
@ -973,21 +972,21 @@ _ = refl
Successor of an ill-typed term:
```
_ : synthesize ∅ (`suc twoᶜ ↓ `) ≡ no _
_ : synthesize ∅ (suc twoᶜ ↓ `) ≡ no _
_ = refl
```
Case of a term with a function type:
```
_ : synthesize ∅
((`case (twoᶜ ↓ Ch) [zero⇒ `zero |suc "x" ⇒ ` "x" ↑ ] ↓ `) ) ≡ no _
((`case (twoᶜ ↓ Ch) [zero⇒ zero |suc "x" ⇒ ` "x" ↑ ] ↓ `) ) ≡ no _
_ = refl
```
Case of an ill-typed term:
```
_ : synthesize ∅
((`case (twoᶜ ↓ `) [zero⇒ `zero |suc "x" ⇒ ` "x" ↑ ] ↓ `) ) ≡ no _
((`case (twoᶜ ↓ `) [zero⇒ zero |suc "x" ⇒ ` "x" ↑ ] ↓ `) ) ≡ no _
_ = refl
```
@ -1043,8 +1042,8 @@ there are two mutually recursive erasure functions:
∥ ⊢↓ ⊢M ∥⁺ = ∥ ⊢M ∥⁻
∥ ⊢ƛ ⊢N ∥⁻ = DB.ƛ ∥ ⊢N ∥⁻
∥ ⊢zero ∥⁻ = DB.`zero
∥ ⊢suc ⊢M ∥⁻ = DB.`suc ∥ ⊢M ∥⁻
∥ ⊢zero ∥⁻ = DB.zero
∥ ⊢suc ⊢M ∥⁻ = DB.suc ∥ ⊢M ∥⁻
∥ ⊢case ⊢L ⊢M ⊢N ∥⁻ = DB.case ∥ ⊢L ∥⁺ ∥ ⊢M ∥⁻ ∥ ⊢N ∥⁻
∥ ⊢μ ⊢M ∥⁻ = DB.μ ∥ ⊢M ∥⁻
∥ ⊢↑ ⊢M refl ∥⁻ = ∥ ⊢M ∥⁺

View file

@ -71,8 +71,8 @@ Terms have seven constructs. Three are for the core lambda calculus:
Three are for the naturals:
* Zero `` `zero ``
* Successor `` `suc ``
* Zero `` zero ``
* Successor `` suc ``
* Case `` case L [zero⇒ M |suc x ⇒ N ] ``
And one is for recursion:
@ -93,7 +93,7 @@ Here is the syntax of terms in Backus-Naur Form (BNF):
L, M, N ::=
` x | ƛ x ⇒ N | L · M |
`zero | `suc M | case L [zero⇒ M |suc x ⇒ N ] |
zero | suc M | case L [zero⇒ M |suc x ⇒ N ] |
μ x ⇒ M
And here it is formalised in Agda:
@ -104,15 +104,14 @@ Id = String
infix 5 ƛ_⇒_
infix 5 μ_⇒_
infixl 7 _·_
infix 8 `suc_
infix 9 `_
data Term : Set where
`_ : Id → Term
ƛ_⇒_ : Id → Term → Term
_·_ : Term → Term → Term
`zero : Term
`suc_ : Term → Term
zero : Term
suc : Term → Term
case_[zero⇒_|suc_⇒_] : Term → Term → Id → Term → Term
μ_⇒_ : Id → Term → Term
```
@ -129,13 +128,13 @@ a function that adds naturals,
and a term that computes two plus two:
```
two : Term
two = `suc `suc `zero
two = suc (suc zero)
plus : Term
plus = μ "+" ⇒ ƛ "m" ⇒ ƛ "n" ⇒
case ` "m"
[zero⇒ ` "n"
|suc "m" ⇒ `suc (` "+" · ` "m" · ` "n") ]
|suc "m" ⇒ suc (` "+" · ` "m" · ` "n") ]
```
The recursive definition of addition is similar to our original
definition of `_+_` for naturals, as given in
@ -149,7 +148,7 @@ the term
plus · two · two
reduces to `` `suc `suc `suc `suc `zero ``.
reduces to `` suc (suc (suc (suc zero))) ``.
As a second example, we use higher-order functions to represent
natural numbers. In particular, the number _n_ is represented by a
@ -167,7 +166,7 @@ plusᶜ = ƛ "m" ⇒ ƛ "n" ⇒ ƛ "s" ⇒ ƛ "z" ⇒
` "m" · ` "s" · (` "n" · ` "s" · ` "z")
sucᶜ : Term
sucᶜ = ƛ "n" ⇒ `suc (` "n")
sucᶜ = ƛ "n" ⇒ suc (` "n")
```
The Church numeral for two takes two arguments `s` and `z`
and applies `s` twice to `z`.
@ -177,13 +176,13 @@ result of using `n` to apply `s` to `z`; hence `s` is applied `m` plus
`n` times to `z`, yielding the Church numeral for the sum of `m` and
`n`. For convenience, we define a function that computes successor.
To convert a Church numeral to the corresponding natural, we apply
it to the `sucᶜ` function and the natural number zero.
it to the sucᶜ` function and the natural number zero.
Again, later we will confirm that two plus two is four,
in other words that the term
plusᶜ · twoᶜ · twoᶜ · sucᶜ · `zero
plusᶜ · twoᶜ · twoᶜ · sucᶜ · zero
reduces to `` `suc `suc `suc `suc `zero ``.
reduces to `` suc (suc (suc (suc zero))) ``.
#### Exercise `mul` (recommended)
@ -236,7 +235,7 @@ plus : Term
plus = μ′ + ⇒ ƛ′ m ⇒ ƛ′ n ⇒
case m
[zero⇒ n
|suc m ⇒ `suc (+ · m · n) ]
|suc m ⇒ suc (+ · m · n) ]
where
+ = ` "+"
m = ` "m"
@ -258,7 +257,9 @@ _meta-language_ (the language in which the description is written),
trusting readers can use context to distinguish the two. Agda is
not quite so forgiving, so here we use `ƛ x ⇒ N` and `L · M` for the
object language, as compared to `λ x → N` and `L M` in our
meta-language, Agda.
meta-language, Agda. We use `zero` and `suc` for both the object
language and the meta-language, using Agda's ability to overload
constructors to distinguish the two.
### Bound and free variables
@ -316,7 +317,7 @@ to alpha renaming. In the term
μ "+" ⇒ ƛ "m" ⇒ ƛ "n" ⇒
case ` "m"
[zero⇒ ` "n"
|suc "m" ⇒ `suc (` "+" · ` "m" · ` "n") ]
|suc "m" ⇒ suc (` "+" · ` "m" · ` "n") ]
notice that there are two binding occurrences of `m`, one in the first
line and one in the last line. It is equivalent to the following term,
@ -324,7 +325,7 @@ line and one in the last line. It is equivalent to the following term,
μ "plus" ⇒ ƛ "x" ⇒ ƛ "y" ⇒
case ` "x"
[zero⇒ ` "y"
|suc "x" ⇒ `suc (` "plus" · ` "x" · ` "y") ]
|suc "x" ⇒ suc (` "plus" · ` "x" · ` "y") ]
where the two binding occurrences corresponding to `m` now have distinct
names, `x` and `x`.
@ -333,7 +334,7 @@ names, `x` and `x`.
## Values
A _value_ is a term that corresponds to an answer.
Thus, `` `suc `suc `suc `suc `zero `` is a value,
Thus, `` suc (suc (suc (suc zero))) `` is a value,
while `` plus · two · two `` is not.
Following convention, we treat all function abstractions
as values; thus, `` plus `` by itself is considered a value.
@ -349,12 +350,12 @@ data Value : Term → Set where
V-zero :
-----------
Value `zero
Value zero
V-suc : ∀ {V}
→ Value V
--------------
→ Value (`suc V)
→ Value (suc V)
```
In what follows, we let `V` and `W` range over values.
@ -385,13 +386,13 @@ Substitution plays a key role in defining the
operational semantics of function application.
For instance, we have
(ƛ "s" ⇒ ƛ "z" ⇒ ` "s" · (` "s" · ` "z")) · sucᶜ · `zero
(ƛ "s" ⇒ ƛ "z" ⇒ ` "s" · (` "s" · ` "z")) · sucᶜ · zero
—→
(ƛ "z" ⇒ sucᶜ · (sucᶜ · "z")) · `zero
(ƛ "z" ⇒ sucᶜ · (sucᶜ · "z")) · zero
—→
sucᶜ · (sucᶜ · `zero)
sucᶜ · (sucᶜ · zero)
where we substitute `sucᶜ` for `` ` "s" `` and `` `zero `` for `` ` "z" ``
where we substitute sucᶜ` for `` ` "s" `` and `` zero `` for `` ` "z" ``
in the body of the function abstraction.
We write substitution as `N [ x := V ]`, meaning
@ -406,14 +407,14 @@ Here are some examples:
* `` (ƛ "z" ⇒ ` "s" · (` "s" · ` "z")) [ "s" := sucᶜ ] `` yields
`` ƛ "z" ⇒ sucᶜ · (sucᶜ · ` "z") ``.
* `` (sucᶜ · (sucᶜ · ` "z")) [ "z" := `zero ] `` yields
`` sucᶜ · (sucᶜ · `zero) ``.
* `` (ƛ "x" ⇒ ` "y") [ "y" := `zero ] `` yields `` ƛ "x" ⇒ `zero ``.
* `` (ƛ "x" ⇒ ` "x") [ "x" := `zero ] `` yields `` ƛ "x" ⇒ ` "x" ``.
* `` (ƛ "y" ⇒ ` "y") [ "x" := `zero ] `` yields `` ƛ "y" ⇒ ` "y" ``.
* `` (sucᶜ · (sucᶜ · ` "z")) [ "z" := zero ] `` yields
`` sucᶜ · (sucᶜ · zero) ``.
* `` (ƛ "x" ⇒ ` "y") [ "y" := zero ] `` yields `` ƛ "x" ⇒ zero ``.
* `` (ƛ "x" ⇒ ` "x") [ "x" := zero ] `` yields `` ƛ "x" ⇒ ` "x" ``.
* `` (ƛ "y" ⇒ ` "y") [ "x" := zero ] `` yields `` ƛ "y" ⇒ ` "y" ``.
In the last but one example, substituting `` `zero `` for `x` in
`` ƛ "x" ⇒ ` "x" `` does _not_ yield `` ƛ "x" ⇒ `zero ``,
In the last but one example, substituting `` zero `` for `x` in
`` ƛ "x" ⇒ ` "x" `` does _not_ yield `` ƛ "x" ⇒ zero ``,
since `x` is bound in the lambda abstraction.
The choice of bound names is irrelevant: both
`` ƛ "x" ⇒ ` "x" `` and `` ƛ "y" ⇒ ` "y" `` stand for the
@ -426,13 +427,13 @@ when term substituted for the variable is closed. This is because
substitution by terms that are _not_ closed may require renaming
of bound variables. For example:
* `` (ƛ "x" ⇒ ` "x" · ` "y") [ "y" := ` "x" · `zero] `` should not yield <br/>
`` (ƛ "x" ⇒ ` "x" · (` "x" · `zero)) ``.
* `` (ƛ "x" ⇒ ` "x" · ` "y") [ "y" := ` "x" · zero] `` should not yield <br/>
`` (ƛ "x" ⇒ ` "x" · (` "x" · zero)) ``.
Instead, we should rename the bound variable to avoid capture:
* `` (ƛ "x" ⇒ ` "x" · ` "y") [ "y" := ` "x" · `zero ] `` should yield <br/>
`` ƛ "x" ⇒ ` "x" · (` "x" · `zero) ``.
* `` (ƛ "x" ⇒ ` "x" · ` "y") [ "y" := ` "x" · zero ] `` should yield <br/>
`` ƛ "x" ⇒ ` "x" · (` "x" · zero) ``.
Here `x` is a fresh variable distinct from `x`.
Formal definition of substitution with suitable renaming is considerably
@ -450,13 +451,13 @@ _[_:=_] : Term → Id → Term → Term
... | no _ = ` x
(ƛ x ⇒ N) [ y := V ] with x ≟ y
... | yes _ = ƛ x ⇒ N
... | no _ = ƛ x ⇒ N [ y := V ]
(L · M) [ y := V ] = L [ y := V ] · M [ y := V ]
(`zero) [ y := V ] = `zero
(`suc M) [ y := V ] = `suc M [ y := V ]
... | no _ = ƛ x ⇒ (N [ y := V ])
(L · M) [ y := V ] = (L [ y := V ]) · (M [ y := V ])
(zero) [ y := V ] = zero
(suc M) [ y := V ] = suc (M [ y := V ])
(case L [zero⇒ M |suc x ⇒ N ]) [ y := V ] with x ≟ y
... | yes _ = case L [ y := V ] [zero⇒ M [ y := V ] |suc x ⇒ N ]
... | no _ = case L [ y := V ] [zero⇒ M [ y := V ] |suc x ⇒ N [ y := V ] ]
... | yes _ = case (L [ y := V ]) [zero⇒ (M [ y := V ]) |suc x ⇒ N ]
... | no _ = case (L [ y := V ]) [zero⇒ (M [ y := V ]) |suc x ⇒ (N [ y := V ]) ]
(μ x ⇒ N) [ y := V ] with x ≟ y
... | yes _ = μ x ⇒ N
... | no _ = μ x ⇒ N [ y := V ]
@ -488,16 +489,16 @@ Here is confirmation that the examples above are correct:
_ : (ƛ "z" ⇒ ` "s" · (` "s" · ` "z")) [ "s" := sucᶜ ] ≡ ƛ "z" ⇒ sucᶜ · (sucᶜ · ` "z")
_ = refl
_ : (sucᶜ · (sucᶜ · ` "z")) [ "z" := `zero ] ≡ sucᶜ · (sucᶜ · `zero)
_ : (sucᶜ · (sucᶜ · ` "z")) [ "z" := zero ] ≡ sucᶜ · (sucᶜ · zero)
_ = refl
_ : (ƛ "x" ⇒ ` "y") [ "y" := `zero ] ≡ ƛ "x" ⇒ `zero
_ : (ƛ "x" ⇒ ` "y") [ "y" := zero ] ≡ ƛ "x" ⇒ zero
_ = refl
_ : (ƛ "x" ⇒ ` "x") [ "x" := `zero ] ≡ ƛ "x" ⇒ ` "x"
_ : (ƛ "x" ⇒ ` "x") [ "x" := zero ] ≡ ƛ "x" ⇒ ` "x"
_ = refl
_ : (ƛ "y" ⇒ ` "y") [ "x" := `zero ] ≡ ƛ "y" ⇒ ` "y"
_ : (ƛ "y" ⇒ ` "y") [ "x" := zero ] ≡ ƛ "y" ⇒ ` "y"
_ = refl
```
@ -506,12 +507,12 @@ _ = refl
What is the result of the following substitution?
(ƛ "y" ⇒ ` "x" · (ƛ "x" ⇒ ` "x")) [ "x" := `zero ]
(ƛ "y" ⇒ ` "x" · (ƛ "x" ⇒ ` "x")) [ "x" := zero ]
1. `` (ƛ "y" ⇒ ` "x" · (ƛ "x" ⇒ ` "x")) ``
2. `` (ƛ "y" ⇒ ` "x" · (ƛ "x" ⇒ `zero)) ``
3. `` (ƛ "y" ⇒ `zero · (ƛ "x" ⇒ ` "x")) ``
4. `` (ƛ "y" ⇒ `zero · (ƛ "x" ⇒ `zero)) ``
2. `` (ƛ "y" ⇒ ` "x" · (ƛ "x" ⇒ zero)) ``
3. `` (ƛ "y" ⇒ zero · (ƛ "x" ⇒ ` "x")) ``
4. `` (ƛ "y" ⇒ zero · (ƛ "x" ⇒ zero)) ``
#### Exercise `_[_:=_]` (stretch)
@ -604,7 +605,7 @@ data _—→_ : Term → Term → Set where
ξ-suc : ∀ {M M}
→ M —→ M
------------------
`suc M —→ `suc M
→ suc M —→ suc M
ξ-case : ∀ {x L L M N}
→ L —→ L
@ -613,12 +614,12 @@ data _—→_ : Term → Term → Set where
β-zero : ∀ {x M N}
----------------------------------------
→ case `zero [zero⇒ M |suc x ⇒ N ] —→ M
→ case zero [zero⇒ M |suc x ⇒ N ] —→ M
β-suc : ∀ {x V M N}
→ Value V
---------------------------------------------------
→ case `suc V [zero⇒ M |suc x ⇒ N ] —→ N [ x := V ]
→ case suc V [zero⇒ M |suc x ⇒ N ] —→ N [ x := V ]
β-μ : ∀ {x M}
------------------------------
@ -660,14 +661,14 @@ What does the following term step to?
2. `` (ƛ "x" ⇒ ` "x") · (ƛ "x" ⇒ ` "x") ``
3. `` (ƛ "x" ⇒ ` "x") · (ƛ "x" ⇒ ` "x") · (ƛ "x" ⇒ ` "x") ``
What does the following term step to? (Where `twoᶜ` and `sucᶜ` are as
What does the following term step to? (Where `twoᶜ` and sucᶜ` are as
defined above.)
twoᶜ · sucᶜ · `zero —→ ???
twoᶜ · sucᶜ · zero —→ ???
1. `` sucᶜ · (sucᶜ · `zero) ``
2. `` (ƛ "z" ⇒ sucᶜ · (sucᶜ · ` "z")) · `zero ``
3. `` `zero ``
1. `` sucᶜ · (sucᶜ · zero) ``
2. `` (ƛ "z" ⇒ sucᶜ · (sucᶜ · ` "z")) · zero ``
3. `` zero ``
## Reflexive and transitive closure
@ -804,98 +805,98 @@ systems studied in this text are trivially confluent.
We start with a simple example. The Church numeral two applied to the
successor function and zero yields the natural number two:
```
_ : twoᶜ · sucᶜ · `zero —↠ `suc `suc `zero
_ : twoᶜ · sucᶜ · zero —↠ suc (suc zero)
_ =
begin
twoᶜ · sucᶜ · `zero
twoᶜ · sucᶜ · zero
—→⟨ ξ-·₁ (β-ƛ V-ƛ) ⟩
(ƛ "z" ⇒ sucᶜ · (sucᶜ · ` "z")) · `zero
(ƛ "z" ⇒ sucᶜ · (sucᶜ · ` "z")) · zero
—→⟨ β-ƛ V-zero ⟩
sucᶜ · (sucᶜ · `zero)
sucᶜ · (sucᶜ · zero)
—→⟨ ξ-·₂ V-ƛ (β-ƛ V-zero) ⟩
sucᶜ · `suc `zero
sucᶜ · suc zero
—→⟨ β-ƛ (V-suc V-zero) ⟩
`suc (`suc `zero)
suc (suc zero)
```
Here is a sample reduction demonstrating that two plus two is four:
```
_ : plus · two · two —↠ `suc `suc `suc `suc `zero
_ : plus · two · two —↠ suc (suc (suc (suc zero)))
_ =
begin
plus · two · two
—→⟨ ξ-·₁ (ξ-·₁ β-μ) ⟩
(ƛ "m" ⇒ ƛ "n" ⇒
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ `suc (plus · ` "m" · ` "n") ])
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ suc (plus · ` "m" · ` "n") ])
· two · two
—→⟨ ξ-·₁ (β-ƛ (V-suc (V-suc V-zero))) ⟩
(ƛ "n" ⇒
case two [zero⇒ ` "n" |suc "m" ⇒ `suc (plus · ` "m" · ` "n") ])
case two [zero⇒ ` "n" |suc "m" ⇒ suc (plus · ` "m" · ` "n") ])
· two
—→⟨ β-ƛ (V-suc (V-suc V-zero)) ⟩
case two [zero⇒ two |suc "m" ⇒ `suc (plus · ` "m" · two) ]
case two [zero⇒ two |suc "m" ⇒ suc (plus · ` "m" · two) ]
—→⟨ β-suc (V-suc V-zero) ⟩
`suc (plus · `suc `zero · two)
suc (plus · suc zero · two)
—→⟨ ξ-suc (ξ-·₁ (ξ-·₁ β-μ)) ⟩
`suc ((ƛ "m" ⇒ ƛ "n" ⇒
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ `suc (plus · ` "m" · ` "n") ])
· `suc `zero · two)
suc ((ƛ "m" ⇒ ƛ "n" ⇒
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ suc (plus · ` "m" · ` "n") ])
· suc zero · two)
—→⟨ ξ-suc (ξ-·₁ (β-ƛ (V-suc V-zero))) ⟩
`suc ((ƛ "n" ⇒
case `suc `zero [zero⇒ ` "n" |suc "m" ⇒ `suc (plus · ` "m" · ` "n") ])
suc ((ƛ "n" ⇒
case suc zero [zero⇒ ` "n" |suc "m" ⇒ suc (plus · ` "m" · ` "n") ])
· two)
—→⟨ ξ-suc (β-ƛ (V-suc (V-suc V-zero))) ⟩
`suc (case `suc `zero [zero⇒ two |suc "m" ⇒ `suc (plus · ` "m" · two) ])
suc (case suc zero [zero⇒ two |suc "m" ⇒ suc (plus · ` "m" · two) ])
—→⟨ ξ-suc (β-suc V-zero) ⟩
`suc `suc (plus · `zero · two)
suc (suc (plus · zero · two))
—→⟨ ξ-suc (ξ-suc (ξ-·₁ (ξ-·₁ β-μ))) ⟩
`suc `suc ((ƛ "m" ⇒ ƛ "n" ⇒
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ `suc (plus · ` "m" · ` "n") ])
· `zero · two)
suc (suc ((ƛ "m" ⇒ ƛ "n" ⇒
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ suc (plus · ` "m" · ` "n") ])
· zero · two))
—→⟨ ξ-suc (ξ-suc (ξ-·₁ (β-ƛ V-zero))) ⟩
`suc `suc ((ƛ "n" ⇒
case `zero [zero⇒ ` "n" |suc "m" ⇒ `suc (plus · ` "m" · ` "n") ])
· two)
suc (suc ((ƛ "n" ⇒
case zero [zero⇒ ` "n" |suc "m" ⇒ suc (plus · ` "m" · ` "n") ])
· two))
—→⟨ ξ-suc (ξ-suc (β-ƛ (V-suc (V-suc V-zero)))) ⟩
`suc `suc (case `zero [zero⇒ two |suc "m" ⇒ `suc (plus · ` "m" · two) ])
suc (suc (case zero [zero⇒ two |suc "m" ⇒ suc (plus · ` "m" · two) ]))
—→⟨ ξ-suc (ξ-suc β-zero) ⟩
`suc (`suc (`suc (`suc `zero)))
suc (suc (suc (suc zero)))
```
And here is a similar sample reduction for Church numerals:
```
_ : plusᶜ · twoᶜ · twoᶜ · sucᶜ · `zero —↠ `suc `suc `suc `suc `zero
_ : plusᶜ · twoᶜ · twoᶜ · sucᶜ · zero —↠ suc (suc (suc (suc zero)))
_ =
begin
(ƛ "m" ⇒ ƛ "n" ⇒ ƛ "s" ⇒ ƛ "z" ⇒ ` "m" · ` "s" · (` "n" · ` "s" · ` "z"))
· twoᶜ · twoᶜ · sucᶜ · `zero
· twoᶜ · twoᶜ · sucᶜ · zero
—→⟨ ξ-·₁ (ξ-·₁ (ξ-·₁ (β-ƛ V-ƛ))) ⟩
(ƛ "n" ⇒ ƛ "s" ⇒ ƛ "z" ⇒ twoᶜ · ` "s" · (` "n" · ` "s" · ` "z"))
· twoᶜ · sucᶜ · `zero
· twoᶜ · sucᶜ · zero
—→⟨ ξ-·₁ (ξ-·₁ (β-ƛ V-ƛ)) ⟩
(ƛ "s" ⇒ ƛ "z" ⇒ twoᶜ · ` "s" · (twoᶜ · ` "s" · ` "z")) · sucᶜ · `zero
(ƛ "s" ⇒ ƛ "z" ⇒ twoᶜ · ` "s" · (twoᶜ · ` "s" · ` "z")) · sucᶜ · zero
—→⟨ ξ-·₁ (β-ƛ V-ƛ) ⟩
(ƛ "z" ⇒ twoᶜ · sucᶜ · (twoᶜ · sucᶜ · ` "z")) · `zero
(ƛ "z" ⇒ twoᶜ · sucᶜ · (twoᶜ · sucᶜ · ` "z")) · zero
—→⟨ β-ƛ V-zero ⟩
twoᶜ · sucᶜ · (twoᶜ · sucᶜ · `zero)
twoᶜ · sucᶜ · (twoᶜ · sucᶜ · zero)
—→⟨ ξ-·₁ (β-ƛ V-ƛ) ⟩
(ƛ "z" ⇒ sucᶜ · (sucᶜ · ` "z")) · (twoᶜ · sucᶜ · `zero)
(ƛ "z" ⇒ sucᶜ · (sucᶜ · ` "z")) · (twoᶜ · sucᶜ · zero)
—→⟨ ξ-·₂ V-ƛ (ξ-·₁ (β-ƛ V-ƛ)) ⟩
(ƛ "z" ⇒ sucᶜ · (sucᶜ · ` "z")) · ((ƛ "z" ⇒ sucᶜ · (sucᶜ · ` "z")) · `zero)
(ƛ "z" ⇒ sucᶜ · (sucᶜ · ` "z")) · ((ƛ "z" ⇒ sucᶜ · (sucᶜ · ` "z")) · zero)
—→⟨ ξ-·₂ V-ƛ (β-ƛ V-zero) ⟩
(ƛ "z" ⇒ sucᶜ · (sucᶜ · ` "z")) · (sucᶜ · (sucᶜ · `zero))
(ƛ "z" ⇒ sucᶜ · (sucᶜ · ` "z")) · (sucᶜ · (sucᶜ · zero))
—→⟨ ξ-·₂ V-ƛ (ξ-·₂ V-ƛ (β-ƛ V-zero)) ⟩
(ƛ "z" ⇒ sucᶜ · (sucᶜ · ` "z")) · (sucᶜ · (`suc `zero))
(ƛ "z" ⇒ sucᶜ · (sucᶜ · ` "z")) · (sucᶜ · suc zero)
—→⟨ ξ-·₂ V-ƛ (β-ƛ (V-suc V-zero)) ⟩
(ƛ "z" ⇒ sucᶜ · (sucᶜ · ` "z")) · (`suc `suc `zero)
(ƛ "z" ⇒ sucᶜ · (sucᶜ · ` "z")) · suc (suc zero)
—→⟨ β-ƛ (V-suc (V-suc V-zero)) ⟩
sucᶜ · (sucᶜ · `suc `suc `zero)
sucᶜ · (sucᶜ · suc (suc zero))
—→⟨ ξ-·₂ V-ƛ (β-ƛ (V-suc (V-suc V-zero))) ⟩
sucᶜ · (`suc `suc `suc `zero)
sucᶜ · suc (suc (suc zero))
—→⟨ β-ƛ (V-suc (V-suc (V-suc V-zero))) ⟩
`suc (`suc (`suc (`suc `zero)))
suc (suc (suc (suc zero)))
```
@ -916,13 +917,13 @@ Write out the reduction sequence demonstrating that one plus one is two.
We have just two types:
* Functions, `A ⇒ B`
* Naturals, `` ` ``
* Naturals, `` ``
As before, to avoid overlap we use variants of the names used by Agda.
Here is the syntax of types in BNF:
A, B, C ::= A ⇒ B | `
A, B, C ::= A ⇒ B |
And here it is formalised in Agda:
@ -941,34 +942,34 @@ currying. This is made more convenient by declaring `_⇒_` to
associate to the right and `_·_` to associate to the left.
Thus:
* ``(``) ⇒ ```` stands for ``((``) ⇒ (``))``.
* ``() ⇒ `` stands for ``(() ⇒ ())``.
* `plus · two · two` stands for `(plus · two) · two`.
### Quiz
* What is the type of the following term?
`` ƛ "s" ⇒ ` "s" · (` "s" · `zero) ``
`` ƛ "s" ⇒ ` "s" · (` "s" · zero) ``
1. `` (``) ⇒ (``) ``
2. `` (``) ⇒ ` ``
3. `` ` ⇒ (``) ``
4. `` ``` ``
5. `` `` ``
6. `` ` ``
1. `` () ⇒ () ``
2. `` () ⇒ ``
3. `` ⇒ () ``
4. `` ``
5. `` ``
6. `` ``
Give more than one answer if appropriate.
* What is the type of the following term?
`` (ƛ "s" ⇒ ` "s" · (` "s" · `zero)) · sucᶜ ``
`` (ƛ "s" ⇒ ` "s" · (` "s" · zero)) · sucᶜ ``
1. `` (``) ⇒ (``) ``
2. `` (``) ⇒ ` ``
3. `` ` ⇒ (``) ``
4. `` ``` ``
5. `` `` ``
6. `` ` ``
1. `` () ⇒ () ``
2. `` () ⇒ ``
3. `` ⇒ () ``
4. `` ``
5. `` ``
6. `` ``
Give more than one answer if appropriate.
@ -987,10 +988,10 @@ over contexts. We write `∅` for the empty context, and `Γ , x ⦂ A`
for the context that extends `Γ` by mapping variable `x` to type `A`.
For example,
* `` ∅ , "s" ⦂ `` , "z" ⦂ ` ``
* `` ∅ , "s" ⦂ , "z" ⦂ ``
is the context that associates variable `` "s" `` with type `` `` ``,
and variable `` "z" `` with type `` ` ``.
is the context that associates variable `` "s" `` with type `` ``,
and variable `` "z" `` with type `` ``.
Contexts are formalised as follows:
@ -1008,11 +1009,11 @@ data Context : Set where
Show that `Context` is isomorphic to `List (Id × Type)`.
For instance, the isomorphism relates the context
∅ , "s" ⦂ `` , "z" ⦂ `
∅ , "s" ⦂ , "z" ⦂
to the list
[ ⟨ "z" , ` ⟩ , ⟨ "s" , `` ⟩ ]
[ ⟨ "z" , ⟩ , ⟨ "s" , ⟩ ]
```
-- Your code goes here
@ -1028,8 +1029,8 @@ and indicates in context `Γ` that variable `x` has type `A`.
It is called _lookup_.
For example,
* `` ∅ , "s" ⦂ `` , "z" ⦂ ` ∋ "z" ⦂ ` ``
* `` ∅ , "s" ⦂ `` , "z" ⦂ ` ∋ "s" ⦂ `` ``
* `` ∅ , "s" ⦂ , "z" ⦂ ∋ "z" ⦂ ``
* `` ∅ , "s" ⦂ , "z" ⦂ ∋ "s" ⦂ ``
give us the types associated with variables `` "z" `` and `` "s" ``,
respectively. The symbol `∋` (pronounced "ni", for "in"
@ -1040,9 +1041,9 @@ If two variables in a context have the same name, then lookup
should return the most recently bound variable, which _shadows_
the other variables. For example,
* `` ∅ , "x" ⦂ `` , "x" ⦂ ` ∋ "x" ⦂ ` ``.
* `` ∅ , "x" ⦂ , "x" ⦂ ∋ "x" ⦂ ``.
Here `` "x" ⦂ `` `` is shadowed by `` "x" ⦂ ` ``.
Here `` "x" ⦂ `` is shadowed by `` "x" ⦂ ``.
Lookup is formalised as follows:
```
@ -1077,12 +1078,12 @@ and indicates in context `Γ` that term `M` has type `A`.
Context `Γ` provides types for all the free variables in `M`.
For example:
* `` ∅ , "s" ⦂ `` , "z" ⦂ ` ⊢ ` "z" ⦂ ` ``
* `` ∅ , "s" ⦂ `` , "z" ⦂ ` ⊢ ` "s" ⦂ `` ``
* `` ∅ , "s" ⦂ `` , "z" ⦂ ` ⊢ ` "s" · ` "z" ⦂ ` ``
* `` ∅ , "s" ⦂ `` , "z" ⦂ ` ⊢ ` "s" · (` "s" · ` "z") ⦂ ` ``
* `` ∅ , "s" ⦂ `` ⊢ ƛ "z" ⇒ ` "s" · (` "s" · ` "z") ⦂ `` ``
* `` ∅ ⊢ ƛ "s" ⇒ ƛ "z" ⇒ ` "s" · (` "s" · ` "z") ⦂ (``) ⇒ `` ``
* `` ∅ , "s" ⦂ , "z" ⦂ ` "z" ⦂ ``
* `` ∅ , "s" ⦂ , "z" ⦂ ` "s" ⦂ ``
* `` ∅ , "s" ⦂ , "z" ⦂ ` "s" · ` "z" ⦂ ``
* `` ∅ , "s" ⦂ , "z" ⦂ ` "s" · (` "s" · ` "z") ⦂ ``
* `` ∅ , "s" ⦂ ⊢ ƛ "z" ⇒ ` "s" · (` "s" · ` "z") ⦂ ``
* `` ∅ ⊢ ƛ "s" ⇒ ƛ "z" ⇒ ` "s" · (` "s" · ` "z") ⦂ () ⇒ ``
Typing is formalised as follows:
```
@ -1112,13 +1113,13 @@ data _⊢_⦂_ : Context → Term → Type → Set where
-- -I₁
⊢zero : ∀ {Γ}
--------------
→ Γ ⊢ `zero ⦂ `
→ Γ ⊢ zero ⦂ `
-- -I₂
⊢suc : ∀ {Γ M}
→ Γ ⊢ M ⦂ `
---------------
→ Γ ⊢ `suc M ⦂ `
→ Γ ⊢ suc M ⦂ `
-- -E
⊢case : ∀ {Γ L M x N A}
@ -1267,7 +1268,7 @@ And here are typings for the remainder of the Church example:
where
∋n = Z
⊢2+2ᶜ : ∅ ⊢ plusᶜ · twoᶜ · twoᶜ · sucᶜ · `zero ⦂ `
⊢2+2ᶜ : ∅ ⊢ plusᶜ · twoᶜ · twoᶜ · sucᶜ · zero ⦂ `
⊢2+2ᶜ = ⊢plusᶜ · ⊢twoᶜ · ⊢twoᶜ · ⊢sucᶜ · ⊢zero
```
@ -1285,11 +1286,11 @@ Typing C-c C-l causes Agda to create a hole and tell us its expected type:
?0 : ∅ ⊢ sucᶜ ⦂ ` ⇒ `
Now we fill in the hole by typing C-c C-r. Agda observes that
the outermost term in `sucᶜ` is `ƛ`, which is typed using `⊢ƛ`. The
the outermost term in sucᶜ` is `ƛ`, which is typed using `⊢ƛ`. The
`⊢ƛ` rule in turn takes one argument, which Agda leaves as a hole:
⊢sucᶜ = ⊢ƛ { }1
?1 : ∅ , "n" ⦂ ``suc ` "n" ⦂ `
?1 : ∅ , "n" ⦂ `suc ` "n" ⦂ `
We can fill in the hole by typing C-c C-r again:
@ -1334,12 +1335,12 @@ the term `ƛ "x" ⇒ "x"` has type `A ⇒ A` for any type `A`.
We can also show that terms are _not_ typeable. For example, here is
a formal proof that it is not possible to type the term
`` `zero · `suc `zero ``. It cannot be typed, because doing so
`` zero · suc zero ``. It cannot be typed, because doing so
requires that the first term in the application is both a natural and
a function:
```
nope₁ : ∀ {A} → ¬ (∅ ⊢ `zero · `suc `zero ⦂ A)
nope₁ : ∀ {A} → ¬ (∅ ⊢ zero · suc zero ⦂ A)
nope₁ (() · _)
```

View file

@ -155,19 +155,19 @@ construct to a calculus without the construct.
A `× B product type
L, M, N ::= ... Terms
`⟨ M , N ⟩ pair
⟨ M , N ⟩ pair
`proj₁ L project first component
`proj₂ L project second component
V, W ::= ... Values
`⟨ V , W ⟩ pair
⟨ V , W ⟩ pair
### Typing
Γ ⊢ M ⦂ A
Γ ⊢ N ⦂ B
----------------------- `⟨_,_⟩ or `×-I
Γ ⊢ `⟨ M , N ⟩ ⦂ A `× B
----------------------- ⟨_,_⟩ or `×-I
Γ ⊢ ⟨ M , N ⟩ ⦂ A `× B
Γ ⊢ L ⦂ A `× B
---------------- `proj₁ or `×-E₁
@ -181,11 +181,11 @@ construct to a calculus without the construct.
M —→ M
------------------------- ξ-⟨,⟩₁
`⟨ M , N ⟩ —→ `⟨ M , N ⟩
⟨ M , N ⟩ —→ ⟨ M , N ⟩
N —→ N
------------------------- ξ-⟨,⟩₂
`⟨ V , N ⟩ —→ `⟨ V , N
⟨ V , N ⟩ —→ ⟨ V , N
L —→ L
--------------------- ξ-proj₁
@ -196,17 +196,17 @@ construct to a calculus without the construct.
`proj₂ L —→ `proj₂ L
---------------------- β-proj₁
`proj₁ `⟨ V , W ⟩ —→ V
`proj₁ ⟨ V , W ⟩ —→ V
---------------------- β-proj₂
`proj₂ `⟨ V , W ⟩ —→ W
`proj₂ ⟨ V , W ⟩ —→ W
### Example
Here is a function to swap the components of a pair:
swap× : ∅ ⊢ A `× B ⇒ B `× A
swap× = ƛ z ⇒ `⟨ proj₂ z , proj₁ z ⟩
swap× = ƛ z ⇒ ⟨ proj₂ z , proj₁ z ⟩
## Alternative formulation of products
@ -222,11 +222,11 @@ and reduction rules:
A `× B product type
L, M, N ::= ... Terms
`⟨ M , N ⟩ pair
⟨ M , N ⟩ pair
case× L [⟨ x , y ⟩⇒ M ] case
V, W ::= Values
`⟨ V , W ⟩ pair
⟨ V , W ⟩ pair
### Typing
@ -242,7 +242,7 @@ and reduction rules:
case× L [⟨ x , y ⟩⇒ N ] —→ case× L [⟨ x , y ⟩⇒ N ]
--------------------------------------------------------- β-case×
case× `⟨ V , W ⟩ [⟨ x , y ⟩⇒ N ] —→ N [ x := V ][ y := W ]
case× ⟨ V , W ⟩ [⟨ x , y ⟩⇒ N ] —→ N [ x := V ][ y := W ]
### Example
@ -250,7 +250,7 @@ Here is a function to swap the components of a pair rewritten in the new notatio
swap×-case : ∅ ⊢ A `× B ⇒ B `× A
swap×-case = ƛ z ⇒ case× z
[⟨ x , y ⟩⇒ `⟨ y , x ⟩ ]
[⟨ x , y ⟩⇒ ⟨ y , x ⟩ ]
### Translation
@ -293,23 +293,23 @@ We can also translate back the other way:
A `⊎ B sum type
L, M, N ::= ... Terms
`inj₁ M inject first component
`inj₂ N inject second component
inj₁ M inject first component
inj₂ N inject second component
case⊎ L [inj₁ x ⇒ M |inj₂ y ⇒ N ] case
V, W ::= ... Values
`inj₁ V inject first component
`inj₂ W inject second component
inj₁ V inject first component
inj₂ W inject second component
### Typing
Γ ⊢ M ⦂ A
-------------------- `inj₁ or ⊎-I₁
Γ ⊢ `inj₁ M ⦂ A `⊎ B
-------------------- inj₁ or ⊎-I₁
Γ ⊢ inj₁ M ⦂ A `⊎ B
Γ ⊢ N ⦂ B
-------------------- `inj₂ or ⊎-I₂
Γ ⊢ `inj₂ N ⦂ A `⊎ B
-------------------- inj₂ or ⊎-I₂
Γ ⊢ inj₂ N ⦂ A `⊎ B
Γ ⊢ L ⦂ A `⊎ B
Γ , x ⦂ A ⊢ M ⦂ C
@ -321,21 +321,21 @@ We can also translate back the other way:
M —→ M
------------------- ξ-inj₁
`inj₁ M —→ `inj₁ M
inj₁ M —→ inj₁ M
N —→ N
------------------- ξ-inj₂
`inj₂ N —→ `inj₂ N
inj₂ N —→ inj₂ N
L —→ L
---------------------------------------------------------------------- ξ-case⊎
case⊎ L [inj₁ x ⇒ M |inj₂ y ⇒ N ] —→ case⊎ L [inj₁ x ⇒ M |inj₂ y ⇒ N ]
--------------------------------------------------------- β-inj₁
case⊎ (`inj₁ V) [inj₁ x ⇒ M |inj₂ y ⇒ N ] —→ M [ x := V ]
case⊎ (inj₁ V) [inj₁ x ⇒ M |inj₂ y ⇒ N ] —→ M [ x := V ]
--------------------------------------------------------- β-inj₂
case⊎ (`inj₂ W) [inj₁ x ⇒ M |inj₂ y ⇒ N ] —→ N [ y := W ]
case⊎ (inj₂ W) [inj₁ x ⇒ M |inj₂ y ⇒ N ] —→ N [ y := W ]
### Example
@ -343,8 +343,8 @@ Here is a function to swap the components of a sum:
swap⊎ : ∅ ⊢ A `⊎ B ⇒ B `⊎ A
swap⊎ = ƛ z ⇒ case⊎ z
[inj₁ x ⇒ `inj₂ x
|inj₂ y ⇒ `inj₁ y ]
[inj₁ x ⇒ inj₂ x
|inj₂ y ⇒ inj₁ y ]
## Unit type
@ -359,15 +359,15 @@ There are no reduction rules.
` unit type
L, M, N ::= ... Terms
`tt unit value
tt unit value
V, W ::= ... Values
`tt unit value
tt unit value
### Typing
------------ `tt or -I
Γ ⊢ `tt ⦂ `
----------- tt or -I
Γ ⊢ tt ⦂ `
### Reduction
@ -378,7 +378,7 @@ There are no reduction rules.
Here is the isomorphism between `A` and ``A `× ```:
to× : ∅ ⊢ A ⇒ A `× `
to× = ƛ x ⇒ `⟨ x , `tt ⟩
to× = ƛ x ⇒ ⟨ x , tt ⟩
from× : ∅ ⊢ A `× ` ⇒ A
from× = ƛ z ⇒ proj₁ z
@ -396,11 +396,11 @@ We repeat the syntax in full, but only give the new type and reduction rules:
` unit type
L, M, N ::= ... Terms
`tt unit value
tt unit value
`case L [tt⇒ N ] case
V, W ::= ... Values
`tt unit value
tt unit value
### Typing
@ -416,7 +416,7 @@ We repeat the syntax in full, but only give the new type and reduction rules:
case L [tt⇒ M ] —→ case L [tt⇒ M ]
----------------------- β-case
case `tt [tt⇒ M ] —→ M
case tt [tt⇒ M ] —→ M
### Example
@ -469,7 +469,7 @@ construct plays a role similar to `⊥-elim` in Agda:
Here is the isomorphism between `A` and ``A `⊎ `⊥``:
to⊎⊥ : ∅ ⊢ A ⇒ A `⊎ `
to⊎⊥ = ƛ x ⇒ `inj₁ x
to⊎⊥ = ƛ x ⇒ inj₁ x
from⊎⊥ : ∅ ⊢ A `⊎ `⊥ ⇒ A
from⊎⊥ = ƛ z ⇒ case⊎ z
@ -577,7 +577,6 @@ infix 5 ƛ_
infix 5 μ_
infixl 7 _·_
infixl 8 _`*_
infix 8 `suc_
infix 9 `_
infix 9 S_
infix 9 #_
@ -643,11 +642,11 @@ data _⊢_ : Context → Type → Set where
-- naturals
`zero : ∀ {Γ}
zero : ∀ {Γ}
------
→ Γ ⊢ `
`suc_ : ∀ {Γ}
suc : ∀ {Γ}
→ Γ ⊢ `
------
→ Γ ⊢ `
@ -689,7 +688,7 @@ data _⊢_ : Context → Type → Set where
-- products
`⟨_,_⟩ : ∀ {Γ A B}
⟨_,_⟩ : ∀ {Γ A B}
→ Γ ⊢ A
→ Γ ⊢ B
-----------
@ -745,14 +744,14 @@ rename : ∀ {Γ Δ} → (∀ {A} → Γ ∋ A → Δ ∋ A) → (∀ {A} → Γ
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 ρ (zero) = zero
rename ρ (suc M) = suc (rename ρ M)
rename ρ (case L M N) = case (rename ρ L) (rename ρ M) (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 ρ (case× L M) = case× (rename ρ L) (rename (ext (ext ρ)) M)
@ -769,14 +768,14 @@ subst : ∀ {Γ Δ} → (∀ {C} → Γ ∋ C → Δ ⊢ C) → (∀ {C} → Γ
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 σ (zero) = zero
subst σ (suc M) = suc (subst σ M)
subst σ (case L M N) = case (subst σ L) (subst σ M) (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 σ (case× L M) = case× (subst σ L) (subst (exts (exts σ)) M)
@ -825,12 +824,12 @@ data Value : ∀ {Γ A} → Γ ⊢ A → Set where
V-zero : ∀ {Γ}
-----------------
→ Value (`zero {Γ})
→ Value (zero {Γ})
V-suc_ : ∀ {Γ} {V : Γ ⊢ `}
→ Value V
--------------
→ Value (`suc V)
→ Value (suc V)
-- primitives
@ -844,7 +843,7 @@ data Value : ∀ {Γ A} → Γ ⊢ A → Set where
→ Value V
→ Value W
----------------
→ Value `⟨ V , W ⟩
→ Value ⟨ V , W ⟩
```
Implicit arguments need to be supplied when they are
@ -880,7 +879,7 @@ data _—→_ : ∀ {Γ A} → (Γ ⊢ A) → (Γ ⊢ A) → Set where
ξ-suc : ∀ {Γ} {M M : Γ ⊢ `}
→ M —→ M
-----------------
`suc M —→ `suc M
→ suc M —→ suc M
ξ-case : ∀ {Γ A} {L L : Γ ⊢ `} {M : Γ ⊢ A} {N : Γ , ` ⊢ A}
→ L —→ L
@ -889,12 +888,12 @@ data _—→_ : ∀ {Γ A} → (Γ ⊢ A) → (Γ ⊢ A) → Set where
β-zero : ∀ {Γ A} {M : Γ ⊢ A} {N : Γ , ` ⊢ A}
-------------------
→ case `zero M N —→ M
→ case zero M N —→ M
β-suc : ∀ {Γ A} {V : Γ ⊢ `} {M : Γ ⊢ A} {N : Γ , ` ⊢ A}
→ Value V
----------------------------
→ case (`suc V) M N —→ N [ V ]
→ case (suc V) M N —→ N [ V ]
-- fixpoint
@ -936,13 +935,13 @@ data _—→_ : ∀ {Γ A} → (Γ ⊢ A) → (Γ ⊢ A) → Set where
ξ-⟨,⟩₁ : ∀ {Γ A B} {M M : Γ ⊢ A} {N : Γ ⊢ B}
→ M —→ M
-------------------------
`⟨ M , N ⟩ —→ `⟨ M , N ⟩
→ ⟨ M , N ⟩ —→ ⟨ M , N ⟩
ξ-⟨,⟩₂ : ∀ {Γ A B} {V : Γ ⊢ A} {N N : Γ ⊢ B}
→ Value V
→ N —→ N
-------------------------
`⟨ V , N ⟩ —→ `⟨ V , N
→ ⟨ V , N ⟩ —→ ⟨ V , N
ξ-proj₁ : ∀ {Γ A B} {L L : Γ ⊢ A `× B}
→ L —→ L
@ -958,13 +957,13 @@ data _—→_ : ∀ {Γ A} → (Γ ⊢ A) → (Γ ⊢ A) → Set where
→ Value V
→ Value W
----------------------
`proj₁ `⟨ V , W ⟩ —→ V
→ `proj₁ ⟨ V , W ⟩ —→ V
β-proj₂ : ∀ {Γ A B} {V : Γ ⊢ A} {W : Γ ⊢ B}
→ Value V
→ Value W
----------------------
`proj₂ `⟨ V , W ⟩ —→ W
→ `proj₂ ⟨ V , W ⟩ —→ W
-- alternative formulation of products
@ -977,7 +976,7 @@ data _—→_ : ∀ {Γ A} → (Γ ⊢ A) → (Γ ⊢ A) → Set where
→ Value V
→ Value W
----------------------------------
→ case× `⟨ V , W ⟩ M —→ M [ V ][ W ]
→ case× ⟨ V , W ⟩ M —→ M [ V ][ W ]
```
@ -1051,8 +1050,8 @@ progress (L · M) with progress L
... | done V-ƛ with progress M
... | step M—→M = step (ξ-·₂ V-ƛ M—→M)
... | done VM = step (β-ƛ VM)
progress (`zero) = done V-zero
progress (`suc M) with progress M
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
@ -1069,7 +1068,7 @@ progress (L `* M) with progress L
progress (`let M N) with progress M
... | step M—→M = step (ξ-let M—→M)
... | done VM = step (β-let VM)
progress `⟨ M , N ⟩ with progress M
progress ⟨ M , N ⟩ with progress M
... | step M—→M = step (ξ-⟨,⟩₁ M—→M)
... | done VM with progress N
... | step N—→N = step (ξ-⟨,⟩₂ VM N—→N)
@ -1171,31 +1170,31 @@ _ =
swap× : ∀ {A B} → ∅ ⊢ A `× B ⇒ B `× A
swap× = ƛ `⟨ `proj₂ (# 0) , `proj₁ (# 0) ⟩
swap× = ƛ `proj₂ (# 0) , `proj₁ (# 0) ⟩
_ : swap× · `⟨ con 42 , `zero ⟩ —↠ `⟨ `zero , con 42 ⟩
_ : swap× · ⟨ con 42 , zero ⟩ —↠ ⟨ zero , con 42 ⟩
_ =
begin
swap× · `⟨ con 42 , `zero ⟩
swap× · ⟨ con 42 , zero ⟩
—→⟨ β-ƛ V-⟨ V-con , V-zero ⟩ ⟩
`⟨ `proj₂ `⟨ con 42 , `zero ⟩ , `proj₁ `⟨ con 42 , `zero ⟩ ⟩
`proj₂ ⟨ con 42 , zero ⟩ , `proj₁ ⟨ con 42 , zero ⟩ ⟩
—→⟨ ξ-⟨,⟩₁ (β-proj₂ V-con V-zero) ⟩
`⟨ `zero , `proj₁ `⟨ con 42 , `zero ⟩ ⟩
⟨ zero , `proj₁ ⟨ con 42 , zero ⟩ ⟩
—→⟨ ξ-⟨,⟩₂ V-zero (β-proj₁ V-con V-zero) ⟩
`⟨ `zero , con 42 ⟩
zero , con 42 ⟩
swap×-case : ∀ {A B} → ∅ ⊢ A `× B ⇒ B `× A
swap×-case = ƛ case× (# 0) `⟨ # 0 , # 1 ⟩
swap×-case = ƛ case× (# 0) ⟨ # 0 , # 1 ⟩
_ : swap×-case · `⟨ con 42 , `zero ⟩ —↠ `⟨ `zero , con 42 ⟩
_ : swap×-case · ⟨ con 42 , zero ⟩ —↠ ⟨ zero , con 42 ⟩
_ =
begin
swap×-case · `⟨ con 42 , `zero ⟩
swap×-case · ⟨ con 42 , zero ⟩
—→⟨ β-ƛ V-⟨ V-con , V-zero ⟩ ⟩
case× `⟨ con 42 , `zero ⟩ `⟨ # 0 , # 1 ⟩
case× ⟨ con 42 , zero ⟩ ⟨ # 0 , # 1 ⟩
—→⟨ β-case× V-con V-zero ⟩
`⟨ `zero , con 42 ⟩
zero , con 42 ⟩
```

View file

@ -46,7 +46,7 @@ Ultimately, we would like to show that we can keep reducing a term
until we reach a value. For instance, in the last chapter we showed
that two plus two is four,
plus · two · two —↠ `suc `suc `suc `suc `zero
plus · two · two —↠ suc suc suc suc `zero
which was proved by a long chain of reductions, ending in the value
on the right. Every term in the chain had the same type, `` ` ``.
@ -146,12 +146,12 @@ data Canonical_⦂_ : Term → Type → Set where
C-zero :
--------------------
Canonical `zero ⦂ `
Canonical zero ⦂ `
C-suc : ∀ {V}
→ Canonical V ⦂ `
---------------------
→ Canonical `suc V ⦂ `
→ Canonical (suc V) ⦂ `
```
Every closed, well-typed value is canonical:
@ -213,7 +213,7 @@ case of successor.
We would like to show that every term is either a value or takes a
reduction step. However, this is not true in general. The term
`zero · `suc `zero
`zero · suc `zero
is neither a value nor can take a reduction step. And if `` s ⦂ ` ⇒ ` ``
then the term
@ -874,17 +874,17 @@ well-typed term to its value, if it has one.
Some terms may reduce forever. Here is a simple example:
```
sucμ = μ "x" ⇒ `suc (` "x")
sucμ = μ "x" ⇒ suc (` "x")
_ =
begin
sucμ
—→⟨ β-μ ⟩
`suc sucμ
suc sucμ
—→⟨ ξ-suc β-μ ⟩
`suc `suc sucμ
suc (suc sucμ)
—→⟨ ξ-suc (ξ-suc β-μ) ⟩
`suc `suc `suc sucμ
suc (suc (suc sucμ))
-- ...
```
@ -981,10 +981,10 @@ remaining. There are two possibilities:
### Examples
We can now use Agda to compute the non-terminating reduction
sequence given earlier. First, we show that the term `sucμ`
sequence given earlier. First, we show that the term sucμ`
is well typed:
```
⊢sucμ : ∅ ⊢ μ "x" ⇒ `suc ` "x" ⦂ `
⊢sucμ : ∅ ⊢ μ "x" ⇒ suc (` "x") ⦂ `
⊢sucμ = ⊢μ (⊢suc (⊢` ∋x))
where
∋x = Z
@ -994,13 +994,13 @@ sequence, we evaluate with three steps worth of gas:
```
_ : eval (gas 3) ⊢sucμ ≡
steps
(μ "x" ⇒ `suc ` "x"
(μ "x" ⇒ suc (` "x")
—→⟨ β-μ ⟩
`suc (μ "x" ⇒ `suc ` "x")
suc (μ "x" ⇒ suc (` "x"))
—→⟨ ξ-suc β-μ ⟩
`suc (`suc (μ "x" ⇒ `suc ` "x"))
suc (suc (μ "x" ⇒ suc (` "x")))
—→⟨ ξ-suc (ξ-suc β-μ) ⟩
`suc (`suc (`suc (μ "x" ⇒ `suc ` "x")))
suc (suc (suc (μ "x" ⇒ suc (` "x"))))
∎)
out-of-gas
_ = refl
@ -1012,17 +1012,17 @@ applied to successor and zero. Supplying 100 steps of gas is more than enough:
```
_ : eval (gas 100) (⊢twoᶜ · ⊢sucᶜ · ⊢zero) ≡
steps
((ƛ "s" ⇒ (ƛ "z" ⇒ ` "s" · (` "s" · ` "z"))) · (ƛ "n" ⇒ `suc ` "n")
· `zero
((ƛ "s" ⇒ (ƛ "z" ⇒ ` "s" · (` "s" · ` "z"))) · (ƛ "n" ⇒ suc (` "n"))
· zero
—→⟨ ξ-·₁ (β-ƛ V-ƛ) ⟩
(ƛ "z" ⇒ (ƛ "n" ⇒ `suc ` "n") · ((ƛ "n" ⇒ `suc ` "n") · ` "z")) ·
`zero
(ƛ "z" ⇒ (ƛ "n" ⇒ suc (` "n")) · ((ƛ "n" ⇒ suc (` "n")) · ` "z")) ·
zero
—→⟨ β-ƛ V-zero ⟩
(ƛ "n" ⇒ `suc ` "n") · ((ƛ "n" ⇒ `suc ` "n") · `zero)
(ƛ "n" ⇒ suc (` "n")) · ((ƛ "n" ⇒ suc (` "n")) · zero)
—→⟨ ξ-·₂ V-ƛ (β-ƛ V-zero) ⟩
(ƛ "n" ⇒ `suc ` "n") · `suc `zero
(ƛ "n" ⇒ suc (` "n")) · suc zero
—→⟨ β-ƛ (V-suc V-zero) ⟩
`suc (`suc `zero)
suc (suc zero)
∎)
(done (V-suc (V-suc V-zero)))
_ = refl
@ -1031,7 +1031,7 @@ The example above was generated by using `C-c C-n` to normalise the
left-hand side of the equation and pasting in the result as the
right-hand side of the equation. The example reduction of the
previous chapter was derived from this result, reformatting and
writing `twoᶜ` and `sucᶜ` in place of their expansions.
writing `twoᶜ` and sucᶜ` in place of their expansions.
Next, we show two plus two is four:
```
@ -1040,157 +1040,157 @@ _ : eval (gas 100) ⊢2+2 ≡
((μ "+" ⇒
(ƛ "m" ⇒
(ƛ "n" ⇒
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ `suc (` "+" · ` "m" · ` "n")
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ suc (` "+" · ` "m" · ` "n")
])))
· `suc (`suc `zero)
· `suc (`suc `zero)
· suc (suc zero)
· suc (suc zero)
—→⟨ ξ-·₁ (ξ-·₁ β-μ) ⟩
(ƛ "m" ⇒
(ƛ "n" ⇒
case ` "m" [zero⇒ ` "n" |suc "m" ⇒
`suc
suc
((μ "+" ⇒
(ƛ "m" ⇒
(ƛ "n" ⇒
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ `suc (` "+" · ` "m" · ` "n")
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ suc (` "+" · ` "m" · ` "n")
])))
· ` "m"
· ` "n")
]))
· `suc (`suc `zero)
· `suc (`suc `zero)
· suc (suc zero)
· suc (suc zero)
—→⟨ ξ-·₁ (β-ƛ (V-suc (V-suc V-zero))) ⟩
(ƛ "n" ⇒
case `suc (`suc `zero) [zero⇒ ` "n" |suc "m" ⇒
`suc
case suc (suc zero) [zero⇒ ` "n" |suc "m" ⇒
suc
((μ "+" ⇒
(ƛ "m" ⇒
(ƛ "n" ⇒
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ `suc (` "+" · ` "m" · ` "n")
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ suc (` "+" · ` "m" · ` "n")
])))
· ` "m"
· ` "n")
])
· `suc (`suc `zero)
· suc (suc zero)
—→⟨ β-ƛ (V-suc (V-suc V-zero)) ⟩
case `suc (`suc `zero) [zero⇒ `suc (`suc `zero) |suc "m" ⇒
`suc
case suc (suc zero) [zero⇒ suc (suc zero) |suc "m" ⇒
suc
((μ "+" ⇒
(ƛ "m" ⇒
(ƛ "n" ⇒
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ `suc (` "+" · ` "m" · ` "n")
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ suc (` "+" · ` "m" · ` "n")
])))
· ` "m"
· `suc (`suc `zero))
· suc (suc zero))
]
—→⟨ β-suc (V-suc V-zero) ⟩
`suc
suc
((μ "+" ⇒
(ƛ "m" ⇒
(ƛ "n" ⇒
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ `suc (` "+" · ` "m" · ` "n")
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ suc (` "+" · ` "m" · ` "n")
])))
· `suc `zero
· `suc (`suc `zero))
· suc zero
· suc (suc zero))
—→⟨ ξ-suc (ξ-·₁ (ξ-·₁ β-μ)) ⟩
`suc
suc
((ƛ "m" ⇒
(ƛ "n" ⇒
case ` "m" [zero⇒ ` "n" |suc "m" ⇒
`suc
suc
((μ "+" ⇒
(ƛ "m" ⇒
(ƛ "n" ⇒
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ `suc (` "+" · ` "m" · ` "n")
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ suc (` "+" · ` "m" · ` "n")
])))
· ` "m"
· ` "n")
]))
· `suc `zero
· `suc (`suc `zero))
· suc zero
· suc (suc zero))
—→⟨ ξ-suc (ξ-·₁ (β-ƛ (V-suc V-zero))) ⟩
`suc
suc
((ƛ "n" ⇒
case `suc `zero [zero⇒ ` "n" |suc "m" ⇒
`suc
case suc zero [zero⇒ ` "n" |suc "m" ⇒
suc
((μ "+" ⇒
(ƛ "m" ⇒
(ƛ "n" ⇒
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ `suc (` "+" · ` "m" · ` "n")
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ suc (` "+" · ` "m" · ` "n")
])))
· ` "m"
· ` "n")
])
· `suc (`suc `zero))
· suc (suc zero))
—→⟨ ξ-suc (β-ƛ (V-suc (V-suc V-zero))) ⟩
`suc
case `suc `zero [zero⇒ `suc (`suc `zero) |suc "m" ⇒
`suc
suc
case suc zero [zero⇒ suc (suc zero) |suc "m" ⇒
suc
((μ "+" ⇒
(ƛ "m" ⇒
(ƛ "n" ⇒
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ `suc (` "+" · ` "m" · ` "n")
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ suc (` "+" · ` "m" · ` "n")
])))
· ` "m"
· `suc (`suc `zero))
· suc (suc zero))
]
—→⟨ ξ-suc (β-suc V-zero) ⟩
`suc
(`suc
suc
(suc
((μ "+" ⇒
(ƛ "m" ⇒
(ƛ "n" ⇒
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ `suc (` "+" · ` "m" · ` "n")
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ suc (` "+" · ` "m" · ` "n")
])))
· `zero
· `suc (`suc `zero)))
· zero
· suc (suc zero)))
—→⟨ ξ-suc (ξ-suc (ξ-·₁ (ξ-·₁ β-μ))) ⟩
`suc
(`suc
suc
(suc
((ƛ "m" ⇒
(ƛ "n" ⇒
case ` "m" [zero⇒ ` "n" |suc "m" ⇒
`suc
suc
((μ "+" ⇒
(ƛ "m" ⇒
(ƛ "n" ⇒
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ `suc (` "+" · ` "m" · ` "n")
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ suc (` "+" · ` "m" · ` "n")
])))
· ` "m"
· ` "n")
]))
· `zero
· `suc (`suc `zero)))
· zero
· suc (suc zero)))
—→⟨ ξ-suc (ξ-suc (ξ-·₁ (β-ƛ V-zero))) ⟩
`suc
(`suc
suc
(suc
((ƛ "n" ⇒
case `zero [zero⇒ ` "n" |suc "m" ⇒
`suc
case zero [zero⇒ ` "n" |suc "m" ⇒
suc
((μ "+" ⇒
(ƛ "m" ⇒
(ƛ "n" ⇒
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ `suc (` "+" · ` "m" · ` "n")
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ suc (` "+" · ` "m" · ` "n")
])))
· ` "m"
· ` "n")
])
· `suc (`suc `zero)))
· suc (suc zero)))
—→⟨ ξ-suc (ξ-suc (β-ƛ (V-suc (V-suc V-zero)))) ⟩
`suc
(`suc
case `zero [zero⇒ `suc (`suc `zero) |suc "m" ⇒
`suc
suc
(suc
case zero [zero⇒ suc (suc zero) |suc "m" ⇒
suc
((μ "+" ⇒
(ƛ "m" ⇒
(ƛ "n" ⇒
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ `suc (` "+" · ` "m" · ` "n")
case ` "m" [zero⇒ ` "n" |suc "m" ⇒ suc (` "+" · ` "m" · ` "n")
])))
· ` "m"
· `suc (`suc `zero))
· suc (suc zero))
])
—→⟨ ξ-suc (ξ-suc β-zero) ⟩
`suc (`suc (`suc (`suc `zero)))
suc (suc (suc (suc zero)))
∎)
(done (V-suc (V-suc (V-suc (V-suc V-zero)))))
_ = refl
@ -1207,8 +1207,8 @@ _ : eval (gas 100) ⊢2+2ᶜ ≡
(ƛ "s" ⇒ (ƛ "z" ⇒ ` "m" · ` "s" · (` "n" · ` "s" · ` "z")))))
· (ƛ "s" ⇒ (ƛ "z" ⇒ ` "s" · (` "s" · ` "z")))
· (ƛ "s" ⇒ (ƛ "z" ⇒ ` "s" · (` "s" · ` "z")))
· (ƛ "n" ⇒ `suc ` "n")
· `zero
· (ƛ "n" ⇒ suc (` "n"))
· zero
—→⟨ ξ-·₁ (ξ-·₁ (ξ-·₁ (β-ƛ V-ƛ))) ⟩
(ƛ "n" ⇒
(ƛ "s" ⇒
@ -1216,50 +1216,50 @@ _ : eval (gas 100) ⊢2+2ᶜ ≡
(ƛ "s" ⇒ (ƛ "z" ⇒ ` "s" · (` "s" · ` "z"))) · ` "s" ·
(` "n" · ` "s" · ` "z"))))
· (ƛ "s" ⇒ (ƛ "z" ⇒ ` "s" · (` "s" · ` "z")))
· (ƛ "n" ⇒ `suc ` "n")
· `zero
· (ƛ "n" ⇒ suc (` "n"))
· zero
—→⟨ ξ-·₁ (ξ-·₁ (β-ƛ V-ƛ)) ⟩
(ƛ "s" ⇒
(ƛ "z" ⇒
(ƛ "s" ⇒ (ƛ "z" ⇒ ` "s" · (` "s" · ` "z"))) · ` "s" ·
((ƛ "s" ⇒ (ƛ "z" ⇒ ` "s" · (` "s" · ` "z"))) · ` "s" · ` "z")))
· (ƛ "n" ⇒ `suc ` "n")
· `zero
· (ƛ "n" ⇒ suc (` "n"))
· zero
—→⟨ ξ-·₁ (β-ƛ V-ƛ) ⟩
(ƛ "z" ⇒
(ƛ "s" ⇒ (ƛ "z" ⇒ ` "s" · (` "s" · ` "z"))) · (ƛ "n" ⇒ `suc ` "n")
(ƛ "s" ⇒ (ƛ "z" ⇒ ` "s" · (` "s" · ` "z"))) · (ƛ "n" ⇒ suc (` "n"))
·
((ƛ "s" ⇒ (ƛ "z" ⇒ ` "s" · (` "s" · ` "z"))) · (ƛ "n" ⇒ `suc ` "n")
((ƛ "s" ⇒ (ƛ "z" ⇒ ` "s" · (` "s" · ` "z"))) · (ƛ "n" ⇒ suc (` "n"))
· ` "z"))
· `zero
· zero
—→⟨ β-ƛ V-zero ⟩
(ƛ "s" ⇒ (ƛ "z" ⇒ ` "s" · (` "s" · ` "z"))) · (ƛ "n" ⇒ `suc ` "n")
(ƛ "s" ⇒ (ƛ "z" ⇒ ` "s" · (` "s" · ` "z"))) · (ƛ "n" ⇒ suc (` "n"))
·
((ƛ "s" ⇒ (ƛ "z" ⇒ ` "s" · (` "s" · ` "z"))) · (ƛ "n" ⇒ `suc ` "n")
· `zero)
((ƛ "s" ⇒ (ƛ "z" ⇒ ` "s" · (` "s" · ` "z"))) · (ƛ "n" ⇒ suc (` "n"))
· zero)
—→⟨ ξ-·₁ (β-ƛ V-ƛ) ⟩
(ƛ "z" ⇒ (ƛ "n" ⇒ `suc ` "n") · ((ƛ "n" ⇒ `suc ` "n") · ` "z")) ·
((ƛ "s" ⇒ (ƛ "z" ⇒ ` "s" · (` "s" · ` "z"))) · (ƛ "n" ⇒ `suc ` "n")
· `zero)
(ƛ "z" ⇒ (ƛ "n" ⇒ suc (` "n")) · ((ƛ "n" ⇒ suc (` "n")) · ` "z")) ·
((ƛ "s" ⇒ (ƛ "z" ⇒ ` "s" · (` "s" · ` "z"))) · (ƛ "n" ⇒ suc (` "n"))
· zero)
—→⟨ ξ-·₂ V-ƛ (ξ-·₁ (β-ƛ V-ƛ)) ⟩
(ƛ "z" ⇒ (ƛ "n" ⇒ `suc ` "n") · ((ƛ "n" ⇒ `suc ` "n") · ` "z")) ·
((ƛ "z" ⇒ (ƛ "n" ⇒ `suc ` "n") · ((ƛ "n" ⇒ `suc ` "n") · ` "z")) ·
`zero)
(ƛ "z" ⇒ (ƛ "n" ⇒ suc (` "n")) · ((ƛ "n" ⇒ suc (` "n")) · ` "z")) ·
((ƛ "z" ⇒ (ƛ "n" ⇒ suc (` "n")) · ((ƛ "n" ⇒ suc (` "n")) · ` "z")) ·
zero)
—→⟨ ξ-·₂ V-ƛ (β-ƛ V-zero) ⟩
(ƛ "z" ⇒ (ƛ "n" ⇒ `suc ` "n") · ((ƛ "n" ⇒ `suc ` "n") · ` "z")) ·
((ƛ "n" ⇒ `suc ` "n") · ((ƛ "n" ⇒ `suc ` "n") · `zero))
(ƛ "z" ⇒ (ƛ "n" ⇒ suc (` "n")) · ((ƛ "n" ⇒ suc (` "n")) · ` "z")) ·
((ƛ "n" ⇒ suc (` "n")) · ((ƛ "n" ⇒ suc (` "n")) · zero))
—→⟨ ξ-·₂ V-ƛ (ξ-·₂ V-ƛ (β-ƛ V-zero)) ⟩
(ƛ "z" ⇒ (ƛ "n" ⇒ `suc ` "n") · ((ƛ "n" ⇒ `suc ` "n") · ` "z")) ·
((ƛ "n" ⇒ `suc ` "n") · `suc `zero)
(ƛ "z" ⇒ (ƛ "n" ⇒ suc (` "n")) · ((ƛ "n" ⇒ suc (` "n")) · ` "z")) ·
((ƛ "n" ⇒ suc (` "n")) · suc zero)
—→⟨ ξ-·₂ V-ƛ (β-ƛ (V-suc V-zero)) ⟩
(ƛ "z" ⇒ (ƛ "n" ⇒ `suc ` "n") · ((ƛ "n" ⇒ `suc ` "n") · ` "z")) ·
`suc (`suc `zero)
(ƛ "z" ⇒ (ƛ "n" ⇒ suc (` "n")) · ((ƛ "n" ⇒ suc (` "n")) · ` "z")) ·
suc (suc zero)
—→⟨ β-ƛ (V-suc (V-suc V-zero)) ⟩
(ƛ "n" ⇒ `suc ` "n") · ((ƛ "n" ⇒ `suc ` "n") · `suc (`suc `zero))
(ƛ "n" ⇒ suc (` "n")) · ((ƛ "n" ⇒ suc (` "n")) · suc (suc zero))
—→⟨ ξ-·₂ V-ƛ (β-ƛ (V-suc (V-suc V-zero))) ⟩
(ƛ "n" ⇒ `suc ` "n") · `suc (`suc (`suc `zero))
(ƛ "n" ⇒ suc (` "n")) · suc (suc (suc zero))
—→⟨ β-ƛ (V-suc (V-suc (V-suc V-zero))) ⟩
`suc (`suc (`suc (`suc `zero)))
suc (suc (suc (suc zero)))
∎)
(done (V-suc (V-suc (V-suc (V-suc V-zero)))))
_ = refl
@ -1401,7 +1401,7 @@ det (ξ-·₂ _ M—→M) (β-ƛ VM) = ⊥-elim (V¬—→ VM M—
det (β-ƛ _) (ξ-·₁ L—→L″) = ⊥-elim (V¬—→ V-ƛ L—→L″)
det (β-ƛ VM) (ξ-·₂ _ M—→M″) = ⊥-elim (V¬—→ VM M—→M″)
det (β-ƛ _) (β-ƛ _) = refl
det (ξ-suc M—→M) (ξ-suc M—→M″) = cong `suc_ (det M—→M M—→M″)
det (ξ-suc M—→M) (ξ-suc M—→M″) = cong suc (det M—→M M—→M″)
det (ξ-case L—→L) (ξ-case L—→L″) = cong₄ case_[zero⇒_|suc_⇒_]
(det L—→L L—→L″) refl refl refl
det (ξ-case L—→L) β-zero = ⊥-elim (V¬—→ V-zero L—→L)

View file

@ -216,7 +216,7 @@ plusᶜ = ƛ ƛ ƛ ƛ (# 3 · # 1 · (# 2 · # 1 · # 0))
2+2ᶜ = plusᶜ · twoᶜ · twoᶜ
```
Before, reduction stopped when we reached a lambda term, so we had to
compute `` plusᶜ · twoᶜ · twoᶜ · sucᶜ · `zero `` to ensure we reduced
compute `` plusᶜ · twoᶜ · twoᶜ · sucᶜ · zero `` to ensure we reduced
to a representation of the natural four. Now, reduction continues
under lambda, so we don't need the extra arguments. It is convenient
to define a term to represent four as a Church numeral, as well as
@ -487,7 +487,7 @@ form or takes a reduction step.
Previously, progress only applied to closed, well-typed terms. We had
to rule out terms where we apply something other than a function (such
as `` `zero ``) or terms with a free variable. Now we can demonstrate
as `` zero ``) or terms with a free variable. Now we can demonstrate
it for open, well-scoped terms. The definition of normal form permits
free variables, and we have no terms that are not functions.
@ -698,7 +698,8 @@ case L M N = L · (ƛ N) · M
Here we have been careful to retain the exact form of our previous
definitions. The successor branch expects an additional variable to
be in scope (as indicated by its type), so it is converted to an
ordinary term using lambda abstraction.
ordinary term using lambda abstraction. We use names `` `zero `` and
`` `suc ``, since we are defining terms rather than constructors.
We can also define fixpoint. Using named terms, we define: