improved typing and trans closure in Lambda

This commit is contained in:
wadler 2018-10-29 12:15:31 +00:00
parent 649d7dcb13
commit 9b0069d8d1
2 changed files with 44 additions and 45 deletions

View file

@ -21,21 +21,21 @@ ex1 = "xbyexxbyyexxxbyyyexxxx"
test1 :: Bool test1 :: Bool
test1 = strip (== 'b') (== 'e') ex1 == ["y","yy","yyy",""] test1 = strip (== 'b') (== 'e') ex1 == ["y","yy","yyy",""]
count :: (a -> Bool) -> (a -> Bool) -> [a] -> Int
count b e = sum . map length . strip b e
test2 :: Bool test2 :: Bool
test2 = count (== 'b') (== 'e') ex1 == 6 test2 = (sum . map length . strip (== 'b') (== 'e')) ex1 == 6
agda :: String -> Int
agda = count (prefix begin) (prefix end) . lines
where
begin = "\\begin{code}"
end = "\\end{code}"
nonblank :: String -> Bool nonblank :: String -> Bool
nonblank = not . all (== ' ') nonblank = not . all (== ' ')
count :: [[String]] -> Int
count = sum . map length . map (filter nonblank)
agda :: String -> Int
agda = count . strip begin end . lines
where
begin = prefix "\\begin{code}"
end = prefix "\\end{code}"
wc :: String -> Int wc :: String -> Int
wc = length . lines wc = length . lines

View file

@ -700,29 +700,29 @@ and transitive. We could do so as follows.
\begin{code} \begin{code}
data _—↠_ : Term → Term → Set where data _—↠_ : Term → Term → Set where
step : ∀ {M N} step : ∀ {M N}
→ M —→ N → M —→ N
------- -------
→ M —↠′ N → M —↠′ N
refl : ∀ {M} refl : ∀ {M}
------- -------
→ M —↠′ M → M —↠′ M
trans : ∀ {L M N} trans : ∀ {L M N}
→ L —↠′ M → L —↠′ M
→ M —↠′ N → M —↠′ N
------- -------
→ L —↠′ N → L —↠′ N
\end{code} \end{code}
The three constructors specify, respectively, that `—↠` includes `—→` The three constructors specify, respectively, that `—↠` includes `—→`
and is reflexive and transitive. A good exercise is to show that and is reflexive and transitive. A good exercise is to show that
the two definitions are equivalent (indeed, isomoprhic). the two definitions are equivalent (indeed, one embeds in the other).
#### Exercise `—↠—↠′` #### Exercise `—↠—↠′`
Show that the two notions of reflexive and transitive closure Show that the first notion of reflexive and transitive closure
above are isomorphic. above embeds into the second. Why are they not isomorphic?
## Confluence ## Confluence
@ -1141,36 +1141,35 @@ evidence of _any_ proposition whatsoever, regardless of its truth.
Type derivations correspond to trees. In informal notation, here Type derivations correspond to trees. In informal notation, here
is a type derivation for the Church numberal two: is a type derivation for the Church numberal two:
∋s ∋z ∋s ∋z
-------------------- ⊢` -------------- ⊢` ------------------ ⊢` -------------- ⊢`
∋s Γ₂ ⊢ ` "s" ⦂ ` ⇒ ` Γ₂ ⊢ ` "z" ⦂ ` ∋s Γ₂ ⊢ ` "s" ⦂ A ⇒ A Γ₂ ⊢ ` "z" ⦂ A
-------------------- ⊢` ------------------------------------------ _·_ ------------------ ⊢` ------------------------------------- _·_
Γ₂ ⊢ ` "s" ⦂ ` ⇒ ` Γ₂ ⊢ ` "s" · ` "z" ⦂ ` Γ₂ ⊢ ` "s" ⦂ A ⇒ A Γ₂ ⊢ ` "s" · ` "z" ⦂ A
------------------------------------------------ _·_ ---------------------------------------------- _·_
Γ₂ ⊢ ` "s" · (` "s" · ` "z") ⦂ ` Γ₂ ⊢ ` "s" · (` "s" · ` "z") ⦂ A
---------------------------------------------- ⊢ƛ -------------------------------------------- ⊢ƛ
Γ₁ ⊢ ƛ "z" ⇒ ` "s" · (` "s" · ` "z") ⦂ ` ⇒ ` Γ₁ ⊢ ƛ "z" ⇒ ` "s" · (` "s" · ` "z") ⦂ A ⇒ A
----------------------------------------------------------------- ⊢ƛ ------------------------------------------------------------- ⊢ƛ
∅ ⊢ ƛ "s" ⇒ ƛ "z" ⇒ ` "s" · (` "s" · ` "z") ⦂ (` ⇒ `) ⇒ ` ⇒ ` Γ ⊢ ƛ "s" ⇒ ƛ "z" ⇒ ` "s" · (` "s" · ` "z") ⦂ (A ⇒ A) ⇒ A ⇒ A
where `∋s` and `∋z` abbreviate the two derivations: where `∋s` and `∋z` abbreviate the two derivations:
------------------ Z ---------------- Z
"s" ≢ "z" Γ₁ ∋ "s" ⦂ ` ⇒ ` "s" ≢ "z" Γ₁ ∋ "s" ⦂ A ⇒ A
------------------------------ S ------------ Z ----------------------------- S ------------- Z
Γ₂ ∋ "s" ⦂ ` ⇒ ` Γ₂ ∋ "z" ⦂ ` Γ₂ ∋ "s" ⦂ A ⇒ A Γ₂ ∋ "z" ⦂ A
and where ``Γ₁ = ∅ , s ⦂ ` ⇒ ``` and ``Γ₂ = ∅ , s ⦂ ` ⇒ ` , z ⦂ ```. and where `Γ₁ = Γ , s ⦂ A ⇒ A` and `Γ₂ = Γ , s ⦂ A ⇒ A , z ⦂ A`.
In fact, `plusᶜ` also has this typing derivation if we replace `∅` by an The typing derivation is valid for any `Γ` and `A`, for instance,
arbitrary context `Γ`, and `` ` `` by an arbitrary type `A`, but the above we might take `Γ` to be `∅` and `A` to be `` ` ``.
will suffice for our purposes.
Here is the above typing derivation formalised in Agda. Here is the above typing derivation formalised in Agda.
\begin{code} \begin{code}
Ch : Type → Type Ch : Type → Type
Ch A = (A ⇒ A) ⇒ A ⇒ A Ch A = (A ⇒ A) ⇒ A ⇒ A
⊢twoᶜ : ∅ ⊢ twoᶜ ⦂ Ch ` ⊢twoᶜ : ∀ {Γ A} → Γ ⊢ twoᶜ ⦂ Ch A
⊢twoᶜ = ⊢ƛ (⊢ƛ (⊢` ∋s · (⊢` ∋s · ⊢` ∋z))) ⊢twoᶜ = ⊢ƛ (⊢ƛ (⊢` ∋s · (⊢` ∋s · ⊢` ∋z)))
where where
∋s = S ("s" ≠ "z") Z ∋s = S ("s" ≠ "z") Z
@ -1179,10 +1178,10 @@ Ch A = (A ⇒ A) ⇒ A ⇒ A
Here are the typings corresponding to computing two plus two. Here are the typings corresponding to computing two plus two.
\begin{code} \begin{code}
⊢two : ⊢ two ⦂ ` ⊢two : ∀ {Γ} → Γ ⊢ two ⦂ `
⊢two = ⊢suc (⊢suc ⊢zero) ⊢two = ⊢suc (⊢suc ⊢zero)
⊢plus : ⊢ plus ⦂ ` ⇒ ` ⇒ ` ⊢plus : ∀ {Γ} → Γ ⊢ plus ⦂ ` ⇒ ` ⇒ `
⊢plus = ⊢μ (⊢ƛ (⊢ƛ (⊢case (⊢` ∋m) (⊢` ∋n) ⊢plus = ⊢μ (⊢ƛ (⊢ƛ (⊢case (⊢` ∋m) (⊢` ∋n)
(⊢suc (⊢` ∋+ · ⊢` ∋m · ⊢` ∋n))))) (⊢suc (⊢` ∋+ · ⊢` ∋m · ⊢` ∋n)))))
where where
@ -1195,6 +1194,9 @@ Here are the typings corresponding to computing two plus two.
⊢2+2 : ∅ ⊢ plus · two · two ⦂ ` ⊢2+2 : ∅ ⊢ plus · two · two ⦂ `
⊢2+2 = ⊢plus · ⊢two · ⊢two ⊢2+2 = ⊢plus · ⊢two · ⊢two
\end{code} \end{code}
In contrast to our earlier examples, here we have typed `two` and `plus`
in an arbitrary context rather than the empty context; this makes it easy
to use them inside other binding contexts as well as at the top level.
Here the two lookup judgements `∋m` and `∋m` refer to two different Here the two lookup judgements `∋m` and `∋m` refer to two different
bindings of variables named `"m"`. In contrast, the two judgements `∋n` and bindings of variables named `"m"`. In contrast, the two judgements `∋n` and
`∋n` both refer to the same binding of `"n"` but accessed in different `∋n` both refer to the same binding of `"n"` but accessed in different
@ -1203,7 +1205,7 @@ the second after "m" is bound in the successor branch of the case.
And here are typings for the remainder of the Church example. And here are typings for the remainder of the Church example.
\begin{code} \begin{code}
⊢plusᶜ : ∅ ⊢ plusᶜ ⦂ Ch ` ⇒ Ch ` ⇒ Ch ` ⊢plusᶜ : ∀ {Γ A} → Γ ⊢ plusᶜ ⦂ Ch A ⇒ Ch A ⇒ Ch A
⊢plusᶜ = ⊢ƛ (⊢ƛ (⊢ƛ (⊢ƛ (⊢` ∋m · ⊢` ∋s · (⊢` ∋n · ⊢` ∋s · ⊢` ∋z))))) ⊢plusᶜ = ⊢ƛ (⊢ƛ (⊢ƛ (⊢ƛ (⊢` ∋m · ⊢` ∋s · (⊢` ∋n · ⊢` ∋s · ⊢` ∋z)))))
where where
∋m = S ("m" ≠ "z") (S ("m" ≠ "s") (S ("m" ≠ "n") Z)) ∋m = S ("m" ≠ "z") (S ("m" ≠ "s") (S ("m" ≠ "n") Z))
@ -1211,14 +1213,11 @@ And here are typings for the remainder of the Church example.
∋s = S ("s" ≠ "z") Z ∋s = S ("s" ≠ "z") Z
∋z = Z ∋z = Z
⊢sucᶜ : ⊢ sucᶜ ⦂ ` ⇒ ` ⊢sucᶜ : ∀ {Γ} → Γ ⊢ sucᶜ ⦂ ` ⇒ `
⊢sucᶜ = ⊢ƛ (⊢suc (⊢` ∋n)) ⊢sucᶜ = ⊢ƛ (⊢suc (⊢` ∋n))
where where
∋n = Z ∋n = Z
⊢2ᶜ : ∅ ⊢ twoᶜ · sucᶜ · `zero ⦂ `
⊢2ᶜ = ⊢twoᶜ · ⊢sucᶜ · ⊢zero
⊢2+2ᶜ : ∅ ⊢ plusᶜ · twoᶜ · twoᶜ · sucᶜ · `zero ⦂ ` ⊢2+2ᶜ : ∅ ⊢ plusᶜ · twoᶜ · twoᶜ · sucᶜ · `zero ⦂ `
⊢2+2ᶜ = ⊢plusᶜ · ⊢twoᶜ · ⊢twoᶜ · ⊢sucᶜ · ⊢zero ⊢2+2ᶜ = ⊢plusᶜ · ⊢twoᶜ · ⊢twoᶜ · ⊢sucᶜ · ⊢zero
\end{code} \end{code}