diff --git a/src/plta/Lambda.lagda b/src/plta/Lambda.lagda index 91aef77e..d720d2ec 100644 --- a/src/plta/Lambda.lagda +++ b/src/plta/Lambda.lagda @@ -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 (\:) diff --git a/src/plta/Properties.lagda b/src/plta/Properties.lagda index f7a46da0..15442d40 100644 --- a/src/plta/Properties.lagda +++ b/src/plta/Properties.lagda @@ -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?