This commit is contained in:
wadler 2020-08-07 09:05:24 +01:00
commit 91a2dd4bf8
24 changed files with 265 additions and 206 deletions

View file

@ -28,15 +28,18 @@ addons:
env:
- SH=bash
before_install:
install:
# Install Stack:
- mkdir -p ~/.local/bin
- export PATH=$HOME/.local/bin:$PATH
- travis_retry curl -L https://www.stackage.org/stack/linux-x86_64 | tar xz --wildcards --strip-components=1 -C ~/.local/bin '*/stack'
# Install Pandoc:
- travis_retry curl -L https://github.com/jgm/pandoc/releases/download/2.9.2.1/pandoc-2.9.2.1-1-amd64.deb -o $HOME/pandoc.deb && sudo dpkg -i $HOME/pandoc.deb
# Install agda, agda-stdlib, and agda2html:
- make travis-setup
# Install agda, agda-stdlib, and acknowledgements:
- travis_wait 60 make travis-install-agda
- make travis-install-agda-stdlib
- make travis-install-acknowledgements
- ruby -S bundle install
script:
- agda --version

View file

@ -8,6 +8,9 @@ group :development do
gem 'guard'
gem 'guard-shell'
gem 'html-proofer'
# ffi-1.13.1 is broken on macos
# https://github.com/ffi/ffi/issues/791
gem 'ffi', '~> 1.12.2'
end
group :epub do

View file

@ -187,14 +187,11 @@ clobber: clean
.phony: clean clobber
# Setup Travis
travis-setup:\
$(HOME)/.local/bin/agda\
$(HOME)/.local/bin/acknowledgements\
$(HOME)/agda-stdlib-$(AGDA_STDLIB_VERSION)/src\
$(HOME)/.agda/defaults\
$(HOME)/.agda/libraries
travis-install-agda\
travis-install-agda-stdlib\
travis-install-acknowledgements
.phony: travis-setup
@ -215,11 +212,11 @@ $(HOME)/.agda/libraries:
echo "$(PLFA_DIR)/plfa.agda-lib" >> $(HOME)/.agda/libraries
$(HOME)/.local/bin/agda:
travis_retry curl -L https://github.com/agda/agda/archive/v$(AGDA_VERSION).zip\
curl -L https://github.com/agda/agda/archive/v$(AGDA_VERSION).zip\
-o $(HOME)/agda-$(AGDA_VERSION).zip
unzip -qq $(HOME)/agda-$(AGDA_VERSION).zip -d $(HOME)
cd $(HOME)/agda-$(AGDA_VERSION);\
stack install --stack-yaml=stack-8.0.2.yaml
stack install --stack-yaml=stack-$(GHC_VERSION).yaml
travis-uninstall-agda:
rm -rf $(HOME)/agda-$(AGDA_VERSION)/
@ -236,7 +233,7 @@ travis-reinstall-agda: travis-uninstall-agda travis-install-agda
travis-install-agda-stdlib: $(HOME)/agda-stdlib-$(AGDA_STDLIB_VERSION)/src
$(HOME)/agda-stdlib-$(AGDA_STDLIB_VERSION)/src:
travis_retry curl -L https://github.com/agda/agda-stdlib/archive/v$(AGDA_STDLIB_VERSION).zip\
curl -L https://github.com/agda/agda-stdlib/archive/v$(AGDA_STDLIB_VERSION).zip\
-o $(HOME)/agda-stdlib-$(AGDA_STDLIB_VERSION).zip
unzip -qq $(HOME)/agda-stdlib-$(AGDA_STDLIB_VERSION).zip -d $(HOME)
mkdir -p $(HOME)/.agda
@ -256,7 +253,7 @@ travis-reinstall-agda-stdlib: travis-uninstall-agda-stdlib travis-install-agda-s
travis-install-acknowledgements: $(HOME)/.local/bin/acknowledgements
$(HOME)/.local/bin/acknowledgements:
travis_retry curl -L https://github.com/plfa/acknowledgements/archive/master.zip\
curl -L https://github.com/plfa/acknowledgements/archive/master.zip\
-o $(HOME)/acknowledgements-master.zip
unzip -qq $(HOME)/acknowledgements-master.zip -d $(HOME)
cd $(HOME)/acknowledgements-master;\

View file

@ -6,6 +6,7 @@ permalink: /GettingStarted/
<!-- Links -->
[epub]: https://plfa.github.io/out/epub/plfa.epub
[plfa]: http://plfa.inf.ed.ac.uk
[plfa-dev]: https://github.com/plfa/plfa.github.io/archive/dev.zip
[plfa-status]: https://travis-ci.org/plfa/plfa.github.io.svg?branch=dev
@ -14,14 +15,14 @@ permalink: /GettingStarted/
[plfa-latest]: https://github.com/plfa/plfa.github.io/releases/latest
[plfa-master]: https://github.com/plfa/plfa.github.io/archive/master.zip
[agda]: https://github.com/agda/agda/releases/tag/v2.6.0.1
[agda-version]: https://img.shields.io/badge/agda-v2.6.0.1-blue.svg
[agda-docs-emacs-mode]: https://agda.readthedocs.io/en/v2.6.0.1/tools/emacs-mode.html
[agda-docs-emacs-notation]: https://agda.readthedocs.io/en/v2.6.0.1/tools/emacs-mode.html#notation-for-key-combinations
[agda-docs-package-system]: https://agda.readthedocs.io/en/v2.6.0.1/tools/package-system.html#example-using-the-standard-library
[agda]: https://github.com/agda/agda/releases/tag/v2.6.1
[agda-version]: https://img.shields.io/badge/agda-v2.6.1-blue.svg
[agda-docs-emacs-mode]: https://agda.readthedocs.io/en/v2.6.1/tools/emacs-mode.html
[agda-docs-emacs-notation]: https://agda.readthedocs.io/en/v2.6.1/tools/emacs-mode.html#notation-for-key-combinations
[agda-docs-package-system]: https://agda.readthedocs.io/en/v2.6.1/tools/package-system.html#example-using-the-standard-library
[agda-stdlib-version]: https://img.shields.io/badge/agda--stdlib-v1.1-blue.svg
[agda-stdlib]: https://github.com/agda/agda-stdlib/releases/tag/v1.1
[agda-stdlib-version]: https://img.shields.io/badge/agda--stdlib-v1.3-blue.svg
[agda-stdlib]: https://github.com/agda/agda-stdlib/releases/tag/v1.3
[haskell-stack]: https://docs.haskellstack.org/en/stable/README/
[haskell-ghc]: https://www.haskell.org/ghc/
@ -44,9 +45,6 @@ permalink: /GettingStarted/
[![Agda][agda-version]][agda]
[![agda-stdlib][agda-stdlib-version]][agda-stdlib]
# Getting Started with PLFA
## Dependencies for users
You can read PLFA [online][plfa] without installing anything.
@ -64,11 +62,11 @@ The easiest way to install any specific version of Agda is using [Stack][haskell
```bash
git clone https://github.com/agda/agda.git
cd agda
git checkout v2.6.0.1
git checkout v2.6.1
```
To install Agda, run Stack from the Agda source directory:
```bash
stack install --stack-yaml stack-8.6.5.yaml
stack install --stack-yaml stack-8.8.3.yaml
```
If you want Stack to use you system installation of GHC, you can pass the `--system-ghc` flag and select the appropriate `stack-*.yaml` file. For instance, if you have GHC 8.2.2 installed, run:
```bash
@ -81,7 +79,7 @@ You can get the required version of the Agda standard library from GitHub, eithe
```bash
git clone https://github.com/agda/agda-stdlib.git
cd agda-stdlib
git checkout v1.1
git checkout v1.3
```
You can get the latest version of Programming Language Foundations in Agda from GitHub, either by cloning the repository, or by downloading [the zip archive][plfa-dev]:
```bash
@ -227,7 +225,7 @@ bundle exec jekyll serve
### Building the EPUB
The EPUB version of the book is built using Pandoc. Here's how to build the EPUB:
The [EPUB version][epub] of the book is built using Pandoc. Here's how to build the EPUB:
1. Install a recent version of Pandoc, [available here][pandoc].
We recommend their official installer (on the linked page),

View file

@ -47,7 +47,7 @@ yourself, or your group in the case of group practicals).
```
import Relation.Binary.PropositionalEquality as Eq
open Eq using (_≡_; refl; cong; sym)
open Eq.≡-Reasoning using (begin_; _≡⟨⟩_; _≡⟨_⟩_; _∎)
open Eq.≡-Reasoning using (begin_; _≡⟨⟩_; step-≡; _∎)
open import Data.Nat using (; zero; suc; _+_; _*_; _∸_; _≤_; z≤n; s≤s)
open import Data.Nat.Properties using (+-assoc; +-identityʳ; +-suc; +-comm;
≤-refl; ≤-trans; ≤-antisym; ≤-total; +-monoʳ-≤; +-monoˡ-≤; +-mono-≤)
@ -142,7 +142,7 @@ Give an example of an operator that has an identity and is
associative but is not commutative.
#### Exercise `finite-+-assoc` (stretch) {#finite-plus-assoc}
#### Exercise `finite-|-assoc` (stretch) {#finite-plus-assoc}
Write out what is known about associativity of addition on each of the first four
days using a finite story of creation, as
@ -196,7 +196,7 @@ Show
for all naturals `n`. Did your proof require induction?
#### Exercise `∸-+-assoc` (practice) {#monus-plus-assoc}
#### Exercise `∸-|-assoc` (practice) {#monus-plus-assoc}
Show that monus associates with addition, that is,

View file

@ -45,7 +45,7 @@ yourself, or your group in the case of group practicals).
```
import Relation.Binary.PropositionalEquality as Eq
open Eq using (_≡_; refl; cong; sym)
open Eq.≡-Reasoning using (begin_; _≡⟨⟩_; _≡⟨_⟩_; _∎)
open Eq.≡-Reasoning using (begin_; _≡⟨⟩_; step-≡; _∎)
open import Data.Nat using (; zero; suc; _+_; _*_; _∸_; _≤_; z≤n; s≤s)
open import Data.Nat.Properties using (+-assoc; +-identityʳ; +-suc; +-comm;
≤-refl; ≤-trans; ≤-antisym; ≤-total; +-monoʳ-≤; +-monoˡ-≤; +-mono-≤)
@ -481,4 +481,3 @@ postulate
```
-- Your code goes here
```

View file

@ -42,7 +42,7 @@ yourself, or your group in the case of group practicals).
```
import Relation.Binary.PropositionalEquality as Eq
open Eq using (_≡_; refl; cong; sym)
open Eq.≡-Reasoning using (begin_; _≡⟨⟩_; _≡⟨_⟩_; _∎)
open Eq.≡-Reasoning using (begin_; _≡⟨⟩_; step-≡; _∎)
open import Data.Bool.Base using (Bool; true; false; T; _∧_; __; not)
open import Data.Nat using (; zero; suc; _+_; _*_; _∸_; _≤_; s≤s; z≤n)
open import Data.Nat.Properties using
@ -538,4 +538,3 @@ Provide proofs of the three postulates, `unstuck`, `preserves`, and `wttdgs` abo
```
-- Your code goes here
```

View file

@ -632,8 +632,10 @@ not fixed by the given arguments.
## Evaluation
```
data Gas : Set where
gas : → Gas
record Gas : Set where
constructor gas
field
amount :
data Finished {Γ A} (N : Γ ⊢ A) : Set where

View file

@ -351,8 +351,10 @@ module Problem2 where
### Evaluation
```
data Gas : Set where
gas : → Gas
record Gas : Set where
constructor gas
field
amount :
data Finished {Γ A} (N : Γ ⊢ A) : Set where

View file

@ -573,7 +573,7 @@ from `m` only if `n ≤ m`:
```
minus : (m n : ) (n≤m : n ≤ m) →
minus m zero _ = m
minus (suc m) (suc n) (s≤s m≤n) = minus m n m≤n
minus (suc m) (suc n) (s≤s n≤m) = minus m n n≤m
```
Unfortunately, it is painful to use, since we have to explicitly provide
@ -595,8 +595,8 @@ fill in an implicit of an *empty* record type, since there aren't any fields
after all. This is why `` is defined as an empty record.
The trick is to have an implicit argument of the type `T ⌊ n ≤? m ⌋`. Let's go
through what this means step-by-step. First, we run the decision procedure, `n
≤? m`. This provides us with evidence whether `n ≤ m` holds or not. We erase the
through what this means step-by-step. First, we run the decision procedure,
`n ≤? m`. This provides us with evidence whether `n ≤ m` holds or not. We erase the
evidence to a boolean. Finally, we apply `T`. Recall that `T` maps booleans into
the world of evidence: `true` becomes the unit type ``, and `false` becomes the
empty type `⊥`. Operationally, an implicit argument of this type works as a

View file

@ -696,23 +696,27 @@ _∘_ : ∀ {ℓ₁ ℓ₂ ℓ₃ : Level} {A : Set ℓ₁} {B : Set ℓ₂} {C
(g ∘ f) x = g (f x)
```
Further information on levels can be found in the [Agda Wiki][wiki].
Further information on levels can be found in the [Agda docs][docs].
[wiki]: http://wiki.portal.chalmers.se/agda/pmwiki.php?n=ReferenceManual.UniversePolymorphism
[docs]: https://agda.readthedocs.io/en/v2.6.1/language/universe-levels.html
## Standard library
Definitions similar to those in this chapter can be found in the
standard library:
Definitions similar to those in this chapter can be found in the standard
library. The Agda standard library defines `_≡⟨_⟩_` as `step-≡`, [which reverses
the order of the arguments][step-≡]. The standard library also defines a syntax
macro, which is automatically imported whenever you import `step-≡`, which
recovers the original argument order:
```
-- import Relation.Binary.PropositionalEquality as Eq
-- open Eq using (_≡_; refl; trans; sym; cong; cong-app; subst)
-- open Eq.≡-Reasoning using (begin_; _≡⟨⟩_; _≡⟨_⟩_; _∎)
-- open Eq.≡-Reasoning using (begin_; _≡⟨⟩_; step-≡; _∎)
```
Here the imports are shown as comments rather than code to avoid
collisions, as mentioned in the introduction.
[step-≡]: https://github.com/agda/agda-stdlib/blob/master/CHANGELOG/v1.3.md#changes-to-how-equational-reasoning-is-implemented
## Unicode

View file

@ -28,7 +28,7 @@ and some operations upon them. We also import a couple of new operations,
```
import Relation.Binary.PropositionalEquality as Eq
open Eq using (_≡_; refl; cong; sym)
open Eq.≡-Reasoning using (begin_; _≡⟨⟩_; _≡⟨_⟩_; _∎)
open Eq.≡-Reasoning using (begin_; _≡⟨⟩_; step-≡; _∎)
open import Data.Nat using (; zero; suc; _+_; _*_; _∸_)
```

View file

@ -1106,8 +1106,8 @@ with their corresponding proofs.
Definitions similar to those in this chapter can be found in the standard library:
```
import Data.List using (List; _++_; length; reverse; map; foldr; downFrom)
import Data.List.All using (All; []; _∷_)
import Data.List.Any using (Any; here; there)
import Data.List.Relation.Unary.All using (All; []; _∷_)
import Data.List.Relation.Unary.Any using (Any; here; there)
import Data.List.Membership.Propositional using (_∈_)
import Data.List.Properties
using (reverse-++-commute; map-compose; map-++-commute; foldr-++)

View file

@ -941,7 +941,7 @@ Such a pragma can only be invoked once, as invoking it twice would
raise confusion as to whether `2` is a value of type `` or type
`Data.Nat.`. Similar confusions arise if other pragmas are invoked
twice. For this reason, we will usually avoid pragmas in future chapters.
Information on pragmas can be found in the Agda documentation.
Information on pragmas can be found in the (Agda documentation)[https://agda.readthedocs.io/en/v2.6.1/language/pragmas.html].
## Unicode

View file

@ -34,8 +34,8 @@ as implication of false:
¬_ : Set → Set
¬ A = A → ⊥
```
This is a form of _proof by contradiction_: if assuming `A` leads
to the conclusion `⊥` (a contradiction), then we must have `¬ A`.
This is a form of _reductio ad absurdum_: if assuming `A` leads
to the conclusion `⊥` (an absurdity), then we must have `¬ A`.
Evidence that `¬ A` holds is of the form

View file

@ -401,14 +401,92 @@ sub-par : ∀{Γ A B} {N N : Γ , A ⊢ B} {M M : Γ ⊢ A}
sub-par pn pm = subst-par (par-subst-zero pm) pn
```
## Parallel reduction satisfies the diamond property
The heart of the confluence proof is made of stone, or rather, of
diamond! We show that parallel reduction satisfies the diamond
property: that if `M ⇛ N` and `M ⇛ N`, then `N ⇛ L` and `N ⇛ L` for
some `L`. The proof is relatively easy; it is parallel reduction's
_raison d'etre_.
some `L`. The typical proof is an induction on `M ⇛ N` and `M ⇛ N`
so that every possible pair gives rise to a witeness `L` given by
performing enough beta reductions in parallel.
However, a simpler approach is to perform as many beta reductions in
parallel as possible on `M`, say `M ⁺`, and then show that `N` also
parallel reduces to `M ⁺`. This is the idea of Takahashi's _complete
development_. The desired property may be illustrated as
M
/|
/ |
/ |
N 2
\ |
\ |
\|
M⁺
where downward lines are instances of `⇛`, so we call it the _triangle
property_.
```
_⁺ : ∀ {Γ A}
→ Γ ⊢ A → Γ ⊢ A
(` x) ⁺ = ` x
(ƛ M) ⁺ = ƛ (M ⁺)
((ƛ N) · M) ⁺ = N ⁺ [ M ⁺ ]
(L · M) ⁺ = L ⁺ · (M ⁺)
par-triangle : ∀ {Γ A} {M N : Γ ⊢ A}
→ M ⇛ N
-------
→ N ⇛ M ⁺
par-triangle pvar = pvar
par-triangle (pabs p) = pabs (par-triangle p)
par-triangle (pbeta p1 p2) = sub-par (par-triangle p1) (par-triangle p2)
par-triangle (papp {L = ƛ _ } (pabs p1) p2) =
pbeta (par-triangle p1) (par-triangle p2)
par-triangle (papp {L = ` _} p1 p2) = papp (par-triangle p1) (par-triangle p2)
par-triangle (papp {L = _ · _} p1 p2) = papp (par-triangle p1) (par-triangle p2)
```
The proof of the triangle property is an induction on `M ⇛ N`.
* Suppose `x ⇛ x`. Clearly `x ⁺ = x`, so `x ⇛ x`.
* Suppose `ƛ M ⇛ ƛ N`. By the induction hypothesis we have `N ⇛ M ⁺`
and by definition `(λ M) ⁺ = λ (M ⁺)`, so we conclude that `λ N ⇛ λ
(M ⁺)`.
* Suppose `(λ N) · M ⇛ N [ M ]`. By the induction hypothesis, we have
`N ⇛ N ⁺` and `M ⇛ M ⁺`. Since substitution respects parallel reduction,
it follows that `N [ M ] ⇛ N ⁺ [ M ⁺ ]`, but the right hand side
is exactly `((λ N) · M) ⁺`, hence `N [ M ] ⇛ ((λ N) · M) ⁺`.
* Suppose `(λ L) · M ⇛ (λ L) · M`. By the induction hypothesis
we have `L ⇛ L ⁺` and `M ⇛ M ⁺`; by definition `((λ L) · M) ⁺ = L ⁺ [ M ⁺ ]`.
It follows `(λ L) · M ⇛ L ⁺ [ M ⁺ ]`.
* Suppose `x · M ⇛ x · M`. By the induction hypothesis we have `M ⇛ M ⁺`
and `x ⇛ x ⁺` so that `x · M ⇛ x · M ⁺`.
The remaining case is proved in the same way, so we ignore it. (As
there is currently no way in Agda to expand the catch-all pattern in
the definition of `_⁺` for us before checking the right-hand side,
we have to write down the remaining case explicitly.)
The diamond property then follows by halving the diamond into two triangles.
M
/|\
/ | \
/ | \
N 2 N
\ | /
\ | /
\|/
M⁺
That is, the diamond property is proved by applying the
triangle property on each side with the same confluent term `M ⁺`.
```
par-diamond : ∀{Γ A} {M N N : Γ ⊢ A}
@ -416,90 +494,24 @@ par-diamond : ∀{Γ A} {M N N : Γ ⊢ A}
→ M ⇛ N
---------------------------------
→ Σ[ L ∈ Γ ⊢ A ] (N ⇛ L) × (N ⇛ L)
par-diamond (pvar{x = x}) pvar = ⟨ ` x , ⟨ pvar , pvar ⟩ ⟩
par-diamond (pabs p1) (pabs p2)
with par-diamond p1 p2
... | ⟨ L , ⟨ p3 , p4 ⟩ ⟩ =
⟨ ƛ L , ⟨ pabs p3 , pabs p4 ⟩ ⟩
par-diamond{Γ}{A}{L · M}{N}{N} (papp{Γ}{L}{L₁}{M}{M₁} p1 p3)
(papp{Γ}{L}{L₂}{M}{M₂} p2 p4)
with par-diamond p1 p2
... | ⟨ L₃ , ⟨ p5 , p6 ⟩ ⟩
with par-diamond p3 p4
... | ⟨ M₃ , ⟨ p7 , p8 ⟩ ⟩ =
⟨ (L₃ · M₃) , ⟨ (papp p5 p7) , (papp p6 p8) ⟩ ⟩
par-diamond (papp (pabs p1) p3) (pbeta p2 p4)
with par-diamond p1 p2
... | ⟨ N₃ , ⟨ p5 , p6 ⟩ ⟩
with par-diamond p3 p4
... | ⟨ M₃ , ⟨ p7 , p8 ⟩ ⟩ =
⟨ N₃ [ M₃ ] , ⟨ pbeta p5 p7 , sub-par p6 p8 ⟩ ⟩
par-diamond (pbeta p1 p3) (papp (pabs p2) p4)
with par-diamond p1 p2
... | ⟨ N₃ , ⟨ p5 , p6 ⟩ ⟩
with par-diamond p3 p4
... | ⟨ M₃ , ⟨ p7 , p8 ⟩ ⟩ =
⟨ (N₃ [ M₃ ]) , ⟨ sub-par p5 p7 , pbeta p6 p8 ⟩ ⟩
par-diamond {Γ}{A} (pbeta p1 p3) (pbeta p2 p4)
with par-diamond p1 p2
... | ⟨ N₃ , ⟨ p5 , p6 ⟩ ⟩
with par-diamond p3 p4
... | ⟨ M₃ , ⟨ p7 , p8 ⟩ ⟩ =
⟨ N₃ [ M₃ ] , ⟨ sub-par p5 p7 , sub-par p6 p8 ⟩ ⟩
par-diamond {M = M} p1 p2 = ⟨ M ⁺ , ⟨ par-triangle p1 , par-triangle p2 ⟩ ⟩
```
The proof is by induction on both premises.
* Suppose `x ⇛ x` and `x ⇛ x`.
We choose `L = x` and immediately have `x ⇛ x` and `x ⇛ x`.
* Suppose `ƛ N ⇛ ƛ N₁` and `ƛ N ⇛ ƛ N₂`.
By the induction hypothesis, there exists `L` such that
`N₁ ⇛ L` and `N₂ ⇛ L`. We choose `L = ƛ L` and
by `pabs` conclude that `ƛ N₁ ⇛ ƛ L` and `ƛ N₂ ⇛ ƛ L.
* Suppose that `L · M ⇛ L₁ · M₁` and `L · M ⇛ L₂ · M₂`.
By the induction hypothesis we have
`L₁ ⇛ L₃` and `L₂ ⇛ L₃` for some `L₃`.
Likewise, we have
`M₁ ⇛ M₃` and `M₂ ⇛ M₃` for some `M₃`.
We choose `L = L₃ · M₃` and conclude with two uses of `papp`.
* Suppose that `(ƛ N) · M ⇛ (ƛ N₁) · M₁` and `(ƛ N) · M ⇛ N₂ [ M₂ ]`
By the induction hypothesis we have
`N₁ ⇛ N₃` and `N₂ ⇛ N₃` for some `N₃`.
Likewise, we have
`M₁ ⇛ M₃` and `M₂ ⇛ M₃` for some `M₃`.
We choose `L = N₃ [ M₃ ]`.
We have `(ƛ N₁) · M₁ ⇛ N₃ [ M₃ ]` by rule `pbeta`
and conclude that `N₂ [ M₂ ] ⇛ N₃ [ M₃ ]` because
substitution respects parallel reduction.
* Suppose that `(ƛ N) · M ⇛ N₁ [ M₁ ]` and `(ƛ N) · M ⇛ (ƛ N₂) · M₂`.
The proof of this case is the mirror image of the last one.
* Suppose that `(ƛ N) · M ⇛ N₁ [ M₁ ]` and `(ƛ N) · M ⇛ N₂ [ M₂ ]`.
By the induction hypothesis we have
`N₁ ⇛ N₃` and `N₂ ⇛ N₃` for some `N₃`.
Likewise, we have
`M₁ ⇛ M₃` and `M₂ ⇛ M₃` for some `M₃`.
We choose `L = N₃ [ M₃ ]`.
We have both `(ƛ N₁) · M₁ ⇛ N₃ [ M₃ ]`
and `(ƛ N₂) · M₂ ⇛ N₃ [ M₃ ]`
by rule `pbeta`
This step is optional, though, in the presence of triangle property.
#### Exercise (practice)
Draw pictures that represent the proofs of each of the six cases in
the above proof of `par-diamond`. The pictures should consist of nodes
and directed edges, where each node is labeled with a term and each
edge represents parallel reduction.
* Prove the diamond property `par-diamond` directly by induction on `M ⇛ N` and `M ⇛ N`.
* Draw pictures that represent the proofs of each of the six cases in
the direct proof of `par-diamond`. The pictures should consist of nodes
and directed edges, where each node is labeled with a term and each
edge represents parallel reduction.
## Proof of confluence for parallel reduction
As promised at the beginning, the proof that parallel reduction is
confluent is easy now that we know it satisfies the diamond property.
confluent is easy now that we know it satisfies the triangle property.
We just need to prove the strip lemma, which states that
if `M ⇛ N` and `M ⇛* N`, then
`N ⇛* L` and `N ⇛ L` for some `L`.
@ -519,7 +531,7 @@ where downward lines are instances of `⇛` or `⇛*`, depending on how
they are marked.
The proof of the strip lemma is a straightforward induction on `M ⇛* N`,
using the diamond property in the induction step.
using the triangle property in the induction step.
```
strip : ∀{Γ A} {M N N : Γ ⊢ A}
@ -529,11 +541,8 @@ strip : ∀{Γ A} {M N N : Γ ⊢ A}
→ Σ[ L ∈ Γ ⊢ A ] (N ⇛* L) × (N ⇛ L)
strip{Γ}{A}{M}{N}{N} mn (M ∎) = ⟨ N , ⟨ N ∎ , mn ⟩ ⟩
strip{Γ}{A}{M}{N}{N} mn (M ⇛⟨ mm' ⟩ m'n')
with par-diamond mn mm'
... | ⟨ L , ⟨ nl , m'l ⟩ ⟩
with strip m'l m'n'
... | ⟨ L , ⟨ ll' , n'l' ⟩ ⟩ =
⟨ L , ⟨ (N ⇛⟨ nl ⟩ ll') , n'l' ⟩ ⟩
with strip (par-triangle mm') m'n'
... | ⟨ L , ⟨ ll' , n'l' ⟩ ⟩ = ⟨ L , ⟨ N ⇛⟨ par-triangle mn ⟩ ll' , n'l' ⟩ ⟩
```
The proof of confluence for parallel reduction is now proved by
@ -605,19 +614,16 @@ Broadly speaking, this proof of confluence, based on parallel
reduction, is due to W. Tait and P. Martin-Lof (see Barendredgt 1984,
Section 3.2). Details of the mechanization come from several sources.
The `subst-par` lemma is the "strong substitutivity" lemma of Shafer,
Tebbi, and Smolka (ITP 2015). The proofs of `par-diamond`, `strip`,
and `par-confluence` are based on Pfenning's 1992 technical report
about the Church-Rosser theorem. In addition, we consulted Nipkow and
Tebbi, and Smolka (ITP 2015). The proofs of `par-triangle`, `strip`,
and `par-confluence` are based on the notion of complete development
by Takahashi (1995) and Pfenning's 1992 technical report about the
Church-Rosser theorem. In addition, we consulted Nipkow and
Berghofer's mechanization in Isabelle, which is based on an earlier
article by Nipkow (JAR 1996). We opted not to use the "complete
developments" approach of Takahashi (1995) because we felt that the
proof was simple enough based solely on parallel reduction. There are
many more mechanizations of the Church-Rosser theorem that we have not
yet had the time to read, including Shankar's (J. ACM 1988) and
Homeier's (TPHOLs 2001).
article by Nipkow (JAR 1996).
## Unicode
This chapter uses the following unicode:
⇛ U+3015 RIGHTWARDS TRIPLE ARROW (\r== or \Rrightarrow)
⇛ U+21DB RIGHTWARDS TRIPLE ARROW (\r== or \Rrightarrow)
⁺ U+207A SUPERSCRIPT PLUS SIGN (\^+)

View file

@ -1043,8 +1043,10 @@ refer to preservation, since it is built-in to the definition of reduction.
As previously, gas is specified by a natural number:
```
data Gas : Set where
gas : → Gas
record Gas : Set where
constructor gas
field
amount :
```
When our evaluator returns a term `N`, it will either give evidence that
`N` is a value or indicate that it ran out of gas:
@ -1375,4 +1377,3 @@ This chapter uses the following unicode:
₆ U+2086 SUBSCRIPT SIX (\_6)
₇ U+2087 SUBSCRIPT SEVEN (\_7)
≠ U+2260 NOT EQUAL TO (\=n)

View file

@ -1089,8 +1089,10 @@ progress (case× L M) with progress L
## Evaluation
```
data Gas : Set where
gas : → Gas
record Gas : Set where
constructor gas
field
amount :
data Finished {Γ A} (N : Γ ⊢ A) : Set where

View file

@ -918,8 +918,10 @@ per unit of gas.
By analogy, we will use the name _gas_ for the parameter which puts a
bound on the number of reduction steps. `Gas` is specified by a natural number:
```
data Gas : Set where
gas : → Gas
record Gas : Set where
constructor gas
field
amount :
```
When our evaluator returns a term `N`, it will either give evidence that
`N` is a value or indicate that it ran out of gas:
@ -950,7 +952,6 @@ data Steps (L : Term) : Set where
The evaluator takes gas and evidence that a term is well typed,
and returns the corresponding steps:
```
{-# TERMINATING #-}
eval : ∀ {L A}
→ Gas
→ ∅ ⊢ L ⦂ A
@ -959,7 +960,7 @@ 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)
... | step {M} L—→M with eval (gas m) (preserve ⊢L L—→M)
... | steps M—↠N fin = steps (L —→⟨ L—→M ⟩ M—↠N) fin
```
Let `L` be the name of the term we are reducing, and `⊢L` be the

View file

@ -48,7 +48,7 @@ system that _decides_ whether any two substitutions are equal.
```
import Relation.Binary.PropositionalEquality as Eq
open Eq using (_≡_; refl; sym; cong; cong₂; cong-app)
open Eq.≡-Reasoning using (begin_; _≡⟨⟩_; _≡⟨_⟩_; _∎)
open Eq.≡-Reasoning using (begin_; _≡⟨⟩_; step-≡; _∎)
open import Function using (_∘_)
open import plfa.part2.Untyped
using (Type; Context; _⊢_; ★; _∋_; ∅; _,_; Z; S_; `_; ƛ_; _·_;

View file

@ -1,5 +1,5 @@
---
title : "Subtyping: records"
title : "Subtyping: Records"
layout : page
prev : /More/
permalink : /Subtyping/
@ -1276,4 +1276,3 @@ of the form:
Subtyping. In ACM Trans. Program. Lang. Syst. Volume 16, 1994.
* Types and Programming Languages. Benjamin C. Pierce. The MIT Press. 2002.

View file

@ -547,8 +547,10 @@ As previously, progress immediately yields an evaluator.
Gas is specified by a natural number:
```
data Gas : Set where
gas : → Gas
record Gas : Set where
constructor gas
field
amount :
```
When our evaluator returns a term `N`, it will either give evidence that
`N` is normal or indicate that it ran out of gas:

View file

@ -54,9 +54,6 @@ down a denotational semantics of the lambda calculus.
## Imports
<!-- JGS: for equational reasoning
open import Relation.Binary using (Setoid)
-->
```
open import Agda.Primitive using (lzero; lsuc)
open import Data.Empty using (⊥-elim)

44
travis-build-cache.sh Executable file
View file

@ -0,0 +1,44 @@
#!/bin/bash
# Dependencies:
# - curl <https://curl.haxx.se/>
# - yq <https://github.com/mikefarah/yq>
# Modify .travis.yml:
# - Remove 'script' and 'deploy' phases;
# - Add 'merge_mode';
# - Create JSON request.
#
body=$(cat .travis.yml \
| yq w - script "echo 'Done'"\
| yq d - before_deploy \
| yq d - deploy \
| yq p - config \
| yq w - message "Build cache" \
| yq w - branch dev \
| yq w - merge_mode replace \
| yq p - request -j)
# Send request to Travis.
#
resp=$(curl -s -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Travis-API-Version: 3" \
-H "Authorization: token $TRAVIS_TOKEN" \
-d "$body" \
https://api.travis-ci.org/repo/plfa%2Fplfa.github.io/requests)
# Output response.
#
echo "$resp" \
| yq d - request.configs \
| yq d - request.config \
| yq r - --prettyPrint
# Output configuration.
#
echo "$resp" \
| yq r - request.config \
| yq p - config \
| yq r - --prettyPrint