fixed reduction arrows
This commit is contained in:
parent
46fd91b60c
commit
41f5efe8ed
2 changed files with 219 additions and 216 deletions
|
@ -345,9 +345,9 @@ operational semantics of function application.
|
|||
For instance, we have
|
||||
|
||||
(ƛ "s" ⇒ ƛ "z" ⇒ ` "s" · (` "s" · ` "z")) · sucᶜ · `zero
|
||||
↦
|
||||
—→
|
||||
(ƛ "z" ⇒ sucᶜ · (sucᶜ · "z")) · `zero
|
||||
↦
|
||||
—→
|
||||
sucᶜ · (sucᶜ · `zero)
|
||||
|
||||
where we substitute `sucᶜ` for `` ` "s" `` and `` `zero `` for `` ` "z" ``
|
||||
|
@ -515,16 +515,16 @@ the argument for the variable in the abstraction.
|
|||
In an informal presentation of the operational semantics,
|
||||
the rules for reduction of applications are written as follows.
|
||||
|
||||
L ↦ L′
|
||||
L —→ L′
|
||||
-------------- ξ-·₁
|
||||
L · M ↦ L′ · M
|
||||
L · M —→ L′ · M
|
||||
|
||||
M ↦ M′
|
||||
M —→ M′
|
||||
-------------- ξ-·₂
|
||||
V · M ↦ V · M′
|
||||
V · M —→ V · M′
|
||||
|
||||
---------------------------- β-ƛ
|
||||
(ƛ x ⇒ N) · V ↦ N [ x := V ]
|
||||
(ƛ x ⇒ N) · V —→ N [ x := V ]
|
||||
|
||||
The Agda version of the rules below will be similar, except that universal
|
||||
quantifications are made explicit, and so are the predicates that indicate
|
||||
|
@ -549,48 +549,48 @@ the bound variable by the entire fixpoint term.
|
|||
Here are the rules formalised in Agda.
|
||||
|
||||
\begin{code}
|
||||
infix 4 _↦_
|
||||
infix 4 _—→_
|
||||
|
||||
data _↦_ : Term → Term → Set where
|
||||
data _—→_ : Term → Term → Set where
|
||||
|
||||
ξ-·₁ : ∀ {L L′ M}
|
||||
→ L ↦ L′
|
||||
→ L —→ L′
|
||||
-----------------
|
||||
→ L · M ↦ L′ · M
|
||||
→ L · M —→ L′ · M
|
||||
|
||||
ξ-·₂ : ∀ {V M M′}
|
||||
→ Value V
|
||||
→ M ↦ M′
|
||||
→ M —→ M′
|
||||
-----------------
|
||||
→ V · M ↦ V · M′
|
||||
→ V · M —→ V · M′
|
||||
|
||||
β-ƛ : ∀ {x N V}
|
||||
→ Value V
|
||||
------------------------------
|
||||
→ (ƛ x ⇒ N) · V ↦ N [ x := V ]
|
||||
→ (ƛ x ⇒ N) · V —→ N [ x := V ]
|
||||
|
||||
ξ-suc : ∀ {M M′}
|
||||
→ M ↦ M′
|
||||
→ M —→ M′
|
||||
------------------
|
||||
→ `suc M ↦ `suc M′
|
||||
→ `suc M —→ `suc M′
|
||||
|
||||
ξ-case : ∀ {x L L′ M N}
|
||||
→ L ↦ L′
|
||||
→ L —→ L′
|
||||
-----------------------------------------------------------------
|
||||
→ `case L [zero⇒ M |suc x ⇒ N ] ↦ `case L′ [zero⇒ M |suc x ⇒ N ]
|
||||
→ `case L [zero⇒ M |suc x ⇒ N ] —→ `case L′ [zero⇒ M |suc x ⇒ N ]
|
||||
|
||||
β-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}
|
||||
------------------------------
|
||||
→ μ x ⇒ M ↦ M [ x := μ x ⇒ M ]
|
||||
→ μ x ⇒ M —→ M [ x := μ x ⇒ M ]
|
||||
\end{code}
|
||||
|
||||
The reduction rules are carefully designed to ensure that subterms
|
||||
|
@ -600,14 +600,14 @@ This is referred to as _call by value_ reduction.
|
|||
Further, we have arranged that subterms are reduced in a
|
||||
left-to-right order. This means that reduction is _deterministic_:
|
||||
for any term, there is at most one other term to which it reduces.
|
||||
Put another way, our reduction relation `↦` is in fact a function.
|
||||
Put another way, our reduction relation `—→` is in fact a function.
|
||||
|
||||
|
||||
#### Quiz
|
||||
|
||||
What does the following term step to?
|
||||
|
||||
(ƛ "x" ⇒ ` "x") · (ƛ "x" ⇒ ` "x") ↦ ???
|
||||
(ƛ "x" ⇒ ` "x") · (ƛ "x" ⇒ ` "x") —→ ???
|
||||
|
||||
1. `` (ƛ "x" ⇒ ` "x") ``
|
||||
2. `` (ƛ "x" ⇒ ` "x") · (ƛ "x" ⇒ ` "x") ``
|
||||
|
@ -615,7 +615,7 @@ What does the following term step to?
|
|||
|
||||
What does the following term step to?
|
||||
|
||||
(ƛ "x" ⇒ ` "x") · (ƛ "x" ⇒ ` "x") · (ƛ "x" ⇒ ` "x") ↦ ???
|
||||
(ƛ "x" ⇒ ` "x") · (ƛ "x" ⇒ ` "x") · (ƛ "x" ⇒ ` "x") —→ ???
|
||||
|
||||
1. `` (ƛ "x" ⇒ ` "x") ``
|
||||
2. `` (ƛ "x" ⇒ ` "x") · (ƛ "x" ⇒ ` "x") ``
|
||||
|
@ -623,7 +623,7 @@ What does the following term step to?
|
|||
|
||||
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 ``
|
||||
|
@ -634,72 +634,72 @@ What does the following term step to? (Where `two` and `sucᶜ` are as defined
|
|||
|
||||
A single step is only part of the story. In general, we wish to repeatedly
|
||||
step a closed term until it reduces to a value. We do this by defining
|
||||
the reflexive and transitive closure `↠` of the step relation `↦`.
|
||||
the reflexive and transitive closure `—↠` of the step relation `—→`.
|
||||
|
||||
We define reflexive and transitive closure as a sequence of zero or
|
||||
more steps of the underlying relation, along lines similar to that for
|
||||
reasoning about chains of equalities
|
||||
Chapter [Equality]({{ site.baseurl }}{% link out/plta/Equality.md %}).
|
||||
\begin{code}
|
||||
infix 2 _↠_
|
||||
infix 2 _—↠_
|
||||
infix 1 begin_
|
||||
infixr 2 _↦⟨_⟩_
|
||||
infixr 2 _—→⟨_⟩_
|
||||
infix 3 _∎
|
||||
|
||||
data _↠_ : Term → Term → Set where
|
||||
data _—↠_ : Term → Term → Set where
|
||||
_∎ : ∀ M
|
||||
---------
|
||||
→ M ↠ M
|
||||
→ M —↠ M
|
||||
|
||||
_↦⟨_⟩_ : ∀ L {M N}
|
||||
→ L ↦ M
|
||||
→ M ↠ N
|
||||
_—→⟨_⟩_ : ∀ L {M N}
|
||||
→ L —→ M
|
||||
→ M —↠ N
|
||||
---------
|
||||
→ L ↠ N
|
||||
→ L —↠ N
|
||||
|
||||
begin_ : ∀ {M N} → (M ↠ N) → (M ↠ N)
|
||||
begin M↠N = M↠N
|
||||
begin_ : ∀ {M N} → (M —↠ N) → (M —↠ N)
|
||||
begin M—↠N = M—↠N
|
||||
\end{code}
|
||||
We can read this as follows.
|
||||
|
||||
* From term `M`, we can take no steps, giving a step of type `M ↠ M`.
|
||||
* From term `M`, we can take no steps, giving a step of type `M —↠ M`.
|
||||
It is written `M ∎`.
|
||||
|
||||
* From term `L` we can take a single of type `L ↦ M` followed by zero
|
||||
or more steps of type `M ↠ N`, giving a step of type `L ↠ N`. It is
|
||||
written `L ↦⟨ L↦M ⟩ M↠N`, where `L↦M` and `M↠N` are steps of the
|
||||
* From term `L` we can take a single of type `L —→ M` followed by zero
|
||||
or more steps of type `M —↠ N`, giving a step of type `L —↠ N`. It is
|
||||
written `L —→⟨ L—→M ⟩ M—↠N`, where `L—→M` and `M—↠N` are steps of the
|
||||
appropriate type.
|
||||
|
||||
The notation is chosen to allow us to lay out example reductions in an
|
||||
appealing way, as we will see in the next section.
|
||||
|
||||
As alternative is to define reflexive and transitive closure directly,
|
||||
as the smallest relation that includes `↦` and is also reflexive
|
||||
as the smallest relation that includes `—→` and is also reflexive
|
||||
and transitive. We could do so as follows.
|
||||
\begin{code}
|
||||
data _↠′_ : Term → Term → Set where
|
||||
data _—↠′_ : Term → Term → Set where
|
||||
|
||||
step : ∀ {M N}
|
||||
→ M ↦ N
|
||||
→ M —→ N
|
||||
------
|
||||
→ M ↠′ N
|
||||
→ M —↠′ N
|
||||
|
||||
refl : ∀ {M}
|
||||
------
|
||||
→ M ↠′ M
|
||||
→ M —↠′ M
|
||||
|
||||
trans : ∀ {L M N}
|
||||
→ L ↠′ M
|
||||
→ M ↠′ N
|
||||
→ L —↠′ M
|
||||
→ M —↠′ N
|
||||
------
|
||||
→ L ↠′ N
|
||||
→ L —↠′ N
|
||||
\end{code}
|
||||
The three constructors specify, respectively, that `↠` includes `↦`
|
||||
The three constructors specify, respectively, that `—↠` includes `—→`
|
||||
and is reflexive and transitive.
|
||||
|
||||
It is a straightforward exercise to show the two are equivalent.
|
||||
|
||||
#### Exercise (`↠≃↠′`)
|
||||
#### Exercise (`—↠≃—↠′`)
|
||||
|
||||
Show that the two notions of reflexive and transitive closure
|
||||
above are isomorphic.
|
||||
|
@ -710,97 +710,97 @@ above are isomorphic.
|
|||
We start with a simple example. The Church numeral two applied to the
|
||||
successor function and zero yields the natural number two.
|
||||
\begin{code}
|
||||
_ : twoᶜ · sucᶜ · `zero ↠ `suc `suc `zero
|
||||
_ : twoᶜ · sucᶜ · `zero —↠ `suc `suc `zero
|
||||
_ =
|
||||
begin
|
||||
twoᶜ · sucᶜ · `zero
|
||||
↦⟨ ξ-·₁ (β-ƛ V-ƛ) ⟩
|
||||
—→⟨ ξ-·₁ (β-ƛ V-ƛ) ⟩
|
||||
(ƛ "z" ⇒ sucᶜ · (sucᶜ · ` "z")) · `zero
|
||||
↦⟨ β-ƛ V-zero ⟩
|
||||
—→⟨ β-ƛ V-zero ⟩
|
||||
sucᶜ · (sucᶜ · `zero)
|
||||
↦⟨ ξ-·₂ V-ƛ (β-ƛ V-zero) ⟩
|
||||
—→⟨ ξ-·₂ V-ƛ (β-ƛ V-zero) ⟩
|
||||
sucᶜ · `suc `zero
|
||||
↦⟨ β-ƛ (V-suc V-zero) ⟩
|
||||
—→⟨ β-ƛ (V-suc V-zero) ⟩
|
||||
`suc (`suc `zero)
|
||||
∎
|
||||
\end{code}
|
||||
|
||||
Here is a sample reduction demonstrating that two plus two is four.
|
||||
\begin{code}
|
||||
_ : 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") ])
|
||||
· two · two
|
||||
↦⟨ ξ-·₁ (β-ƛ (V-suc (V-suc V-zero))) ⟩
|
||||
—→⟨ ξ-·₁ (β-ƛ (V-suc (V-suc V-zero))) ⟩
|
||||
(ƛ "n" ⇒
|
||||
`case two [zero⇒ ` "n" |suc "m" ⇒ `suc (plus · ` "m" · ` "n") ])
|
||||
· two
|
||||
↦⟨ β-ƛ (V-suc (V-suc V-zero)) ⟩
|
||||
—→⟨ β-ƛ (V-suc (V-suc V-zero)) ⟩
|
||||
`case two [zero⇒ two |suc "m" ⇒ `suc (plus · ` "m" · two) ]
|
||||
↦⟨ β-suc (V-suc V-zero) ⟩
|
||||
—→⟨ β-suc (V-suc V-zero) ⟩
|
||||
`suc (plus · `suc `zero · two)
|
||||
↦⟨ ξ-suc (ξ-·₁ (ξ-·₁ β-μ)) ⟩
|
||||
—→⟨ ξ-suc (ξ-·₁ (ξ-·₁ β-μ)) ⟩
|
||||
`suc ((ƛ "m" ⇒ ƛ "n" ⇒
|
||||
`case ` "m" [zero⇒ ` "n" |suc "m" ⇒ `suc (plus · ` "m" · ` "n") ])
|
||||
· `suc `zero · two)
|
||||
↦⟨ ξ-suc (ξ-·₁ (β-ƛ (V-suc V-zero))) ⟩
|
||||
—→⟨ ξ-suc (ξ-·₁ (β-ƛ (V-suc V-zero))) ⟩
|
||||
`suc ((ƛ "n" ⇒
|
||||
`case `suc `zero [zero⇒ ` "n" |suc "m" ⇒ `suc (plus · ` "m" · ` "n") ])
|
||||
· two)
|
||||
↦⟨ ξ-suc (β-ƛ (V-suc (V-suc V-zero))) ⟩
|
||||
—→⟨ ξ-suc (β-ƛ (V-suc (V-suc V-zero))) ⟩
|
||||
`suc (`case `suc `zero [zero⇒ two |suc "m" ⇒ `suc (plus · ` "m" · two) ])
|
||||
↦⟨ ξ-suc (β-suc V-zero) ⟩
|
||||
—→⟨ ξ-suc (β-suc V-zero) ⟩
|
||||
`suc `suc (plus · `zero · two)
|
||||
↦⟨ ξ-suc (ξ-suc (ξ-·₁ (ξ-·₁ β-μ))) ⟩
|
||||
—→⟨ ξ-suc (ξ-suc (ξ-·₁ (ξ-·₁ β-μ))) ⟩
|
||||
`suc `suc ((ƛ "m" ⇒ ƛ "n" ⇒
|
||||
`case ` "m" [zero⇒ ` "n" |suc "m" ⇒ `suc (plus · ` "m" · ` "n") ])
|
||||
· `zero · two)
|
||||
↦⟨ ξ-suc (ξ-suc (ξ-·₁ (β-ƛ V-zero))) ⟩
|
||||
—→⟨ ξ-suc (ξ-suc (ξ-·₁ (β-ƛ V-zero))) ⟩
|
||||
`suc `suc ((ƛ "n" ⇒
|
||||
`case `zero [zero⇒ ` "n" |suc "m" ⇒ `suc (plus · ` "m" · ` "n") ])
|
||||
· two)
|
||||
↦⟨ ξ-suc (ξ-suc (β-ƛ (V-suc (V-suc V-zero)))) ⟩
|
||||
—→⟨ ξ-suc (ξ-suc (β-ƛ (V-suc (V-suc V-zero)))) ⟩
|
||||
`suc `suc (`case `zero [zero⇒ two |suc "m" ⇒ `suc (plus · ` "m" · two) ])
|
||||
↦⟨ ξ-suc (ξ-suc β-zero) ⟩
|
||||
—→⟨ ξ-suc (ξ-suc β-zero) ⟩
|
||||
`suc (`suc (`suc (`suc `zero)))
|
||||
∎
|
||||
\end{code}
|
||||
|
||||
And here is a similar sample reduction for Church numerals.
|
||||
\begin{code}
|
||||
_ : fourᶜ ↠ `suc `suc `suc `suc `zero
|
||||
_ : fourᶜ —↠ `suc `suc `suc `suc `zero
|
||||
_ =
|
||||
begin
|
||||
(ƛ "m" ⇒ ƛ "n" ⇒ ƛ "s" ⇒ ƛ "z" ⇒ ` "m" · ` "s" · (` "n" · ` "s" · ` "z"))
|
||||
· twoᶜ · twoᶜ · sucᶜ · `zero
|
||||
↦⟨ ξ-·₁ (ξ-·₁ (ξ-·₁ (β-ƛ V-ƛ))) ⟩
|
||||
—→⟨ ξ-·₁ (ξ-·₁ (ξ-·₁ (β-ƛ V-ƛ))) ⟩
|
||||
(ƛ "n" ⇒ ƛ "s" ⇒ ƛ "z" ⇒ twoᶜ · ` "s" · (` "n" · ` "s" · ` "z"))
|
||||
· twoᶜ · sucᶜ · `zero
|
||||
↦⟨ ξ-·₁ (ξ-·₁ (β-ƛ V-ƛ)) ⟩
|
||||
—→⟨ ξ-·₁ (ξ-·₁ (β-ƛ V-ƛ)) ⟩
|
||||
(ƛ "s" ⇒ ƛ "z" ⇒ twoᶜ · ` "s" · (twoᶜ · ` "s" · ` "z")) · sucᶜ · `zero
|
||||
↦⟨ ξ-·₁ (β-ƛ V-ƛ) ⟩
|
||||
—→⟨ ξ-·₁ (β-ƛ V-ƛ) ⟩
|
||||
(ƛ "z" ⇒ twoᶜ · sucᶜ · (twoᶜ · sucᶜ · ` "z")) · `zero
|
||||
↦⟨ β-ƛ V-zero ⟩
|
||||
—→⟨ β-ƛ V-zero ⟩
|
||||
twoᶜ · sucᶜ · (twoᶜ · sucᶜ · `zero)
|
||||
↦⟨ ξ-·₁ (β-ƛ V-ƛ) ⟩
|
||||
—→⟨ ξ-·₁ (β-ƛ V-ƛ) ⟩
|
||||
(ƛ "z" ⇒ sucᶜ · (sucᶜ · ` "z")) · (twoᶜ · sucᶜ · `zero)
|
||||
↦⟨ ξ-·₂ V-ƛ (ξ-·₁ (β-ƛ V-ƛ)) ⟩
|
||||
—→⟨ ξ-·₂ V-ƛ (ξ-·₁ (β-ƛ V-ƛ)) ⟩
|
||||
(ƛ "z" ⇒ sucᶜ · (sucᶜ · ` "z")) · ((ƛ "z" ⇒ sucᶜ · (sucᶜ · ` "z")) · `zero)
|
||||
↦⟨ ξ-·₂ V-ƛ (β-ƛ V-zero) ⟩
|
||||
—→⟨ ξ-·₂ V-ƛ (β-ƛ V-zero) ⟩
|
||||
(ƛ "z" ⇒ sucᶜ · (sucᶜ · ` "z")) · (sucᶜ · (sucᶜ · `zero))
|
||||
↦⟨ ξ-·₂ V-ƛ (ξ-·₂ V-ƛ (β-ƛ V-zero)) ⟩
|
||||
—→⟨ ξ-·₂ V-ƛ (ξ-·₂ V-ƛ (β-ƛ V-zero)) ⟩
|
||||
(ƛ "z" ⇒ sucᶜ · (sucᶜ · ` "z")) · (sucᶜ · (`suc `zero))
|
||||
↦⟨ ξ-·₂ V-ƛ (β-ƛ (V-suc V-zero)) ⟩
|
||||
—→⟨ ξ-·₂ V-ƛ (β-ƛ (V-suc V-zero)) ⟩
|
||||
(ƛ "z" ⇒ sucᶜ · (sucᶜ · ` "z")) · (`suc `suc `zero)
|
||||
↦⟨ β-ƛ (V-suc (V-suc V-zero)) ⟩
|
||||
—→⟨ β-ƛ (V-suc (V-suc V-zero)) ⟩
|
||||
sucᶜ · (sucᶜ · `suc `suc `zero)
|
||||
↦⟨ ξ-·₂ V-ƛ (β-ƛ (V-suc (V-suc V-zero))) ⟩
|
||||
—→⟨ ξ-·₂ V-ƛ (β-ƛ (V-suc (V-suc V-zero))) ⟩
|
||||
sucᶜ · (`suc `suc `suc `zero)
|
||||
↦⟨ β-ƛ (V-suc (V-suc (V-suc V-zero))) ⟩
|
||||
—→⟨ β-ƛ (V-suc (V-suc (V-suc V-zero))) ⟩
|
||||
`suc (`suc (`suc (`suc `zero)))
|
||||
∎
|
||||
\end{code}
|
||||
|
@ -1267,16 +1267,16 @@ showing that it is well-typed.
|
|||
|
||||
This chapter uses the following unicode
|
||||
|
||||
⇒ U+21D2: RIGHTWARDS DOUBLE ARROW (\=>)
|
||||
ƛ U+019B: LATIN SMALL LETTER LAMBDA WITH STROKE (\Gl-)
|
||||
· U+00B7: MIDDLE DOT (\cdot)
|
||||
⇒ U+21D2: RIGHTWARDS DOUBLE ARROW (\=>)
|
||||
ƛ U+019B: LATIN SMALL LETTER LAMBDA WITH STROKE (\Gl-)
|
||||
· U+00B7: MIDDLE DOT (\cdot)
|
||||
😇 U+1F607: SMILING FACE WITH HALO
|
||||
😈 U+1F608: SMILING FACE WITH HORNS
|
||||
↦ U+21A6: RIGHTWARDS ARROW FROM BAR (\mapsto, \r-|)
|
||||
↠ U+21A0: RIGHTWARDS TWO HEADED ARROW (\rr-)
|
||||
ξ U+03BE: GREEK SMALL LETTER XI (\Gx or \xi)
|
||||
β U+03B2: GREEK SMALL LETTER BETA (\Gb or \beta)
|
||||
∋ U+220B: CONTAINS AS MEMBER (\ni)
|
||||
⊢ U+22A2: RIGHT TACK (\vdash or \|-)
|
||||
⦂ U+2982: Z NOTATION TYPE COLON (\:)
|
||||
— U+2014: EM DASH (\em)
|
||||
↠ U+21A0: RIGHTWARDS TWO HEADED ARROW (\rr-)
|
||||
ξ U+03BE: GREEK SMALL LETTER XI (\Gx or \xi)
|
||||
β U+03B2: GREEK SMALL LETTER BETA (\Gb or \beta)
|
||||
∋ U+220B: CONTAINS AS MEMBER (\ni)
|
||||
⊢ U+22A2: RIGHT TACK (\vdash or \|-)
|
||||
⦂ U+2982: Z NOTATION TYPE COLON (\:)
|
||||
|
||||
|
|
|
@ -48,7 +48,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 plust 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, `` `ℕ ``.
|
||||
|
@ -59,7 +59,7 @@ a reduction step. As we will see, this property does _not_ hold for
|
|||
every term, but it does hold for every closed, well-typed term.
|
||||
|
||||
_Progress_: If `∅ ⊢ M ⦂ A` then either `M` is a value or there is an `N` such
|
||||
that `M ↦ N`.
|
||||
that `M —→ N`.
|
||||
|
||||
So, either we have a value, and we are done, or we can take a reduction step.
|
||||
In the latter case, we would like to apply progress again. But to do so we need
|
||||
|
@ -67,7 +67,7 @@ to know that the term yielded by the reduction is itself closed and well-typed.
|
|||
It turns out that this property holds whenever we start with a closed,
|
||||
well-typed term.
|
||||
|
||||
_Preservation_: If `∅ ⊢ M ⦂ A` and `M ↦ N` then `∅ ⊢ N ⦂ A`.
|
||||
_Preservation_: If `∅ ⊢ M ⦂ A` and `M —→ N` then `∅ ⊢ N ⦂ A`.
|
||||
|
||||
This gives us a recipe for automating evaluation. Start with a closed
|
||||
and well-typed term. By progress, it is either a value, in which case
|
||||
|
@ -93,10 +93,10 @@ types without needing to develop a separate inductive definition of the
|
|||
|
||||
We start with any easy observation. Values do not reduce.
|
||||
\begin{code}
|
||||
V¬↦ : ∀ {M N} → Value M → ¬ (M ↦ N)
|
||||
V¬↦ V-ƛ ()
|
||||
V¬↦ V-zero ()
|
||||
V¬↦ (V-suc VM) (ξ-suc M↦N) = V¬↦ VM M↦N
|
||||
V¬—→ : ∀ {M N} → Value M → ¬ (M —→ N)
|
||||
V¬—→ V-ƛ ()
|
||||
V¬—→ V-zero ()
|
||||
V¬—→ (V-suc VM) (ξ-suc M—→N) = V¬—→ VM M—→N
|
||||
\end{code}
|
||||
We consider the three possibilities for values.
|
||||
|
||||
|
@ -110,13 +110,13 @@ We consider the three possibilities for values.
|
|||
|
||||
As a corollary, terms that reduce are not values.
|
||||
\begin{code}
|
||||
↦¬V : ∀ {M N} → (M ↦ N) → ¬ Value M
|
||||
↦¬V M↦N VM = V¬↦ VM M↦N
|
||||
—→¬V : ∀ {M N} → (M —→ N) → ¬ Value M
|
||||
—→¬V M—→N VM = V¬—→ VM M—→N
|
||||
\end{code}
|
||||
If we expand out the negations, we have
|
||||
|
||||
V¬↦ : ∀ {M N} → Value M → M ↦ N → ⊥
|
||||
↦¬V : ∀ {M N} → M ↦ N → Value M → ⊥
|
||||
V¬—→ : ∀ {M N} → Value M → M —→ N → ⊥
|
||||
—→¬V : ∀ {M N} → M —→ N → Value M → ⊥
|
||||
|
||||
which are the same function with the arguments swapped.
|
||||
|
||||
|
@ -139,38 +139,38 @@ cong₄ f refl refl refl refl = refl
|
|||
It is now straightforward to show that reduction is deterministic.
|
||||
\begin{code}
|
||||
det : ∀ {M M′ M″}
|
||||
→ (M ↦ M′)
|
||||
→ (M ↦ M″)
|
||||
→ (M —→ M′)
|
||||
→ (M —→ M″)
|
||||
--------
|
||||
→ M′ ≡ M″
|
||||
det (ξ-·₁ L↦L′) (ξ-·₁ L↦L″) = cong₂ _·_ (det L↦L′ L↦L″) refl
|
||||
det (ξ-·₁ L↦L′) (ξ-·₂ VL M↦M″) = ⊥-elim (V¬↦ VL L↦L′)
|
||||
det (ξ-·₁ L↦L′) (β-ƛ _) = ⊥-elim (V¬↦ V-ƛ L↦L′)
|
||||
det (ξ-·₂ VL _) (ξ-·₁ L↦L″) = ⊥-elim (V¬↦ VL L↦L″)
|
||||
det (ξ-·₂ _ M↦M′) (ξ-·₂ _ M↦M″) = cong₂ _·_ refl (det M↦M′ M↦M″)
|
||||
det (ξ-·₂ _ M↦M′) (β-ƛ VM) = ⊥-elim (V¬↦ VM M↦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 (ξ-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′)
|
||||
det (ξ-case L↦L′) (β-suc VL) = ⊥-elim (V¬↦ (V-suc VL) L↦L′)
|
||||
det β-zero (ξ-case M↦M″) = ⊥-elim (V¬↦ V-zero M↦M″)
|
||||
det β-zero β-zero = refl
|
||||
det (β-suc VL) (ξ-case L↦L″) = ⊥-elim (V¬↦ (V-suc VL) L↦L″)
|
||||
det (β-suc _) (β-suc _) = refl
|
||||
det β-μ β-μ = refl
|
||||
det (ξ-·₁ L—→L′) (ξ-·₁ L—→L″) = cong₂ _·_ (det L—→L′ L—→L″) refl
|
||||
det (ξ-·₁ L—→L′) (ξ-·₂ VL M—→M″) = ⊥-elim (V¬—→ VL L—→L′)
|
||||
det (ξ-·₁ L—→L′) (β-ƛ _) = ⊥-elim (V¬—→ V-ƛ L—→L′)
|
||||
det (ξ-·₂ VL _) (ξ-·₁ L—→L″) = ⊥-elim (V¬—→ VL L—→L″)
|
||||
det (ξ-·₂ _ M—→M′) (ξ-·₂ _ M—→M″) = cong₂ _·_ refl (det M—→M′ M—→M″)
|
||||
det (ξ-·₂ _ M—→M′) (β-ƛ VM) = ⊥-elim (V¬—→ VM M—→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 (ξ-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′)
|
||||
det (ξ-case L—→L′) (β-suc VL) = ⊥-elim (V¬—→ (V-suc VL) L—→L′)
|
||||
det β-zero (ξ-case M—→M″) = ⊥-elim (V¬—→ V-zero M—→M″)
|
||||
det β-zero β-zero = refl
|
||||
det (β-suc VL) (ξ-case L—→L″) = ⊥-elim (V¬—→ (V-suc VL) L—→L″)
|
||||
det (β-suc _) (β-suc _) = refl
|
||||
det β-μ β-μ = refl
|
||||
\end{code}
|
||||
The proof is by induction over possible reductions. We consider
|
||||
three typical cases.
|
||||
|
||||
* Two instances of `ξ-·₁`.
|
||||
|
||||
L ↦ L′ L ↦ L″
|
||||
L —→ L′ L —→ L″
|
||||
-------------- ξ-·₁ -------------- ξ-·₁
|
||||
L · M ↦ L′ · M L · M ↦ L″ · M
|
||||
L · M —→ L′ · M L · M —→ L″ · M
|
||||
|
||||
By induction we have `L′ ≡ L″`, and hence by congruence
|
||||
`L′ · M ≡ L″ · M`.
|
||||
|
@ -178,9 +178,9 @@ three typical cases.
|
|||
* An instance of `ξ-·₁` and an instance of `ξ-·₂`.
|
||||
|
||||
Value L
|
||||
L ↦ L′ M ↦ M″
|
||||
L —→ L′ M —→ M″
|
||||
-------------- ξ-·₁ -------------- ξ-·₂
|
||||
L · M ↦ L′ · M L · M ↦ L · M″
|
||||
L · M —→ L′ · M L · M —→ L · M″
|
||||
|
||||
The rule on the left requires `L` to reduce, but the rule on the right
|
||||
requires `L` to be a value. This is a contradiction since values do
|
||||
|
@ -191,7 +191,7 @@ three typical cases.
|
|||
|
||||
Value V Value V
|
||||
---------------------------- β-ƛ ---------------------------- β-ƛ
|
||||
(ƛ x ⇒ N) · V ↦ N [ x := V ] (ƛ x ⇒ N) · V ↦ N [ x := V ]
|
||||
(ƛ x ⇒ N) · V —→ N [ x := V ] (ƛ x ⇒ N) · V —→ N [ x := V ]
|
||||
|
||||
Since the left-hand sides are identical, the right-hand sides are
|
||||
also identical.
|
||||
|
@ -202,7 +202,7 @@ once with `ξ-·₁` first and `ξ-·₂` second, and the other time with the
|
|||
two swapped. What we might like to do is delete the redundant lines
|
||||
and add
|
||||
|
||||
det M↦M′ M↦M″ = sym (det M↦M″ M↦M′)
|
||||
det M—→M′ M—→M″ = sym (det M—→M″ M—→M′)
|
||||
|
||||
to the bottom of the proof. But this does not work. The termination
|
||||
checker complains, because the arguments have merely switched order
|
||||
|
@ -310,7 +310,7 @@ second has a free variable. Every term that is well-typed and closed
|
|||
has the desired property.
|
||||
|
||||
_Progress_: If `∅ ⊢ M ⦂ A` then either `M` is a value or there is an `N` such
|
||||
that `M ↦ N`.
|
||||
that `M —→ N`.
|
||||
|
||||
To formulate this property, we first introduce a relation that
|
||||
captures what it means for a term `M` to make progess.
|
||||
|
@ -318,7 +318,7 @@ captures what it means for a term `M` to make progess.
|
|||
data Progress (M : Term) : Set where
|
||||
|
||||
step : ∀ {N}
|
||||
→ M ↦ N
|
||||
→ M —→ N
|
||||
----------
|
||||
→ Progress M
|
||||
|
||||
|
@ -328,7 +328,7 @@ data Progress (M : Term) : Set where
|
|||
→ Progress M
|
||||
\end{code}
|
||||
A term `M` makes progress if either it can take a step, meaning there
|
||||
exists a term `N` such that `M ↦ N`, or if it is done, meaning that
|
||||
exists a term `N` such that `M —→ N`, or if it is done, meaning that
|
||||
`M` is a value.
|
||||
|
||||
If a term is well-typed in the empty context then it is a value.
|
||||
|
@ -340,17 +340,17 @@ progress : ∀ {M A}
|
|||
progress (⊢` ())
|
||||
progress (⊢ƛ ⊢N) = done V-ƛ
|
||||
progress (⊢L · ⊢M) with progress ⊢L
|
||||
... | step L↦L′ = step (ξ-·₁ L↦L′)
|
||||
... | step L—→L′ = step (ξ-·₁ L—→L′)
|
||||
... | done VL with progress ⊢M
|
||||
... | step M↦M′ = step (ξ-·₂ VL M↦M′)
|
||||
... | step M—→M′ = step (ξ-·₂ VL M—→M′)
|
||||
... | done VM with canonical ⊢L VL
|
||||
... | C-ƛ _ = step (β-ƛ VM)
|
||||
progress ⊢zero = done V-zero
|
||||
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)
|
||||
progress (⊢case ⊢L ⊢M ⊢N) with progress ⊢L
|
||||
... | step L↦L′ = step (ξ-case L↦L′)
|
||||
... | step L—→L′ = step (ξ-case L—→L′)
|
||||
... | done VL with canonical ⊢L VL
|
||||
... | C-zero = step β-zero
|
||||
... | C-suc CL = step (β-suc (value CL))
|
||||
|
@ -367,7 +367,7 @@ Let's unpack the first three cases.
|
|||
* If the term is an application `L · M`, recursively apply
|
||||
progress to the derivation that `L` is well-typed.
|
||||
|
||||
+ If the term steps, we have evidence that `L ↦ L′`,
|
||||
+ If the term steps, we have evidence that `L —→ L′`,
|
||||
which by `ξ-·₁` means that our original term steps
|
||||
to `L′ · M`
|
||||
|
||||
|
@ -375,7 +375,7 @@ Let's unpack the first three cases.
|
|||
a value. Recursively apply progress to the derivation
|
||||
that `M` is well-typed.
|
||||
|
||||
- If the term steps, we have evidence that `M ↦ M′`,
|
||||
- If the term steps, we have evidence that `M —→ M′`,
|
||||
which by `ξ-·₂` means that our original term steps
|
||||
to `L · M′`. Step `ξ-·₂` applies only if we have
|
||||
evidence that `L` is a value, but progress on that
|
||||
|
@ -407,7 +407,7 @@ Instead of defining a data type for `Progress M`, we could
|
|||
have formulated progress using disjunction and existentials:
|
||||
\begin{code}
|
||||
postulate
|
||||
progress′ : ∀ M {A} → ∅ ⊢ M ⦂ A → Value M ⊎ ∃[ N ](M ↦ N)
|
||||
progress′ : ∀ M {A} → ∅ ⊢ M ⦂ A → Value M ⊎ ∃[ N ](M —→ N)
|
||||
\end{code}
|
||||
This leads to a less perspicous proof. Instead of the mnemonic `done`
|
||||
and `step` we use `inj₁` and `inj₂`, and the term `N` is no longer
|
||||
|
@ -423,7 +423,7 @@ proof of `progress` above.
|
|||
|
||||
#### Exercise (`Progress-iso`)
|
||||
|
||||
Show that `Progress M` is isomorphic to `Value M ⊎ ∃[ N ](M ↦ N)`.
|
||||
Show that `Progress M` is isomorphic to `Value M ⊎ ∃[ N ](M —→ N)`.
|
||||
|
||||
|
||||
## Prelude to preservation
|
||||
|
@ -488,7 +488,7 @@ the same result as if we first substitute and then type the result.
|
|||
The third step is to show preservation.
|
||||
|
||||
_Preservation_:
|
||||
If `∅ ⊢ M ⦂ A` and `M ↦ N` then `∅ ⊢ N ⦂ A`.
|
||||
If `∅ ⊢ M ⦂ A` and `M —→ N` then `∅ ⊢ N ⦂ A`.
|
||||
|
||||
The proof is by induction over the possible reductions, and
|
||||
the substitution lemma is crucial in showing that each of the
|
||||
|
@ -904,20 +904,20 @@ that reduction preserves types is straightforward.
|
|||
\begin{code}
|
||||
preserve : ∀ {M N A}
|
||||
→ ∅ ⊢ M ⦂ A
|
||||
→ M ↦ N
|
||||
→ M —→ N
|
||||
----------
|
||||
→ ∅ ⊢ N ⦂ A
|
||||
preserve (⊢` ())
|
||||
preserve (⊢ƛ ⊢N) ()
|
||||
preserve (⊢L · ⊢M) (ξ-·₁ L↦L′) = (preserve ⊢L L↦L′) · ⊢M
|
||||
preserve (⊢L · ⊢M) (ξ-·₂ VL M↦M′) = ⊢L · (preserve ⊢M M↦M′)
|
||||
preserve ((⊢ƛ ⊢N) · ⊢V) (β-ƛ VV) = subst ⊢V ⊢N
|
||||
preserve (⊢L · ⊢M) (ξ-·₁ L—→L′) = (preserve ⊢L L—→L′) · ⊢M
|
||||
preserve (⊢L · ⊢M) (ξ-·₂ VL M—→M′) = ⊢L · (preserve ⊢M M—→M′)
|
||||
preserve ((⊢ƛ ⊢N) · ⊢V) (β-ƛ VV) = subst ⊢V ⊢N
|
||||
preserve ⊢zero ()
|
||||
preserve (⊢suc ⊢M) (ξ-suc M↦M′) = ⊢suc (preserve ⊢M M↦M′)
|
||||
preserve (⊢case ⊢L ⊢M ⊢N) (ξ-case L↦L′) = ⊢case (preserve ⊢L L↦L′) ⊢M ⊢N
|
||||
preserve (⊢case ⊢zero ⊢M ⊢N) β-zero = ⊢M
|
||||
preserve (⊢case (⊢suc ⊢V) ⊢M ⊢N) (β-suc VV) = subst ⊢V ⊢N
|
||||
preserve (⊢μ ⊢M) (β-μ) = subst (⊢μ ⊢M) ⊢M
|
||||
preserve (⊢suc ⊢M) (ξ-suc M—→M′) = ⊢suc (preserve ⊢M M—→M′)
|
||||
preserve (⊢case ⊢L ⊢M ⊢N) (ξ-case L—→L′) = ⊢case (preserve ⊢L L—→L′) ⊢M ⊢N
|
||||
preserve (⊢case ⊢zero ⊢M ⊢N) β-zero = ⊢M
|
||||
preserve (⊢case (⊢suc ⊢V) ⊢M ⊢N) (β-suc VV) = subst ⊢V ⊢N
|
||||
preserve (⊢μ ⊢M) (β-μ) = subst (⊢μ ⊢M) ⊢M
|
||||
\end{code}
|
||||
The proof never mentions the types of `M` or `N`,
|
||||
so in what follows we choose type name as convenient.
|
||||
|
@ -926,9 +926,9 @@ Let's unpack the cases for two of the reduction rules.
|
|||
|
||||
* Rule `ξ-·₁`. We have
|
||||
|
||||
L ↦ L′
|
||||
L —→ L′
|
||||
----------------
|
||||
L · M ↦ L′ · M
|
||||
L · M —→ L′ · M
|
||||
|
||||
where the left-hand side is typed by
|
||||
|
||||
|
@ -940,7 +940,7 @@ Let's unpack the cases for two of the reduction rules.
|
|||
By induction, we have
|
||||
|
||||
Γ ⊢ L ⦂ A ⇒ B
|
||||
L ↦ L′
|
||||
L —→ L′
|
||||
--------------
|
||||
Γ ⊢ L′ ⦂ A ⇒ B
|
||||
|
||||
|
@ -987,11 +987,11 @@ sucμ = μ "x" ⇒ `suc (` "x")
|
|||
_ =
|
||||
begin
|
||||
sucμ
|
||||
↦⟨ β-μ ⟩
|
||||
—→⟨ β-μ ⟩
|
||||
`suc sucμ
|
||||
↦⟨ ξ-suc β-μ ⟩
|
||||
—→⟨ ξ-suc β-μ ⟩
|
||||
`suc `suc sucμ
|
||||
↦⟨ ξ-suc (ξ-suc β-μ) ⟩
|
||||
—→⟨ ξ-suc (ξ-suc β-μ) ⟩
|
||||
`suc `suc `suc sucμ
|
||||
-- ...
|
||||
∎
|
||||
|
@ -1042,7 +1042,7 @@ reduction finished.
|
|||
data Steps (L : Term) : Set where
|
||||
|
||||
steps : ∀ {N}
|
||||
→ L ↠ N
|
||||
→ L —↠ N
|
||||
→ Finished N
|
||||
----------
|
||||
→ Steps L
|
||||
|
@ -1058,15 +1058,15 @@ eval : ∀ {L A}
|
|||
eval {L} (gas zero) ⊢L = steps (L ∎) out-of-gas
|
||||
eval {L} (gas (suc m)) ⊢L with progress ⊢L
|
||||
... | done VL = steps (L ∎) (done VL)
|
||||
... | step L↦M with eval (gas m) (preserve ⊢L L↦M)
|
||||
... | steps M↠N fin = steps (L ↦⟨ L↦M ⟩ M↠N) fin
|
||||
... | step L—→M with eval (gas m) (preserve ⊢L L—→M)
|
||||
... | steps M—↠N fin = steps (L —→⟨ L—→M ⟩ M—↠N) fin
|
||||
\end{code}
|
||||
Let `L` be the name of the term we are reducing, and `⊢L` be the
|
||||
evidence that `L` is well-typed. We consider the amount of gas
|
||||
remaining. There are two possibilities.
|
||||
|
||||
* It is zero, so we stop early. We return the trivial reduction
|
||||
sequence `L ↠ L`, evidence that `L` is well-typed, and an
|
||||
sequence `L —↠ L`, evidence that `L` is well-typed, and an
|
||||
indication that we are out of gas.
|
||||
|
||||
* It is non-zero and after the next step we have `m` gas remaining.
|
||||
|
@ -1074,15 +1074,15 @@ remaining. There are two possibilities.
|
|||
are two possibilities.
|
||||
|
||||
+ Term `L` is a value, so we are done. We return the
|
||||
trivial reduction sequence `L ↠ L`, evidence that `L` is
|
||||
trivial reduction sequence `L —↠ L`, evidence that `L` is
|
||||
well-typed, and the evidence that `L` is a value.
|
||||
|
||||
+ Term `L` steps to another term `M`. Preservation provides
|
||||
evidence that `M` is also well-typed, and we recursively invoke
|
||||
`eval` on the remaining gas. The result is evidence that
|
||||
`M ↠ N`, together with evidence that `N` is well-typed and an
|
||||
`M —↠ N`, together with evidence that `N` is well-typed and an
|
||||
indication of whether reduction finished. We combine the evidence
|
||||
that `L ↦ M` and `M ↠ N` to return evidence that `L ↠ N`,
|
||||
that `L —→ M` and `M —↠ N` to return evidence that `L —↠ N`,
|
||||
together with the other relevant evidence.
|
||||
|
||||
|
||||
|
@ -1102,9 +1102,9 @@ sequence, we evaluate with three steps worth of gas.
|
|||
\begin{code}
|
||||
_ : eval (gas 3) ⊢sucμ ≡
|
||||
steps
|
||||
(μ "x" ⇒ `suc ` "x" ↦⟨ β-μ ⟩
|
||||
`suc (μ "x" ⇒ `suc ` "x") ↦⟨ ξ-suc β-μ ⟩
|
||||
`suc (`suc (μ "x" ⇒ `suc ` "x")) ↦⟨ ξ-suc (ξ-suc β-μ) ⟩
|
||||
(μ "x" ⇒ `suc ` "x" —→⟨ β-μ ⟩
|
||||
`suc (μ "x" ⇒ `suc ` "x") —→⟨ ξ-suc β-μ ⟩
|
||||
`suc (`suc (μ "x" ⇒ `suc ` "x")) —→⟨ ξ-suc (ξ-suc β-μ) ⟩
|
||||
`suc (`suc (`suc (μ "x" ⇒ `suc ` "x"))) ∎)
|
||||
out-of-gas
|
||||
_ = refl
|
||||
|
@ -1118,13 +1118,13 @@ _ : eval (gas 100) (⊢twoᶜ · ⊢sucᶜ · ⊢zero) ≡
|
|||
steps
|
||||
((ƛ "s" ⇒ (ƛ "z" ⇒ ` "s" · (` "s" · ` "z"))) · (ƛ "n" ⇒ `suc ` "n")
|
||||
· `zero
|
||||
↦⟨ ξ-·₁ (β-ƛ V-ƛ) ⟩
|
||||
—→⟨ ξ-·₁ (β-ƛ V-ƛ) ⟩
|
||||
(ƛ "z" ⇒ (ƛ "n" ⇒ `suc ` "n") · ((ƛ "n" ⇒ `suc ` "n") · ` "z")) ·
|
||||
`zero
|
||||
↦⟨ β-ƛ V-zero ⟩
|
||||
(ƛ "n" ⇒ `suc ` "n") · ((ƛ "n" ⇒ `suc ` "n") · `zero) ↦⟨
|
||||
—→⟨ β-ƛ V-zero ⟩
|
||||
(ƛ "n" ⇒ `suc ` "n") · ((ƛ "n" ⇒ `suc ` "n") · `zero) —→⟨
|
||||
ξ-·₂ V-ƛ (β-ƛ V-zero) ⟩
|
||||
(ƛ "n" ⇒ `suc ` "n") · `suc `zero ↦⟨ β-ƛ (V-suc V-zero) ⟩
|
||||
(ƛ "n" ⇒ `suc ` "n") · `suc `zero —→⟨ β-ƛ (V-suc V-zero) ⟩
|
||||
`suc (`suc `zero) ∎)
|
||||
(done (V-suc (V-suc V-zero)))
|
||||
_ = refl
|
||||
|
@ -1146,7 +1146,7 @@ _ : eval (gas 100) ⊢2+2 ≡
|
|||
])))
|
||||
· `suc (`suc `zero)
|
||||
· `suc (`suc `zero)
|
||||
↦⟨ ξ-·₁ (ξ-·₁ β-μ) ⟩
|
||||
—→⟨ ξ-·₁ (ξ-·₁ β-μ) ⟩
|
||||
(ƛ "m" ⇒
|
||||
(ƛ "n" ⇒
|
||||
`case ` "m" [zero⇒ ` "n" |suc "m" ⇒
|
||||
|
@ -1161,7 +1161,7 @@ _ : eval (gas 100) ⊢2+2 ≡
|
|||
]))
|
||||
· `suc (`suc `zero)
|
||||
· `suc (`suc `zero)
|
||||
↦⟨ ξ-·₁ (β-ƛ (V-suc (V-suc V-zero))) ⟩
|
||||
—→⟨ ξ-·₁ (β-ƛ (V-suc (V-suc V-zero))) ⟩
|
||||
(ƛ "n" ⇒
|
||||
`case `suc (`suc `zero) [zero⇒ ` "n" |suc "m" ⇒
|
||||
`suc
|
||||
|
@ -1174,7 +1174,7 @@ _ : eval (gas 100) ⊢2+2 ≡
|
|||
· ` "n")
|
||||
])
|
||||
· `suc (`suc `zero)
|
||||
↦⟨ β-ƛ (V-suc (V-suc V-zero)) ⟩
|
||||
—→⟨ β-ƛ (V-suc (V-suc V-zero)) ⟩
|
||||
`case `suc (`suc `zero) [zero⇒ `suc (`suc `zero) |suc "m" ⇒
|
||||
`suc
|
||||
((μ "+" ⇒
|
||||
|
@ -1185,7 +1185,7 @@ _ : eval (gas 100) ⊢2+2 ≡
|
|||
· ` "m"
|
||||
· `suc (`suc `zero))
|
||||
]
|
||||
↦⟨ β-suc (V-suc V-zero) ⟩
|
||||
—→⟨ β-suc (V-suc V-zero) ⟩
|
||||
`suc
|
||||
((μ "+" ⇒
|
||||
(ƛ "m" ⇒
|
||||
|
@ -1194,7 +1194,7 @@ _ : eval (gas 100) ⊢2+2 ≡
|
|||
])))
|
||||
· `suc `zero
|
||||
· `suc (`suc `zero))
|
||||
↦⟨ ξ-suc (ξ-·₁ (ξ-·₁ β-μ)) ⟩
|
||||
—→⟨ ξ-suc (ξ-·₁ (ξ-·₁ β-μ)) ⟩
|
||||
`suc
|
||||
((ƛ "m" ⇒
|
||||
(ƛ "n" ⇒
|
||||
|
@ -1210,7 +1210,7 @@ _ : eval (gas 100) ⊢2+2 ≡
|
|||
]))
|
||||
· `suc `zero
|
||||
· `suc (`suc `zero))
|
||||
↦⟨ ξ-suc (ξ-·₁ (β-ƛ (V-suc V-zero))) ⟩
|
||||
—→⟨ ξ-suc (ξ-·₁ (β-ƛ (V-suc V-zero))) ⟩
|
||||
`suc
|
||||
((ƛ "n" ⇒
|
||||
`case `suc `zero [zero⇒ ` "n" |suc "m" ⇒
|
||||
|
@ -1224,7 +1224,7 @@ _ : eval (gas 100) ⊢2+2 ≡
|
|||
· ` "n")
|
||||
])
|
||||
· `suc (`suc `zero))
|
||||
↦⟨ ξ-suc (β-ƛ (V-suc (V-suc V-zero))) ⟩
|
||||
—→⟨ ξ-suc (β-ƛ (V-suc (V-suc V-zero))) ⟩
|
||||
`suc
|
||||
`case `suc `zero [zero⇒ `suc (`suc `zero) |suc "m" ⇒
|
||||
`suc
|
||||
|
@ -1236,7 +1236,7 @@ _ : eval (gas 100) ⊢2+2 ≡
|
|||
· ` "m"
|
||||
· `suc (`suc `zero))
|
||||
]
|
||||
↦⟨ ξ-suc (β-suc V-zero) ⟩
|
||||
—→⟨ ξ-suc (β-suc V-zero) ⟩
|
||||
`suc
|
||||
(`suc
|
||||
((μ "+" ⇒
|
||||
|
@ -1246,7 +1246,7 @@ _ : eval (gas 100) ⊢2+2 ≡
|
|||
])))
|
||||
· `zero
|
||||
· `suc (`suc `zero)))
|
||||
↦⟨ ξ-suc (ξ-suc (ξ-·₁ (ξ-·₁ β-μ))) ⟩
|
||||
—→⟨ ξ-suc (ξ-suc (ξ-·₁ (ξ-·₁ β-μ))) ⟩
|
||||
`suc
|
||||
(`suc
|
||||
((ƛ "m" ⇒
|
||||
|
@ -1263,7 +1263,7 @@ _ : eval (gas 100) ⊢2+2 ≡
|
|||
]))
|
||||
· `zero
|
||||
· `suc (`suc `zero)))
|
||||
↦⟨ ξ-suc (ξ-suc (ξ-·₁ (β-ƛ V-zero))) ⟩
|
||||
—→⟨ ξ-suc (ξ-suc (ξ-·₁ (β-ƛ V-zero))) ⟩
|
||||
`suc
|
||||
(`suc
|
||||
((ƛ "n" ⇒
|
||||
|
@ -1278,7 +1278,7 @@ _ : eval (gas 100) ⊢2+2 ≡
|
|||
· ` "n")
|
||||
])
|
||||
· `suc (`suc `zero)))
|
||||
↦⟨ ξ-suc (ξ-suc (β-ƛ (V-suc (V-suc V-zero)))) ⟩
|
||||
—→⟨ ξ-suc (ξ-suc (β-ƛ (V-suc (V-suc V-zero)))) ⟩
|
||||
`suc
|
||||
(`suc
|
||||
`case `zero [zero⇒ `suc (`suc `zero) |suc "m" ⇒
|
||||
|
@ -1291,7 +1291,7 @@ _ : eval (gas 100) ⊢2+2 ≡
|
|||
· ` "m"
|
||||
· `suc (`suc `zero))
|
||||
])
|
||||
↦⟨ ξ-suc (ξ-suc β-zero) ⟩ `suc (`suc (`suc (`suc `zero))) ∎)
|
||||
—→⟨ ξ-suc (ξ-suc β-zero) ⟩ `suc (`suc (`suc (`suc `zero))) ∎)
|
||||
(done (V-suc (V-suc (V-suc (V-suc V-zero)))))
|
||||
_ = refl
|
||||
\end{code}
|
||||
|
@ -1309,7 +1309,7 @@ _ : eval (gas 100) ⊢2+2ᶜ ≡
|
|||
· (ƛ "s" ⇒ (ƛ "z" ⇒ ` "s" · (` "s" · ` "z")))
|
||||
· (ƛ "n" ⇒ `suc ` "n")
|
||||
· `zero
|
||||
↦⟨ ξ-·₁ (ξ-·₁ (ξ-·₁ (β-ƛ V-ƛ))) ⟩
|
||||
—→⟨ ξ-·₁ (ξ-·₁ (ξ-·₁ (β-ƛ V-ƛ))) ⟩
|
||||
(ƛ "n" ⇒
|
||||
(ƛ "s" ⇒
|
||||
(ƛ "z" ⇒
|
||||
|
@ -1318,46 +1318,46 @@ _ : eval (gas 100) ⊢2+2ᶜ ≡
|
|||
· (ƛ "s" ⇒ (ƛ "z" ⇒ ` "s" · (` "s" · ` "z")))
|
||||
· (ƛ "n" ⇒ `suc ` "n")
|
||||
· `zero
|
||||
↦⟨ ξ-·₁ (ξ-·₁ (β-ƛ V-ƛ)) ⟩
|
||||
—→⟨ ξ-·₁ (ξ-·₁ (β-ƛ V-ƛ)) ⟩
|
||||
(ƛ "s" ⇒
|
||||
(ƛ "z" ⇒
|
||||
(ƛ "s" ⇒ (ƛ "z" ⇒ ` "s" · (` "s" · ` "z"))) · ` "s" ·
|
||||
((ƛ "s" ⇒ (ƛ "z" ⇒ ` "s" · (` "s" · ` "z"))) · ` "s" · ` "z")))
|
||||
· (ƛ "n" ⇒ `suc ` "n")
|
||||
· `zero
|
||||
↦⟨ ξ-·₁ (β-ƛ V-ƛ) ⟩
|
||||
—→⟨ ξ-·₁ (β-ƛ V-ƛ) ⟩
|
||||
(ƛ "z" ⇒
|
||||
(ƛ "s" ⇒ (ƛ "z" ⇒ ` "s" · (` "s" · ` "z"))) · (ƛ "n" ⇒ `suc ` "n")
|
||||
·
|
||||
((ƛ "s" ⇒ (ƛ "z" ⇒ ` "s" · (` "s" · ` "z"))) · (ƛ "n" ⇒ `suc ` "n")
|
||||
· ` "z"))
|
||||
· `zero
|
||||
↦⟨ β-ƛ V-zero ⟩
|
||||
—→⟨ β-ƛ V-zero ⟩
|
||||
(ƛ "s" ⇒ (ƛ "z" ⇒ ` "s" · (` "s" · ` "z"))) · (ƛ "n" ⇒ `suc ` "n")
|
||||
·
|
||||
((ƛ "s" ⇒ (ƛ "z" ⇒ ` "s" · (` "s" · ` "z"))) · (ƛ "n" ⇒ `suc ` "n")
|
||||
· `zero)
|
||||
↦⟨ ξ-·₁ (β-ƛ V-ƛ) ⟩
|
||||
—→⟨ ξ-·₁ (β-ƛ V-ƛ) ⟩
|
||||
(ƛ "z" ⇒ (ƛ "n" ⇒ `suc ` "n") · ((ƛ "n" ⇒ `suc ` "n") · ` "z")) ·
|
||||
((ƛ "s" ⇒ (ƛ "z" ⇒ ` "s" · (` "s" · ` "z"))) · (ƛ "n" ⇒ `suc ` "n")
|
||||
· `zero)
|
||||
↦⟨ ξ-·₂ V-ƛ (ξ-·₁ (β-ƛ V-ƛ)) ⟩
|
||||
—→⟨ ξ-·₂ V-ƛ (ξ-·₁ (β-ƛ V-ƛ)) ⟩
|
||||
(ƛ "z" ⇒ (ƛ "n" ⇒ `suc ` "n") · ((ƛ "n" ⇒ `suc ` "n") · ` "z")) ·
|
||||
((ƛ "z" ⇒ (ƛ "n" ⇒ `suc ` "n") · ((ƛ "n" ⇒ `suc ` "n") · ` "z")) ·
|
||||
`zero)
|
||||
↦⟨ ξ-·₂ V-ƛ (β-ƛ V-zero) ⟩
|
||||
—→⟨ ξ-·₂ V-ƛ (β-ƛ V-zero) ⟩
|
||||
(ƛ "z" ⇒ (ƛ "n" ⇒ `suc ` "n") · ((ƛ "n" ⇒ `suc ` "n") · ` "z")) ·
|
||||
((ƛ "n" ⇒ `suc ` "n") · ((ƛ "n" ⇒ `suc ` "n") · `zero))
|
||||
↦⟨ ξ-·₂ V-ƛ (ξ-·₂ V-ƛ (β-ƛ V-zero)) ⟩
|
||||
—→⟨ ξ-·₂ V-ƛ (ξ-·₂ V-ƛ (β-ƛ V-zero)) ⟩
|
||||
(ƛ "z" ⇒ (ƛ "n" ⇒ `suc ` "n") · ((ƛ "n" ⇒ `suc ` "n") · ` "z")) ·
|
||||
((ƛ "n" ⇒ `suc ` "n") · `suc `zero)
|
||||
↦⟨ ξ-·₂ V-ƛ (β-ƛ (V-suc V-zero)) ⟩
|
||||
—→⟨ ξ-·₂ V-ƛ (β-ƛ (V-suc V-zero)) ⟩
|
||||
(ƛ "z" ⇒ (ƛ "n" ⇒ `suc ` "n") · ((ƛ "n" ⇒ `suc ` "n") · ` "z")) ·
|
||||
`suc (`suc `zero)
|
||||
↦⟨ β-ƛ (V-suc (V-suc V-zero)) ⟩
|
||||
—→⟨ β-ƛ (V-suc (V-suc V-zero)) ⟩
|
||||
(ƛ "n" ⇒ `suc ` "n") · ((ƛ "n" ⇒ `suc ` "n") · `suc (`suc `zero))
|
||||
↦⟨ ξ-·₂ V-ƛ (β-ƛ (V-suc (V-suc V-zero))) ⟩
|
||||
(ƛ "n" ⇒ `suc ` "n") · `suc (`suc (`suc `zero)) ↦⟨
|
||||
—→⟨ ξ-·₂ V-ƛ (β-ƛ (V-suc (V-suc V-zero))) ⟩
|
||||
(ƛ "n" ⇒ `suc ` "n") · `suc (`suc (`suc `zero)) —→⟨
|
||||
β-ƛ (V-suc (V-suc (V-suc V-zero))) ⟩
|
||||
`suc (`suc (`suc (`suc `zero))) ∎)
|
||||
(done (V-suc (V-suc (V-suc (V-suc V-zero)))))
|
||||
|
@ -1371,7 +1371,7 @@ above.
|
|||
A term is _normal_ if it cannot reduce.
|
||||
\begin{code}
|
||||
Normal : Term → Set
|
||||
Normal M = ∀ {N} → ¬ (M ↦ N)
|
||||
Normal M = ∀ {N} → ¬ (M —→ N)
|
||||
\end{code}
|
||||
|
||||
A term is _stuck_ if it is normal yet not a value.
|
||||
|
@ -1394,7 +1394,7 @@ Using preservation, it is easy to show that after any number of steps, a well-ty
|
|||
postulate
|
||||
preserves : ∀ {M N A}
|
||||
→ ∅ ⊢ M ⦂ A
|
||||
→ M ↠ N
|
||||
→ M —↠ N
|
||||
---------
|
||||
→ ∅ ⊢ N ⦂ A
|
||||
\end{code}
|
||||
|
@ -1406,7 +1406,7 @@ result with the slogan _well-typed terms don't get stuck_.
|
|||
postulate
|
||||
wttdgs : ∀ {M N A}
|
||||
→ ∅ ⊢ M ⦂ A
|
||||
→ M ↠ N
|
||||
→ M —↠ N
|
||||
-----------
|
||||
→ ¬ (Stuck M)
|
||||
\end{code}
|
||||
|
@ -1427,8 +1427,8 @@ unstuck′ : ∀ {M A}
|
|||
→ ∅ ⊢ M ⦂ A
|
||||
-----------
|
||||
→ ¬ (Stuck M)
|
||||
unstuck′ ⊢M ⟨ ¬M↦N , ¬VM ⟩ with progress ⊢M
|
||||
... | step M↦N = ¬M↦N M↦N
|
||||
unstuck′ ⊢M ⟨ ¬M—→N , ¬VM ⟩ with progress ⊢M
|
||||
... | step M—→N = ¬M—→N M—→N
|
||||
... | done VM = ¬VM VM
|
||||
\end{code}
|
||||
|
||||
|
@ -1436,21 +1436,21 @@ Any descendant of a well-typed term is well-typed.
|
|||
\begin{code}
|
||||
preserves′ : ∀ {M N A}
|
||||
→ ∅ ⊢ M ⦂ A
|
||||
→ M ↠ N
|
||||
→ M —↠ N
|
||||
---------
|
||||
→ ∅ ⊢ N ⦂ A
|
||||
preserves′ ⊢M (M ∎) = ⊢M
|
||||
preserves′ ⊢L (L ↦⟨ L↦M ⟩ M↠N) = preserves′ (preserve ⊢L L↦M) M↠N
|
||||
preserves′ ⊢L (L —→⟨ L—→M ⟩ M—↠N) = preserves′ (preserve ⊢L L—→M) M—↠N
|
||||
\end{code}
|
||||
|
||||
Combining the above gives us the desired result.
|
||||
\begin{code}
|
||||
wttdgs′ : ∀ {M N A}
|
||||
→ ∅ ⊢ M ⦂ A
|
||||
→ M ↠ N
|
||||
→ M —↠ N
|
||||
-----------
|
||||
→ ¬ (Stuck N)
|
||||
wttdgs′ ⊢M M↠N = unstuck′ (preserves′ ⊢M M↠N)
|
||||
wttdgs′ ⊢M M—↠N = unstuck′ (preserves′ ⊢M M—↠N)
|
||||
\end{code}
|
||||
|
||||
|
||||
|
@ -1462,20 +1462,21 @@ and preservation theorems for the simply typed lambda-calculus.
|
|||
|
||||
#### Exercise `subject_expansion`
|
||||
|
||||
We say that `M` _reduces_ to `N` if `M ↦ N`,
|
||||
and conversely that `M` _expands_ to `N` if `N ↦ M`.
|
||||
We say that `M` _reduces_ to `N` if `M —→ N`,
|
||||
and conversely that `M` _expands_ to `N` if `N —→ M`.
|
||||
The preservation property is sometimes called _subject reduction_.
|
||||
Its opposite is _subject expansion_, which holds if
|
||||
`M ↦ N` and `∅ ⊢ N ⦂ A` imply `∅ ⊢ M ⦂ A`.
|
||||
`M —→ N` and `∅ ⊢ N ⦂ A` imply `∅ ⊢ M ⦂ A`.
|
||||
Find two counter-examples to subject expansion, one
|
||||
with case expressions and one not involving case expressions.
|
||||
|
||||
|
||||
#### Quiz
|
||||
|
||||
Suppose we add a new term `zap` with the following reduction rule
|
||||
|
||||
--------- β-zap
|
||||
M ↦ zap
|
||||
-------- β-zap
|
||||
M —→ zap
|
||||
|
||||
and the following typing rule:
|
||||
|
||||
|
@ -1499,11 +1500,11 @@ false, give a counterexample.
|
|||
Suppose instead that we add a new term `foo` with the following
|
||||
reduction rules:
|
||||
|
||||
--------------------- β-foo₁
|
||||
(λ x ⇒ ` x) ↦ foo
|
||||
------------------ β-foo₁
|
||||
(λ x ⇒ ` x) —→ foo
|
||||
|
||||
------------ β-foo₂
|
||||
foo ↦ zero
|
||||
----------- β-foo₂
|
||||
foo —→ zero
|
||||
|
||||
Which of the following properties remain true in
|
||||
the presence of this rule? For each one, write either
|
||||
|
@ -1543,14 +1544,14 @@ to interpret a natural as a function from naturals to naturals.
|
|||
|
||||
Γ ⊢ L ⦂ `ℕ
|
||||
Γ ⊢ M ⦂ `ℕ
|
||||
-------------- ⊢ℕ⇒ℕ
|
||||
-------------- _·ℕ_
|
||||
Γ ⊢ L · M ⦂ `ℕ
|
||||
|
||||
And that we add the corresponding reduction rule.
|
||||
|
||||
fᵢ(m) → n
|
||||
--------- δ
|
||||
i · m → n
|
||||
fᵢ(m) —→ n
|
||||
---------- δ
|
||||
i · m —→ n
|
||||
|
||||
Which of the following properties remain true in
|
||||
the presence of this rule? For each one, write either
|
||||
|
@ -1563,3 +1564,5 @@ false, give a counterexample.
|
|||
|
||||
- Preservation
|
||||
|
||||
Are all properties preserved in this case? Are there any
|
||||
other alterations we would wish to make to the system?
|
||||
|
|
Loading…
Reference in a new issue