migrate all tutorials from Markdown to Org mode

Converted with pandoc 3.7 (markdown → org), all 17 files:
- README, references, 15 tutorial units
- Internal file links updated from .md to .org
- Source code blocks (#+begin_src lean) preserved
- Tables, math notation, links intact

For the Emacs workflow.
This commit is contained in:
2026-05-28 20:15:38 +02:00
parent 0cf85517c2
commit 6e2914b06e
22 changed files with 805 additions and 611 deletions

View File

@@ -1,48 +0,0 @@
# Lean 4 + Programming Language Semantics
A self-study curriculum for computer scientists who know PL theory and want
to mechanize proofs in Lean 4 — from syntax to soundness of the
Hindley-Milner type system.
## Structure
```
├── README.md ← this file
├── tutorial-01-basics/ ← Lean 4 fundamentals
│ ├── 01-types-and-functions.md
│ ├── 02-inductive-types.md
│ ├── 03-propositions-and-proofs.md
│ ├── 04-quantifiers-and-equality.md
│ ├── 05-advanced-tactics.md
│ ├── 06-structures-type-classes.md
│ └── 07-dependent-types.md
├── tutorial-02-semantics/ ← PL semantics in Lean
│ ├── 08-syntax-representation.md
│ ├── 09-substitution.md
│ ├── 10-small-step-semantics.md
│ ├── 11-stlc-type-system.md
│ ├── 12-type-safety.md
│ ├── 13-hm-declarative.md
│ ├── 14-algorithm-w.md
│ └── 15-soundness-completeness.md
└── references.md ← all cited resources
```
## How to Use
1. Install Lean 4 (VS Code + `lean4` extension):
[lean-lang.org/lean4/doc/quickstart.html](https://lean-lang.org/lean4/doc/quickstart.html)
2. Start with **Tutorial 1**, Unit 1. Each unit is a standalone `.md` file with
inline Lean exercises.
3. Type the exercises into a `.lean` file and make it compile.
4. After Tutorial 1, move to **Tutorial 2** to mechanize STLC and HM.
## Prerequisites
- Functional programming (Haskell/OCaml familiarity)
- Basic PL theory (lambda calculus, operational semantics, type systems)
- No prior proof assistant experience required
## References
See [references.md](references.md) for the full list of resources.

58
README.org Normal file
View File

@@ -0,0 +1,58 @@
* Lean 4 + Programming Language Semantics
:PROPERTIES:
:CUSTOM_ID: lean-4-programming-language-semantics
:END:
A self-study curriculum for computer scientists who know PL theory and want
to mechanize proofs in Lean 4 --- from syntax to soundness of the
Hindley-Milner type system.
** Structure
:PROPERTIES:
:CUSTOM_ID: structure
:END:
#+begin_example
├── README.org ← this file
├── tutorial-01-basics/ ← Lean 4 fundamentals
│ ├── 01-types-and-functions.org
│ ├── 02-inductive-types.org
│ ├── 03-propositions-and-proofs.org
│ ├── 04-quantifiers-and-equality.org
│ ├── 05-advanced-tactics.org
│ ├── 06-structures-type-classes.org
│ └── 07-dependent-types.org
├── tutorial-02-semantics/ ← PL semantics in Lean
│ ├── 08-syntax-representation.org
│ ├── 09-substitution.org
│ ├── 10-small-step-semantics.org
│ ├── 11-stlc-type-system.org
│ ├── 12-type-safety.org
│ ├── 13-hm-declarative.org
│ ├── 14-algorithm-w.org
│ └── 15-soundness-completeness.org
└── references.org ← all cited resources
#+end_example
** How to Use
:PROPERTIES:
:CUSTOM_ID: how-to-use
:END:
1. Install Lean 4 (VS Code + =lean4= extension):
[[https://lean-lang.org/lean4/doc/quickstart.html][lean-lang.org/lean4/doc/quickstart.html]]
2. Start with *Tutorial 1*, Unit 1. Each unit is a standalone =.org= file with
inline Lean exercises.
3. Type the exercises into a =.lean= file and make it compile.
4. After Tutorial 1, move to *Tutorial 2* to mechanize STLC and HM.
** Prerequisites
:PROPERTIES:
:CUSTOM_ID: prerequisites
:END:
- Functional programming (Haskell/OCaml familiarity)
- Basic PL theory (lambda calculus, operational semantics, type systems)
- No prior proof assistant experience required
** References
:PROPERTIES:
:CUSTOM_ID: references
:END:
See [[file:references.org]] for the full list of resources.

View File

@@ -1,39 +0,0 @@
# References
## Primary Learning Resources
| Abbr | Title | Link |
|------|-------|------|
| FPIL | *Functional Programming in Lean* | https://lean-lang.org/functional_programming_in_lean/ |
| TPIL | *Theorem Proving in Lean 4* | https://leanprover.github.io/theorem_proving_in_lean4/ |
| MiL | *Mathematics in Lean* | https://leanprover-community.github.io/mathematics_in_lean/ |
## PL Semantics Formalizations in Lean 4
| Resource | What it covers | Link |
|----------|---------------|------|
| syndikos/lean4-stlc | STLC: syntax, semantics, typing, metatheory (Progress + Preservation) | https://github.com/syndikos/lean4-stlc |
| chenson2018/LeanScratch | Untyped λ-calculus: de Bruijn + locally nameless, confluence proofs | https://github.com/chenson2018/LeanScratch |
| sdemos/type-inference | STLC + HM type inference, soundness & completeness of W | https://github.com/sdemos/type-inference |
| rami3l/PLFaLean | PLFA Parts 23 translated to Lean 4 | https://github.com/rami3l/PLFaLean |
## PL Theory (Non-Lean)
| Resource | Format | Link |
|----------|--------|------|
| Software Foundations Vol.2 | Rocq book | https://softwarefoundations.cis.upenn.edu/ |
| PLFA Part 2 | Agda book | https://plfa.github.io/ |
| Chris Henson: Beginner Resources for Formalizing Lambda Calculi | Blog post | https://chrishenson.net/posts/2025-05-10-formalized_lambda_calculus.html |
## HM Type System
| Resource | Format | Link |
|----------|--------|------|
| Wikipedia: Hindley-Milner type system | Reference | https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system |
| Jeff Vaughan: "A proof of correctness for the HM type inference algorithm" | PDF (2008) | https://www.jeffvaughan.net/docs/hmproof.pdf |
## Community
- Official site: https://lean-lang.org/
- Zulip chat: https://leanprover.zulipchat.com/
- Lean 4 docs: https://lean-lang.org/documentation/

51
references.org Normal file
View File

@@ -0,0 +1,51 @@
* References
:PROPERTIES:
:CUSTOM_ID: references
:END:
** Primary Learning Resources
:PROPERTIES:
:CUSTOM_ID: primary-learning-resources
:END:
| Abbr | Title | Link |
|------+----------------------------------+-------------------------------------------------------------|
| FPIL | /Functional Programming in Lean/ | https://lean-lang.org/functional_programming_in_lean/ |
| TPIL | /Theorem Proving in Lean 4/ | https://leanprover.github.io/theorem_proving_in_lean4/ |
| MiL | /Mathematics in Lean/ | https://leanprover-community.github.io/mathematics_in_lean/ |
** PL Semantics Formalizations in Lean 4
:PROPERTIES:
:CUSTOM_ID: pl-semantics-formalizations-in-lean-4
:END:
| Resource | What it covers | Link |
|-------------------------+-----------------------------------------------------------------------+--------------------------------------------|
| syndikos/lean4-stlc | STLC: syntax, semantics, typing, metatheory (Progress + Preservation) | https://github.com/syndikos/lean4-stlc |
| chenson2018/LeanScratch | Untyped λ-calculus: de Bruijn + locally nameless, confluence proofs | https://github.com/chenson2018/LeanScratch |
| sdemos/type-inference | STLC + HM type inference, soundness & completeness of W | https://github.com/sdemos/type-inference |
| rami3l/PLFaLean | PLFA Parts 2--3 translated to Lean 4 | https://github.com/rami3l/PLFaLean |
** PL Theory (Non-Lean)
:PROPERTIES:
:CUSTOM_ID: pl-theory-non-lean
:END:
| Resource | Format | Link |
|-----------------------------------------------------------------+-----------+--------------------------------------------------------------------------|
| Software Foundations Vol.2 | Rocq book | https://softwarefoundations.cis.upenn.edu/ |
| PLFA Part 2 | Agda book | https://plfa.github.io/ |
| Chris Henson: Beginner Resources for Formalizing Lambda Calculi | Blog post | https://chrishenson.net/posts/2025-05-10-formalized_lambda_calculus.html |
** HM Type System
:PROPERTIES:
:CUSTOM_ID: hm-type-system
:END:
| Resource | Format | Link |
|----------------------------------------------------------------------------+------------+------------------------------------------------------------------|
| Wikipedia: Hindley-Milner type system | Reference | https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system |
| Jeff Vaughan: "A proof of correctness for the HM type inference algorithm" | PDF (2008) | https://www.jeffvaughan.net/docs/hmproof.pdf |
** Community
:PROPERTIES:
:CUSTOM_ID: community
:END:
- Official site: https://lean-lang.org/
- Zulip chat: https://leanprover.zulipchat.com/
- Lean 4 docs: https://lean-lang.org/documentation/

View File

@@ -1,107 +0,0 @@
# Unit 1 — Types and Functions
**Tutorial 1: Lean 4 Fundamentals** · [← Back to README](../README.md)
## Goals
- Define functions with `def` and lambda notation
- Understand Lean's basic types: `Nat`, `Int`, `String`, `Bool`, `List`, `Option`
- Use pattern matching and `match` expressions
- Run code with `#eval`
## Source
*Functional Programming in Lean* (FPIL), Chapters 12
→ https://lean-lang.org/functional_programming_in_lean/
## Concepts
| Concept | Lean syntax | Example |
|---------|------------|---------|
| Function definition | `def f (x : Nat) : Nat :=` | `def double (x : Nat) : Nat := x + x` |
| Lambda | `fun x => ...` | `fun x => x + 1` |
| Pattern matching | `match e with \| pat => ...` | `match n with \| 0 => "zero" \| _ => "non-zero"` |
| Recursion | `def f ... := match ...` | Structural recursion only (no general fixpoint) |
| `#eval` | `#eval expr` | `#eval double 21` prints `42` |
## Exercises
> **How to work**: Create a file `Unit1.lean`. Write each exercise, then
> `#eval` to test it (if it's a function) or just make it compile (if it's a
> proof or definition). Fill in the `sorry` placeholders.
### Exercise 1.1 — Warm-up functions
```lean
-- (a) Write a function that returns the absolute difference between two nats
def absDiff (a b : Nat) : Nat :=
sorry
#eval absDiff 7 3 -- expected: 4
#eval absDiff 3 7 -- expected: 4
#eval absDiff 5 5 -- expected: 0
-- (b) Write a function that checks whether a list contains an element
def contains [BEq α] (x : α) (xs : List α) : Bool :=
sorry
#eval contains 3 [1, 2, 3, 4] -- expected: true
#eval contains 5 [1, 2, 3, 4] -- expected: false
-- (c) Write `map` (without looking at the standard library)
def myMap (f : α β) (xs : List α) : List β :=
sorry
#eval myMap (fun x => x * 2) [1, 2, 3] -- expected: [2, 4, 6]
```
### Exercise 1.2 — Recursion on lists
```lean
-- (a) Sum of a list
def sumList (xs : List Nat) : Nat :=
sorry
#eval sumList [1, 2, 3, 4] -- expected: 10
-- (b) Reverse a list (the slow way is fine)
def myReverse (xs : List α) : List α :=
sorry
#eval myReverse [1, 2, 3] -- expected: [3, 2, 1]
-- (c) Filter: keep elements satisfying p
def myFilter (p : α Bool) (xs : List α) : List α :=
sorry
#eval myFilter (fun x => x % 2 == 0) [1, 2, 3, 4, 5, 6] -- expected: [2, 4, 6]
```
### Exercise 1.3 — Option type
```lean
-- (a) Safe head
def safeHead (xs : List α) : Option α :=
sorry
#eval safeHead ([1, 2, 3] : List Nat) -- expected: some 1
#eval safeHead ([] : List Nat) -- expected: none
-- (b) Safe division
def safeDiv (a b : Nat) : Option Nat :=
sorry
#eval safeDiv 10 2 -- expected: some 5
#eval safeDiv 10 0 -- expected: none
-- (c) Lookup in an association list
def lookup [BEq α] (key : α) (alist : List (α × β)) : Option β :=
sorry
#eval lookup "b" [("a", 1), ("b", 2), ("c", 3)] -- expected: some 2
#eval lookup "d" [("a", 1), ("b", 2), ("c", 3)] -- expected: none
```
---
← [Back to README](../README.md) · Next: [Unit 2 — Inductive Types](02-inductive-types.md)

View File

@@ -0,0 +1,126 @@
* Unit 1 --- Types and Functions
:PROPERTIES:
:CUSTOM_ID: unit-1-types-and-functions
:END:
*Tutorial 1: Lean 4 Fundamentals* · [[../README.org][← Back to README]]
** Goals
:PROPERTIES:
:CUSTOM_ID: goals
:END:
- Define functions with =def= and lambda notation
- Understand Lean's basic types: =Nat=, =Int=, =String=, =Bool=, =List=, =Option=
- Use pattern matching and =match= expressions
- Run code with =#eval=
** Source
:PROPERTIES:
:CUSTOM_ID: source
:END:
/Functional Programming in Lean/ (FPIL), Chapters 1--2
→ https://lean-lang.org/functional_programming_in_lean/
** Concepts
:PROPERTIES:
:CUSTOM_ID: concepts
:END:
| Concept | Lean syntax | Example |
|---------------------+------------------------------+--------------------------------------------------|
| Function definition | =def f (x : Nat) : Nat :== | =def double (x : Nat) : Nat := x + x= |
| Lambda | =fun x => ...= | =fun x => x + 1= |
| Pattern matching | =match e with \| pat => ...= | =match n with \| 0 => "zero" \| _ => "non-zero"= |
| Recursion | =def f ... := match ...= | Structural recursion only (no general fixpoint) |
| =#eval= | =#eval expr= | =#eval double 21= prints =42= |
** Exercises
:PROPERTIES:
:CUSTOM_ID: exercises
:END:
#+begin_quote
*How to work*: Create a file =Unit1.lean=. Write each exercise, then
=#eval= to test it (if it's a function) or just make it compile (if it's a
proof or definition). Fill in the =sorry= placeholders.
#+end_quote
*** Exercise 1.1 --- Warm-up functions
:PROPERTIES:
:CUSTOM_ID: exercise-1.1-warm-up-functions
:END:
#+begin_src lean
-- (a) Write a function that returns the absolute difference between two nats
def absDiff (a b : Nat) : Nat :=
sorry
#eval absDiff 7 3 -- expected: 4
#eval absDiff 3 7 -- expected: 4
#eval absDiff 5 5 -- expected: 0
-- (b) Write a function that checks whether a list contains an element
def contains [BEq α] (x : α) (xs : List α) : Bool :=
sorry
#eval contains 3 [1, 2, 3, 4] -- expected: true
#eval contains 5 [1, 2, 3, 4] -- expected: false
-- (c) Write `map` (without looking at the standard library)
def myMap (f : α β) (xs : List α) : List β :=
sorry
#eval myMap (fun x => x * 2) [1, 2, 3] -- expected: [2, 4, 6]
#+end_src
*** Exercise 1.2 --- Recursion on lists
:PROPERTIES:
:CUSTOM_ID: exercise-1.2-recursion-on-lists
:END:
#+begin_src lean
-- (a) Sum of a list
def sumList (xs : List Nat) : Nat :=
sorry
#eval sumList [1, 2, 3, 4] -- expected: 10
-- (b) Reverse a list (the slow way is fine)
def myReverse (xs : List α) : List α :=
sorry
#eval myReverse [1, 2, 3] -- expected: [3, 2, 1]
-- (c) Filter: keep elements satisfying p
def myFilter (p : α Bool) (xs : List α) : List α :=
sorry
#eval myFilter (fun x => x % 2 == 0) [1, 2, 3, 4, 5, 6] -- expected: [2, 4, 6]
#+end_src
*** Exercise 1.3 --- Option type
:PROPERTIES:
:CUSTOM_ID: exercise-1.3-option-type
:END:
#+begin_src lean
-- (a) Safe head
def safeHead (xs : List α) : Option α :=
sorry
#eval safeHead ([1, 2, 3] : List Nat) -- expected: some 1
#eval safeHead ([] : List Nat) -- expected: none
-- (b) Safe division
def safeDiv (a b : Nat) : Option Nat :=
sorry
#eval safeDiv 10 2 -- expected: some 5
#eval safeDiv 10 0 -- expected: none
-- (c) Lookup in an association list
def lookup [BEq α] (key : α) (alist : List (α × β)) : Option β :=
sorry
#eval lookup "b" [("a", 1), ("b", 2), ("c", 3)] -- expected: some 2
#eval lookup "d" [("a", 1), ("b", 2), ("c", 3)] -- expected: none
#+end_src
--------------
← [[../README.org][Back to README]] · Next: [[file:02-inductive-types.org][Unit 2 --- Inductive Types]]

View File

@@ -1,34 +1,46 @@
# Unit 2 Inductive Types * Unit 2 --- Inductive Types
:PROPERTIES:
:CUSTOM_ID: unit-2-inductive-types
:END:
*Tutorial 1: Lean 4 Fundamentals* · [[../README.org][← Back to README]]
**Tutorial 1: Lean 4 Fundamentals** · [← Back to README](../README.md) ** Goals
:PROPERTIES:
## Goals :CUSTOM_ID: goals
:END:
- Define inductive data types with the `inductive` keyword - Define inductive data types with the =inductive= keyword
- Understand constructors and pattern matching - Understand constructors and pattern matching
- Write structurally recursive functions over inductive types - Write structurally recursive functions over inductive types
- Define `Nat`, `List`, and `Tree` from scratch - Define =Nat=, =List=, and =Tree= from scratch
## Sources ** Sources
:PROPERTIES:
- *Theorem Proving in Lean 4* (TPIL), Chapter 7 "Inductive Types" :CUSTOM_ID: sources
:END:
- /Theorem Proving in Lean 4/ (TPIL), Chapter 7 "Inductive Types"
→ https://leanprover.github.io/theorem_proving_in_lean4/ → https://leanprover.github.io/theorem_proving_in_lean4/
- *Functional Programming in Lean* (FPIL), Chapter 1 - /Functional Programming in Lean/ (FPIL), Chapter 1
## Concepts
** Concepts
:PROPERTIES:
:CUSTOM_ID: concepts
:END:
| Concept | Lean syntax | | Concept | Lean syntax |
|---------|------------| |-------------------------------+-----------------------------------------------------------|
| Inductive definition | `inductive Name where \| ctor1 : ... → Name` | | Inductive definition | =inductive Name where \| ctor1 : ... → Name= |
| Pattern matching constructors | `match t with \| ctor1 x => ... \| ctor2 y => ...` | | Pattern matching constructors | =match t with \| ctor1 x => ... \| ctor2 y => ...= |
| Structural recursion | Recursion on *structurally smaller* subterms only | | Structural recursion | Recursion on /structurally smaller/ subterms only |
| `deriving` clauses | `deriving Repr, BEq, DecidableEq` for auto-generated code | | =deriving= clauses | =deriving Repr, BEq, DecidableEq= for auto-generated code |
## Exercises ** Exercises
:PROPERTIES:
### Exercise 2.1 — Define `Nat` from scratch :CUSTOM_ID: exercises
:END:
```lean *** Exercise 2.1 --- Define =Nat= from scratch
:PROPERTIES:
:CUSTOM_ID: exercise-2.1-define-nat-from-scratch
:END:
#+begin_src lean
inductive MyNat where inductive MyNat where
| zero : MyNat | zero : MyNat
| succ : MyNat → MyNat | succ : MyNat → MyNat
@@ -46,11 +58,13 @@ def myMul (a b : MyNat) : MyNat :=
-- (c) Prove that zero is a right identity: myAdd a MyNat.zero = a -- (c) Prove that zero is a right identity: myAdd a MyNat.zero = a
-- (We'll do proofs properly in Unit 3, but try `by rfl` for now) -- (We'll do proofs properly in Unit 3, but try `by rfl` for now)
``` #+end_src
### Exercise 2.2 Define `List α` from scratch *** Exercise 2.2 --- Define =List α= from scratch
:PROPERTIES:
```lean :CUSTOM_ID: exercise-2.2-define-list-α-from-scratch
:END:
#+begin_src lean
inductive MyList (α : Type) where inductive MyList (α : Type) where
| nil : MyList α | nil : MyList α
| cons : α → MyList α → MyList α | cons : α → MyList α → MyList α
@@ -66,11 +80,13 @@ def myAppend {α : Type} (xs ys : MyList α) : MyList α :=
-- (c) Prove: myLength (myAppend xs ys) = myLength xs + myLength ys -- (c) Prove: myLength (myAppend xs ys) = myLength xs + myLength ys
-- (Try this after Unit 4/5) -- (Try this after Unit 4/5)
``` #+end_src
### Exercise 2.3 Binary trees *** Exercise 2.3 --- Binary trees
:PROPERTIES:
```lean :CUSTOM_ID: exercise-2.3-binary-trees
:END:
#+begin_src lean
inductive BinTree (α : Type) where inductive BinTree (α : Type) where
| leaf : BinTree α | leaf : BinTree α
| node : BinTree αα → BinTree α → BinTree α | node : BinTree αα → BinTree α → BinTree α
@@ -99,8 +115,8 @@ def inorder {α : Type} (t : BinTree α) : List α :=
-- Hint: you may want a helper with min/max bounds. -- Hint: you may want a helper with min/max bounds.
def isBST (t : BinTree Int) : Bool := def isBST (t : BinTree Int) : Bool :=
sorry sorry
``` #+end_src
--- --------------
← [Previous: Unit 1](01-types-and-functions.md) · Next: [Unit 3 — Propositions and Proofs](03-propositions-and-proofs.md) ← [[file:01-types-and-functions.org][Previous: Unit 1]] · Next: [[file:03-propositions-and-proofs.org][Unit 3 --- Propositions and Proofs]]

View File

@@ -1,90 +0,0 @@
# Unit 3 — Propositions and Proofs
**Tutorial 1: Lean 4 Fundamentals** · [← Back to README](../README.md)
## Goals
- Understand propositions as types (Curry-Howard)
- Write basic proofs using `example` and `theorem`
- Use the tactic language: `intro`, `apply`, `exact`, `have`
## Source
*Theorem Proving in Lean 4* (TPIL), Chapters 23
→ https://leanprover.github.io/theorem_proving_in_lean4/
## Concepts
| Concept | Lean |
|---------|------|
| Proposition | `P : Prop` — a type whose terms are proofs |
| Implication `P → Q` | Function from proofs of `P` to proofs of `Q` |
| Conjunction `P ∧ Q` | `And.intro` (constructor), `.left` / `.right` (projections) |
| Disjunction `P Q` | `Or.inl` / `Or.inr` |
| Negation `¬ P` | `P → False` |
| Tactics | `intro`, `apply`, `exact`, `have`, `assumption` |
## Exercises
### Exercise 3.1 — Implicational logic
```lean
-- (a) Identity
theorem id_prop (A : Prop) : A A :=
by
intro h
exact h
-- (b) Composition
theorem compose (A B C : Prop) : (A B) (B C) (A C) :=
by
sorry
-- (c) Currying
theorem curry (A B C : Prop) : (A B C) (A B C) :=
by
sorry
```
### Exercise 3.2 — Conjunction and disjunction
```lean
-- (a) Swap conjuncts
theorem and_comm (A B : Prop) : A B B A :=
by
sorry
-- (b) Disjunction is symmetric
theorem or_comm (A B : Prop) : A B B A :=
by
sorry
-- (c) Forward reasoning with `have`
theorem forward_example (A B C : Prop) (h1 : A B) (h2 : B C) (ha : A) : C :=
by
have hb : B := h1 ha
sorry
```
### Exercise 3.3 — Negation
```lean
-- (a) Contradiction
theorem contrapositive (A B : Prop) : (A B) (¬ B ¬ A) :=
by
sorry
-- (b) Double negation introduction
theorem double_neg_intro (A : Prop) : A ¬ ¬ A :=
by
sorry
-- (c) Ex falso quodlibet
theorem ex_falso (A : Prop) : False A :=
by
sorry
```
---
← [Previous: Unit 2](02-inductive-types.md) · Next: [Unit 4 — Quantifiers and Equality](04-quantifiers-and-equality.md)

View File

@@ -0,0 +1,106 @@
* Unit 3 --- Propositions and Proofs
:PROPERTIES:
:CUSTOM_ID: unit-3-propositions-and-proofs
:END:
*Tutorial 1: Lean 4 Fundamentals* · [[../README.org][← Back to README]]
** Goals
:PROPERTIES:
:CUSTOM_ID: goals
:END:
- Understand propositions as types (Curry-Howard)
- Write basic proofs using =example= and =theorem=
- Use the tactic language: =intro=, =apply=, =exact=, =have=
** Source
:PROPERTIES:
:CUSTOM_ID: source
:END:
/Theorem Proving in Lean 4/ (TPIL), Chapters 2--3
→ https://leanprover.github.io/theorem_proving_in_lean4/
** Concepts
:PROPERTIES:
:CUSTOM_ID: concepts
:END:
| Concept | Lean |
|---------------------+-------------------------------------------------------------|
| Proposition | =P : Prop= --- a type whose terms are proofs |
| Implication =P → Q= | Function from proofs of =P= to proofs of =Q= |
| Conjunction =P ∧ Q= | =And.intro= (constructor), =.left= / =.right= (projections) |
| Disjunction =P Q= | =Or.inl= / =Or.inr= |
| Negation =¬ P= | =P → False= |
| Tactics | =intro=, =apply=, =exact=, =have=, =assumption= |
** Exercises
:PROPERTIES:
:CUSTOM_ID: exercises
:END:
*** Exercise 3.1 --- Implicational logic
:PROPERTIES:
:CUSTOM_ID: exercise-3.1-implicational-logic
:END:
#+begin_src lean
-- (a) Identity
theorem id_prop (A : Prop) : A A :=
by
intro h
exact h
-- (b) Composition
theorem compose (A B C : Prop) : (A B) (B C) (A C) :=
by
sorry
-- (c) Currying
theorem curry (A B C : Prop) : (A B C) (A B C) :=
by
sorry
#+end_src
*** Exercise 3.2 --- Conjunction and disjunction
:PROPERTIES:
:CUSTOM_ID: exercise-3.2-conjunction-and-disjunction
:END:
#+begin_src lean
-- (a) Swap conjuncts
theorem and_comm (A B : Prop) : A B B A :=
by
sorry
-- (b) Disjunction is symmetric
theorem or_comm (A B : Prop) : A B B A :=
by
sorry
-- (c) Forward reasoning with `have`
theorem forward_example (A B C : Prop) (h1 : A B) (h2 : B C) (ha : A) : C :=
by
have hb : B := h1 ha
sorry
#+end_src
*** Exercise 3.3 --- Negation
:PROPERTIES:
:CUSTOM_ID: exercise-3.3-negation
:END:
#+begin_src lean
-- (a) Contradiction
theorem contrapositive (A B : Prop) : (A B) (¬ B ¬ A) :=
by
sorry
-- (b) Double negation introduction
theorem double_neg_intro (A : Prop) : A ¬ ¬ A :=
by
sorry
-- (c) Ex falso quodlibet
theorem ex_falso (A : Prop) : False A :=
by
sorry
#+end_src
--------------
← [[file:02-inductive-types.org][Previous: Unit 2]] · Next: [[file:04-quantifiers-and-equality.org][Unit 4 --- Quantifiers and Equality]]

View File

@@ -1,32 +1,44 @@
# Unit 4 Quantifiers and Equality * Unit 4 --- Quantifiers and Equality
:PROPERTIES:
:CUSTOM_ID: unit-4-quantifiers-and-equality
:END:
*Tutorial 1: Lean 4 Fundamentals* · [[../README.org][← Back to README]]
**Tutorial 1: Lean 4 Fundamentals** · [← Back to README](../README.md) ** Goals
:PROPERTIES:
## Goals :CUSTOM_ID: goals
:END:
- Use `∀` (forall) and `∃` (exists) quantifiers - Use =∀= (forall) and =∃= (exists) quantifiers
- Manipulate equality with `rfl`, `rw`, `calc` - Manipulate equality with =rfl=, =rw=, =calc=
- Combine quantifiers with logical connectives - Combine quantifiers with logical connectives
## Source ** Source
:PROPERTIES:
*Theorem Proving in Lean 4* (TPIL), Chapter 4 :CUSTOM_ID: source
:END:
/Theorem Proving in Lean 4/ (TPIL), Chapter 4
→ https://leanprover.github.io/theorem_proving_in_lean4/ → https://leanprover.github.io/theorem_proving_in_lean4/
## Concepts ** Concepts
:PROPERTIES:
:CUSTOM_ID: concepts
:END:
| Concept | Lean | | Concept | Lean |
|---------|------| |------------------------+------------------------------------------------------|
| Universal `∀ x, P x` | `intro x` to prove; `h x` or `apply h` to use | | Universal =∀ x, P x= | =intro x= to prove; =h x= or =apply h= to use |
| Existential `∃ x, P x` | `⟨x, h⟩` to prove; `rcases h with ⟨x, hx⟩` to use | | Existential =∃ x, P x= | =⟨x, h⟩= to prove; =rcases h with ⟨x, hx⟩= to use |
| Equality `a = b` | `rfl` when definitional; `rw [h]` when propositional | | Equality =a = b= | =rfl= when definitional; =rw [h]= when propositional |
| `calc` block | Chain equalities: `calc a = b := h1; _ = c := h2` | | =calc= block | Chain equalities: =calc a = b := h1; _ = c := h2= |
## Exercises ** Exercises
:PROPERTIES:
### Exercise 4.1 — Universal quantifier :CUSTOM_ID: exercises
:END:
```lean *** Exercise 4.1 --- Universal quantifier
:PROPERTIES:
:CUSTOM_ID: exercise-4.1-universal-quantifier
:END:
#+begin_src lean
-- (a) Prove a simple forall -- (a) Prove a simple forall
theorem all_imp (P Q : Nat → Prop) (h : ∀ n, P n → Q n) (x : Nat) (hp : P x) : Q x := theorem all_imp (P Q : Nat → Prop) (h : ∀ n, P n → Q n) (x : Nat) (hp : P x) : Q x :=
by by
@@ -46,11 +58,13 @@ def Even (n : Nat) : Prop := ∃ k, n = 2 * k
theorem all_even_implies_42 : (∀ n, Even n) → Even 42 := theorem all_even_implies_42 : (∀ n, Even n) → Even 42 :=
by by
sorry sorry
``` #+end_src
### Exercise 4.2 Existential quantifier *** Exercise 4.2 --- Existential quantifier
:PROPERTIES:
```lean :CUSTOM_ID: exercise-4.2-existential-quantifier
:END:
#+begin_src lean
-- (a) Prove existence -- (a) Prove existence
theorem exists_square (a : Nat) : ∃ n, n = a * a := theorem exists_square (a : Nat) : ∃ n, n = a * a :=
by by
@@ -67,11 +81,13 @@ theorem exists_or_distrib (P Q : Nat → Prop) : (∃ n, P n Q n) ↔ (∃ n
theorem even_and_gt10_implies_gt5 : (∃ n, Even n ∧ n > 10) → (∃ n, n > 5) := theorem even_and_gt10_implies_gt5 : (∃ n, Even n ∧ n > 10) → (∃ n, n > 5) :=
by by
sorry sorry
``` #+end_src
### Exercise 4.3 Equality and rewriting *** Exercise 4.3 --- Equality and rewriting
:PROPERTIES:
```lean :CUSTOM_ID: exercise-4.3-equality-and-rewriting
:END:
#+begin_src lean
-- (a) Prove symmetry and transitivity of equality (without using `symm`/`trans`) -- (a) Prove symmetry and transitivity of equality (without using `symm`/`trans`)
theorem eq_symm {α : Type} (a b : α) (h : a = b) : b = a := theorem eq_symm {α : Type} (a b : α) (h : a = b) : b = a :=
by by
@@ -90,8 +106,8 @@ theorem calc_example (a b c d : Nat) (h1 : a = b) (h2 : b = c + 1) (h3 : c + 1 =
theorem rewrite_example (a b : Nat) (h : a = b + 1) : a * 2 = (b + 1) * 2 := theorem rewrite_example (a b : Nat) (h : a = b + 1) : a * 2 = (b + 1) * 2 :=
by by
sorry sorry
``` #+end_src
--- --------------
← [Previous: Unit 3](03-propositions-and-proofs.md) · Next: [Unit 5 — Advanced Tactics](05-advanced-tactics.md) ← [[file:03-propositions-and-proofs.org][Previous: Unit 3]] · Next: [[file:05-advanced-tactics.org][Unit 5 --- Advanced Tactics]]

View File

@@ -1,52 +0,0 @@
# Unit 5 — Advanced Tactics
**Tutorial 1: Lean 4 Fundamentals** · [← Back to README](../README.md)
## Goals
- Prove properties by induction with `induction`
- Use `simp`, `ring`, `omega` for automation
- Use `rcases` and `obtain` for case analysis
- Work with `Nat` arithmetic proofs
## Sources
- TPIL Chapters 56 → https://leanprover.github.io/theorem_proving_in_lean4/
- *Mathematics in Lean* (MiL), Chapter 1 → https://leanprover-community.github.io/mathematics_in_lean/
## Exercises
```lean
open Nat
-- 5.1 — Induction on naturals
theorem add_assoc (a b c : Nat) : (a + b) + c = a + (b + c) := by
sorry
theorem add_comm (a b : Nat) : a + b = b + a := by
sorry
theorem mul_comm (a b : Nat) : a * b = b * a := by
sorry
theorem zero_mul (n : Nat) : 0 * n = 0 := by
sorry
-- 5.2 — Induction on lists
theorem reverse_reverse (xs : List α) : xs.reverse.reverse = xs := by
sorry
theorem length_append (xs ys : List α) : (xs ++ ys).length = xs.length + ys.length := by
sorry
theorem map_id (xs : List α) : xs.map id = xs := by
sorry
-- 5.3 — Using `simp` and `ring`
theorem square_sum (a b : Nat) : (a + b) ^ 2 = a ^ 2 + 2 * a * b + b ^ 2 := by
sorry
```
---
← [Previous: Unit 4](04-quantifiers-and-equality.md) · Next: [Unit 6 — Structures and Type Classes](06-structures-type-classes.md)

View File

@@ -0,0 +1,60 @@
* Unit 5 --- Advanced Tactics
:PROPERTIES:
:CUSTOM_ID: unit-5-advanced-tactics
:END:
*Tutorial 1: Lean 4 Fundamentals* · [[../README.org][← Back to README]]
** Goals
:PROPERTIES:
:CUSTOM_ID: goals
:END:
- Prove properties by induction with =induction=
- Use =simp=, =ring=, =omega= for automation
- Use =rcases= and =obtain= for case analysis
- Work with =Nat= arithmetic proofs
** Sources
:PROPERTIES:
:CUSTOM_ID: sources
:END:
- TPIL Chapters 5--6 → https://leanprover.github.io/theorem_proving_in_lean4/
- /Mathematics in Lean/ (MiL), Chapter 1 → https://leanprover-community.github.io/mathematics_in_lean/
** Exercises
:PROPERTIES:
:CUSTOM_ID: exercises
:END:
#+begin_src lean
open Nat
-- 5.1 — Induction on naturals
theorem add_assoc (a b c : Nat) : (a + b) + c = a + (b + c) := by
sorry
theorem add_comm (a b : Nat) : a + b = b + a := by
sorry
theorem mul_comm (a b : Nat) : a * b = b * a := by
sorry
theorem zero_mul (n : Nat) : 0 * n = 0 := by
sorry
-- 5.2 — Induction on lists
theorem reverse_reverse (xs : List α) : xs.reverse.reverse = xs := by
sorry
theorem length_append (xs ys : List α) : (xs ++ ys).length = xs.length + ys.length := by
sorry
theorem map_id (xs : List α) : xs.map id = xs := by
sorry
-- 5.3 — Using `simp` and `ring`
theorem square_sum (a b : Nat) : (a + b) ^ 2 = a ^ 2 + 2 * a * b + b ^ 2 := by
sorry
#+end_src
--------------
← [[file:04-quantifiers-and-equality.org][Previous: Unit 4]] · Next: [[file:06-structures-type-classes.org][Unit 6 --- Structures and Type Classes]]

View File

@@ -1,22 +1,30 @@
# Unit 6 Structures and Type Classes * Unit 6 --- Structures and Type Classes
:PROPERTIES:
:CUSTOM_ID: unit-6-structures-and-type-classes
:END:
*Tutorial 1: Lean 4 Fundamentals* · [[../README.org][← Back to README]]
**Tutorial 1: Lean 4 Fundamentals** · [← Back to README](../README.md) ** Goals
:PROPERTIES:
## Goals :CUSTOM_ID: goals
:END:
- Define `structure` for records with named fields - Define =structure= for records with named fields
- Understand type classes as structures + instance resolution - Understand type classes as structures + instance resolution
- Use `deriving` for `Repr`, `BEq`, `Inhabited` - Use =deriving= for =Repr=, =BEq=, =Inhabited=
- Write monadic code with `do` notation - Write monadic code with =do= notation
## Sources
** Sources
:PROPERTIES:
:CUSTOM_ID: sources
:END:
- TPIL Chapter 9 (Structures), Chapter 10 (Type Classes) - TPIL Chapter 9 (Structures), Chapter 10 (Type Classes)
- FPIL Chapters 35 (overloading, monads) - FPIL Chapters 3--5 (overloading, monads)
## Exercises ** Exercises
:PROPERTIES:
```lean :CUSTOM_ID: exercises
:END:
#+begin_src lean
-- 6.1 — Structures -- 6.1 — Structures
structure Point where structure Point where
x : Float x : Float
@@ -61,8 +69,8 @@ def compute (x y z : Nat) : Option Nat :=
#eval compute 10 2 3 -- expected: some 2 #eval compute 10 2 3 -- expected: some 2
#eval compute 10 0 3 -- expected: none #eval compute 10 0 3 -- expected: none
``` #+end_src
--- --------------
← [Previous: Unit 5](05-advanced-tactics.md) · Next: [Unit 7 — Dependent Types](07-dependent-types.md) ← [[file:05-advanced-tactics.org][Previous: Unit 5]] · Next: [[file:07-dependent-types.org][Unit 7 --- Dependent Types]]

View File

@@ -1,33 +1,43 @@
# Unit 7 Dependent Types * Unit 7 --- Dependent Types
:PROPERTIES:
**Tutorial 1: Lean 4 Fundamentals** · [← Back to README](../README.md) :CUSTOM_ID: unit-7-dependent-types
:END:
## Goals *Tutorial 1: Lean 4 Fundamentals* · [[../README.org][← Back to README]]
** Goals
:PROPERTIES:
:CUSTOM_ID: goals
:END:
- Understand types that depend on values - Understand types that depend on values
- Work with `Fin n` (numbers < n), `Vector α n` (fixed-length lists) - Work with =Fin n= (numbers < n), =Vector α n= (fixed-length lists)
- Write functions whose return type depends on input - Write functions whose return type depends on input
- See why dependent types matter for PL semantics - See why dependent types matter for PL semantics
## Sources ** Sources
:PROPERTIES:
:CUSTOM_ID: sources
:END:
- TPIL Chapter 2 "Dependent Type Theory" - TPIL Chapter 2 "Dependent Type Theory"
- FPIL Chapter 7 "Programming with Dependent Types" - FPIL Chapter 7 "Programming with Dependent Types"
- Henson 2025: "Beginner Resources for Formalizing Lambda Calculi" - Henson 2025: "Beginner Resources for Formalizing Lambda Calculi"
## Concepts ** Concepts
:PROPERTIES:
:CUSTOM_ID: concepts
:END:
| Concept | Lean | | Concept | Lean |
|---------|------| |---------------------------+-----------------------------------------------------|
| Pi type `(x : α) → β x` | Function where return type depends on argument | | Pi type =(x : α) → β x= | Function where return type depends on argument |
| Sigma type `Σ x : α, β x` | Dependent pair: value + property | | Sigma type =Σ x : α, β x= | Dependent pair: value + property |
| `Fin n` | Natural numbers `< n` | | =Fin n= | Natural numbers =< n= |
| `Vector α n` | Lists with length tracked in the type | | =Vector α n= | Lists with length tracked in the type |
| `h : a = b → ...` | Equality can rewrite types (substitution principle) | | =h : a = b → ...= | Equality can rewrite types (substitution principle) |
## Exercises ** Exercises
:PROPERTIES:
```lean :CUSTOM_ID: exercises
:END:
#+begin_src lean
-- 7.1 — Fin n -- 7.1 — Fin n
-- Define a safe nth function for lists that *cannot* fail at runtime -- Define a safe nth function for lists that *cannot* fail at runtime
def safeNth {α : Type} (xs : List α) (i : Fin xs.length) : α := def safeNth {α : Type} (xs : List α) (i : Fin xs.length) : α :=
@@ -70,8 +80,8 @@ inductive HasType : Expr → Ty → Prop where
theorem isZero_returns_bool (e : Expr) : HasType (Expr.isZero e) Ty.nat → HasType e Ty.nat := theorem isZero_returns_bool (e : Expr) : HasType (Expr.isZero e) Ty.nat → HasType e Ty.nat :=
by by
sorry sorry
``` #+end_src
--- --------------
← [Previous: Unit 6](06-structures-type-classes.md) · [← Tutorial 1 Index](./) · Next: [Tutorial 2 — Unit 8](../tutorial-02-semantics/08-syntax-representation.md) ← [[file:06-structures-type-classes.org][Previous: Unit 6]] · [[./][← Tutorial 1 Index]] · Next: [[../tutorial-02-semantics/08-syntax-representation.org][Tutorial 2 --- Unit 8]]

View File

@@ -1,28 +1,36 @@
# Unit 8 Representing Syntax * Unit 8 --- Representing Syntax
:PROPERTIES:
**Tutorial 2: PL Semantics in Lean** · [← Back to README](../README.md) :CUSTOM_ID: unit-8-representing-syntax
:END:
## Goals *Tutorial 2: PL Semantics in Lean* · [[../README.org][← Back to README]]
** Goals
:PROPERTIES:
:CUSTOM_ID: goals
:END:
- Encode lambda calculus terms as an inductive type - Encode lambda calculus terms as an inductive type
- Understand three binding representations: - Understand three binding representations:
1. **Named** (strings simple, but α-equiv isn't definitional) 1. *Named* (strings --- simple, but α-equiv isn't definitional)
2. **de Bruijn indices** (numbers α-equiv is free, shifting is painful) 2. *de Bruijn indices* (numbers --- α-equiv is free, shifting is painful)
3. **Locally nameless** (free vars named, bound vars indexed compromise) 3. *Locally nameless* (free vars named, bound vars indexed --- compromise)
We'll use de Bruijn indices (the "heavy lifter") for the rest of this tutorial, We'll use de Bruijn indices (the "heavy lifter") for the rest of this tutorial,
with locally nameless for comparison. with locally nameless for comparison.
## Sources ** Sources
:PROPERTIES:
- syndikos/lean4-stlc `Syntax.lean`: https://github.com/syndikos/lean4-stlc :CUSTOM_ID: sources
:END:
- syndikos/lean4-stlc =Syntax.lean=: https://github.com/syndikos/lean4-stlc
- Chris Henson 2025: https://chrishenson.net/posts/2025-05-10-formalized_lambda_calculus.html - Chris Henson 2025: https://chrishenson.net/posts/2025-05-10-formalized_lambda_calculus.html
- chenson2018/LeanScratch: https://github.com/chenson2018/LeanScratch - chenson2018/LeanScratch: https://github.com/chenson2018/LeanScratch
- Software Foundations Vol.2: https://softwarefoundations.cis.upenn.edu/ - Software Foundations Vol.2: https://softwarefoundations.cis.upenn.edu/
## Exercises ** Exercises
:PROPERTIES:
```lean :CUSTOM_ID: exercises
:END:
#+begin_src lean
-- 8.1 — Named representation -- 8.1 — Named representation
inductive NamedTerm where inductive NamedTerm where
| var (x : String) | var (x : String)
@@ -68,15 +76,17 @@ inductive LNTerm where
| lam (body : LNTerm) -- binder | lam (body : LNTerm) -- binder
| app (f arg : LNTerm) | app (f arg : LNTerm)
deriving Repr deriving Repr
``` #+end_src
### Key insight for PL semantics *** Key insight for PL semantics
:PROPERTIES:
When we encode **typing contexts** `Γ = x₁:τ₁, x₂:τ₂, ...`, de Bruijn indices :CUSTOM_ID: key-insight-for-pl-semantics
:END:
When we encode *typing contexts* =Γ = x₁:τ₁, x₂:τ₂, ...=, de Bruijn indices
give us "index into the context" for free. The last binding is index 0, the give us "index into the context" for free. The last binding is index 0, the
second-last is index 1, etc. This makes the typing rules elegant in Lean second-last is index 1, etc. This makes the typing rules elegant in Lean ---
no name-clash avoidance needed. no name-clash avoidance needed.
--- --------------
← [Tutorial 1 — Unit 7](../tutorial-01-basics/07-dependent-types.md) · Next: [Unit 9 — Substitution](09-substitution.md) ← [[../tutorial-01-basics/07-dependent-types.org][Tutorial 1 --- Unit 7]] · Next: [[file:09-substitution.org][Unit 9 --- Substitution]]

View File

@@ -1,22 +1,30 @@
# Unit 9 Substitution and α-Equivalence * Unit 9 --- Substitution and α-Equivalence
:PROPERTIES:
:CUSTOM_ID: unit-9-substitution-and-α-equivalence
:END:
*Tutorial 2: PL Semantics in Lean* · [[../README.org][← Back to README]]
**Tutorial 2: PL Semantics in Lean** · [← Back to README](../README.md) ** Goals
:PROPERTIES:
## Goals :CUSTOM_ID: goals
:END:
- Implement `subst` (substitution) for de Bruijn terms - Implement =subst= (substitution) for de Bruijn terms
- Implement `lift` (index shifting) the key operation that avoids capture - Implement =lift= (index shifting) --- the key operation that avoids capture
- Prove fundamental substitution lemmas - Prove fundamental substitution lemmas
## Sources ** Sources
:PROPERTIES:
- syndikos/lean4-stlc `Syntax.lean` and `Reduction.lean` :CUSTOM_ID: sources
:END:
- syndikos/lean4-stlc =Syntax.lean= and =Reduction.lean=
- chenson2018/LeanScratch: https://github.com/chenson2018/LeanScratch - chenson2018/LeanScratch: https://github.com/chenson2018/LeanScratch
- PLFA Part 2: https://plfa.github.io/ - PLFA Part 2: https://plfa.github.io/
## Exercises ** Exercises
:PROPERTIES:
```lean :CUSTOM_ID: exercises
:END:
#+begin_src lean
open DBTerm -- from Unit 8 open DBTerm -- from Unit 8
-- 9.1 — Lift: shift all *free* variables above a cutoff by k -- 9.1 — Lift: shift all *free* variables above a cutoff by k
@@ -67,15 +75,17 @@ lemma subst_lift_commute (t s : DBTerm) (n : Nat) :
-- This lemma is *critical* for proving preservation/type safety later. -- This lemma is *critical* for proving preservation/type safety later.
-- It says that shifting before and after substitution agree. -- It says that shifting before and after substitution agree.
``` #+end_src
### Why this matters
*** Why this matters
:PROPERTIES:
:CUSTOM_ID: why-this-matters
:END:
Substitution is the core operation of operational semantics. Doing it right Substitution is the core operation of operational semantics. Doing it right
(no variable capture) is the hardest part of formalizing lambda calculi. (no variable capture) is the hardest part of formalizing lambda calculi.
de Bruijn indices make capture impossible the arithmetic is mechanical. de Bruijn indices make capture impossible --- the arithmetic is mechanical.
The lemmas here are boilerplate you prove once, then reuse everywhere. The lemmas here are boilerplate you prove once, then reuse everywhere.
--- --------------
← [Previous: Unit 8](08-syntax-representation.md) · Next: [Unit 10 — Small-Step Semantics](10-small-step-semantics.md) ← [[file:08-syntax-representation.org][Previous: Unit 8]] · Next: [[file:10-small-step-semantics.org][Unit 10 --- Small-Step Semantics]]

View File

@@ -1,22 +1,30 @@
# Unit 10 Small-Step Operational Semantics * Unit 10 --- Small-Step Operational Semantics
:PROPERTIES:
:CUSTOM_ID: unit-10-small-step-operational-semantics
:END:
*Tutorial 2: PL Semantics in Lean* · [[../README.org][← Back to README]]
**Tutorial 2: PL Semantics in Lean** · [← Back to README](../README.md) ** Goals
:PROPERTIES:
:CUSTOM_ID: goals
:END:
- Define single-step reduction =→= for call-by-value λ-calculus
- Define reflexive-transitive closure =→*=
- Prove determinism: =t → t₁ ∧ t → t₂ ⇒ t₁ = t₂=
## Goals ** Sources
:PROPERTIES:
- Define single-step reduction `→` for call-by-value λ-calculus :CUSTOM_ID: sources
- Define reflexive-transitive closure `→*` :END:
- Prove determinism: `t → t₁ ∧ t → t₂ ⇒ t₁ = t₂` - syndikos/lean4-stlc =Reduction.lean=, =Semantics.lean=
## Sources
- syndikos/lean4-stlc `Reduction.lean`, `Semantics.lean`
- Software Foundations Vol.2 "Smallstep" - Software Foundations Vol.2 "Smallstep"
- PLFA Part 2 - PLFA Part 2
## Exercises ** Exercises
:PROPERTIES:
```lean :CUSTOM_ID: exercises
:END:
#+begin_src lean
open DBTerm open DBTerm
-- 10.1 — Single-step cbv reduction -- 10.1 — Single-step cbv reduction
@@ -62,4 +70,4 @@ def stuckExample : DBTerm :=
app (var 0) (var 1) -- a free variable applied to another free variable app (var 0) (var 1) -- a free variable applied to another free variable
-- Show it's stuck (you'll prove something similar in Unit 12 with types) -- Show it's stuck (you'll prove something similar in Unit 12 with types)
``` #+end_src

View File

@@ -1,22 +1,30 @@
# Unit 11 STLC Type System * Unit 11 --- STLC Type System
:PROPERTIES:
:CUSTOM_ID: unit-11-stlc-type-system
:END:
*Tutorial 2: PL Semantics in Lean* · [[../README.org][← Back to README]]
**Tutorial 2: PL Semantics in Lean** · [← Back to README](../README.md) ** Goals
:PROPERTIES:
:CUSTOM_ID: goals
:END:
- Define simple types (=Nat → Bool=, etc.)
- Define typing contexts =Γ= as lists of types
- Encode the STLC typing judgment =Γ ⊢ t : τ=
## Goals ** Sources
:PROPERTIES:
- Define simple types (`Nat → Bool`, etc.) :CUSTOM_ID: sources
- Define typing contexts `Γ` as lists of types :END:
- Encode the STLC typing judgment `Γ ⊢ t : τ` - syndikos/lean4-stlc =Typing.lean=
## Sources
- syndikos/lean4-stlc `Typing.lean`
- Software Foundations Vol.2 "Types" - Software Foundations Vol.2 "Types"
- sdemos/type-inference for type inference perspective - sdemos/type-inference for type inference perspective
## Exercises ** Exercises
:PROPERTIES:
```lean :CUSTOM_ID: exercises
:END:
#+begin_src lean
open DBTerm open DBTerm
-- 11.1 — Types -- 11.1 — Types
@@ -75,4 +83,4 @@ theorem weakening (Γ Δ : Ctx) (t : DBTerm) (τ : Ty)
(h : HasType Γ t τ) (hsub : ∀ i, lookup Γ i = lookup (Δ ++ Γ) i) : HasType (Δ ++ Γ) t τ := (h : HasType Γ t τ) (hsub : ∀ i, lookup Γ i = lookup (Δ ++ Γ) i) : HasType (Δ ++ Γ) t τ :=
by by
sorry sorry
``` #+end_src

View File

@@ -1,22 +1,30 @@
# Unit 12 Type Safety (Progress + Preservation) * Unit 12 --- Type Safety (Progress + Preservation)
:PROPERTIES:
:CUSTOM_ID: unit-12-type-safety-progress-preservation
:END:
*Tutorial 2: PL Semantics in Lean* · [[../README.org][← Back to README]]
**Tutorial 2: PL Semantics in Lean** · [← Back to README](../README.md) ** Goals
:PROPERTIES:
:CUSTOM_ID: goals
:END:
- Prove *Progress*: well-typed terms are either values or can step
- Prove *Preservation* (Subject Reduction): types survive reduction
- Combine them: *Type Soundness* = well-typed programs don't get stuck
## Goals ** Sources
:PROPERTIES:
- Prove **Progress**: well-typed terms are either values or can step :CUSTOM_ID: sources
- Prove **Preservation** (Subject Reduction): types survive reduction :END:
- Combine them: **Type Soundness** = well-typed programs don't get stuck - syndikos/lean4-stlc =Metatheory.lean=
## Sources
- syndikos/lean4-stlc `Metatheory.lean`
- Software Foundations Vol.2 - Software Foundations Vol.2
- PLFA Part 2: DeBruijn chapter - PLFA Part 2: DeBruijn chapter
## Key Lemmas ** Key Lemmas
:PROPERTIES:
``` :CUSTOM_ID: key-lemmas
:END:
#+begin_example
Canonical Forms: Canonical Forms:
If [] ⊢ v : τ₁ ⇒ τ₂ and v is a value, then v = λ.t If [] ⊢ v : τ₁ ⇒ τ₂ and v is a value, then v = λ.t
@@ -28,11 +36,13 @@ Preservation:
Progress: Progress:
If [] ⊢ t : τ, then either Value t or ∃ t', t → t' If [] ⊢ t : τ, then either Value t or ∃ t', t → t'
``` #+end_example
## Exercises ** Exercises
:PROPERTIES:
```lean :CUSTOM_ID: exercises
:END:
#+begin_src lean
open DBTerm open DBTerm
open Step open Step
open HasType open HasType
@@ -101,4 +111,4 @@ theorem soundness {t : DBTerm} {τ : Ty} (h : HasType [] t τ) :
· exact hnotval hv · exact hnotval hv
· apply hnostep · apply hnostep
exact hstep exact hstep
``` #+end_src

View File

@@ -1,43 +1,56 @@
# Unit 13 Hindley-Milner Declarative Typing Rules * Unit 13 --- Hindley-Milner Declarative Typing Rules
:PROPERTIES:
:CUSTOM_ID: unit-13-hindley-milner-declarative-typing-rules
:END:
*Tutorial 2: PL Semantics in Lean* · [[../README.org][← Back to README]]
**Tutorial 2: PL Semantics in Lean** · [← Back to README](../README.md) ** Goals
:PROPERTIES:
## Goals :CUSTOM_ID: goals
:END:
- Extend STLC with **let-polymorphism** - Extend STLC with *let-polymorphism*
- Encode HM types with **type schemes** `∀α. τ` - Encode HM types with *type schemes* =∀α. τ=
- Formalize the 6 declarative typing rules (Var, App, Abs, Let, Inst, Gen) - Formalize the 6 declarative typing rules (Var, App, Abs, Let, Inst, Gen)
- Understand the distinction between monomorphic (`τ`) and polymorphic (`σ = ∀α.τ`) types - Understand the distinction between monomorphic (=τ=) and polymorphic (=σ = ∀α.τ=) types
## Sources ** Sources
:PROPERTIES:
:CUSTOM_ID: sources
:END:
- [[https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system][Wikipedia: Hindley-Milner type system]]
- [[https://www.jeffvaughan.net/docs/hmproof.pdf][Vaughan 2008]] (declarative rules, §2)
- [[https://github.com/sdemos/type-inference][sdemos/type-inference]] (Lean formalization)
- [Wikipedia: Hindley-Milner type system](https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system) ** Background
- [Vaughan 2008](https://www.jeffvaughan.net/docs/hmproof.pdf) (declarative rules, §2) :PROPERTIES:
- [sdemos/type-inference](https://github.com/sdemos/type-inference) (Lean formalization) :CUSTOM_ID: background
:END:
HM adds *let-polymorphism* to STLC:
## Background #+begin_example
HM adds **let-polymorphism** to STLC:
```
let x = e₁ in e₂ let x = e₁ in e₂
``` #+end_example
In STLC, `x` would have a single monomorphic type. In HM, `x` gets a type
*scheme* — e.g., `∀α. αα` for the identity function — and each use of `x` In STLC, =x= would have a single monomorphic type. In HM, =x= gets a type
/scheme/ --- e.g., =∀α. αα= for the identity function --- and each use of =x=
instantiates the scheme with fresh type variables. instantiates the scheme with fresh type variables.
The declarative rules: The declarative rules:
```
#+begin_example
Var: Γ, x:σ ⊢ x : σ Var: Γ, x:σ ⊢ x : σ
App: Γ ⊢ e₁ : τ₁ → τ₂ Γ ⊢ e₂ : τ₁ ⇛ Γ ⊢ e₁ e₂ : τ₂ App: Γ ⊢ e₁ : τ₁ → τ₂ Γ ⊢ e₂ : τ₁ ⇛ Γ ⊢ e₁ e₂ : τ₂
Abs: Γ, x:τ₁ ⊢ e : τ₂ ⇛ Γ ⊢ λx.e : τ₁ → τ₂ Abs: Γ, x:τ₁ ⊢ e : τ₂ ⇛ Γ ⊢ λx.e : τ₁ → τ₂
Let: Γ ⊢ e₁ : σ Γ, x:σ ⊢ e₂ : τ ⇛ Γ ⊢ let x = e₁ in e₂ : τ Let: Γ ⊢ e₁ : σ Γ, x:σ ⊢ e₂ : τ ⇛ Γ ⊢ let x = e₁ in e₂ : τ
Inst: Γ ⊢ e : ∀α.τ ⇛ Γ ⊢ e : τ[α := τ'] Inst: Γ ⊢ e : ∀α.τ ⇛ Γ ⊢ e : τ[α := τ']
Gen: Γ ⊢ e : τ ∧ α ∉ ftv(Γ) ⇛ Γ ⊢ e : ∀α.τ Gen: Γ ⊢ e : τ ∧ α ∉ ftv(Γ) ⇛ Γ ⊢ e : ∀α.τ
``` #+end_example
## Exercises ** Exercises
:PROPERTIES:
```lean :CUSTOM_ID: exercises
:END:
#+begin_src lean
-- 13.1 — Types and type schemes -- 13.1 — Types and type schemes
inductive MonoType where inductive MonoType where
| tvar (id : Nat) -- type variable α | tvar (id : Nat) -- type variable α
@@ -112,8 +125,8 @@ theorem self_app_id_typed (τ : MonoType) :
HMTyping [] self_app_id {vars := [], body := τ ⇒ τ} := HMTyping [] self_app_id {vars := [], body := τ ⇒ τ} :=
by by
sorry sorry
``` #+end_src
--- --------------
← [Previous: Unit 12](12-type-safety.md) · Next: [Unit 14 — Algorithm W](14-algorithm-w.md) ← [[file:12-type-safety.org][Previous: Unit 12]] · Next: [[file:14-algorithm-w.org][Unit 14 --- Algorithm W]]

View File

@@ -1,39 +1,49 @@
# Unit 14 Algorithm W (Hindley-Milner Type Inference) * Unit 14 --- Algorithm W (Hindley-Milner Type Inference)
:PROPERTIES:
**Tutorial 2: PL Semantics in Lean** · [← Back to README](../README.md) :CUSTOM_ID: unit-14-algorithm-w-hindley-milner-type-inference
:END:
## Goals *Tutorial 2: PL Semantics in Lean* · [[../README.org][← Back to README]]
** Goals
:PROPERTIES:
:CUSTOM_ID: goals
:END:
- Understand type inference as solving unification constraints - Understand type inference as solving unification constraints
- Implement **Algorithm W**: the classic HM inference algorithm - Implement *Algorithm W*: the classic HM inference algorithm
- Write `unify` (Robinson's unification) - Write =unify= (Robinson's unification)
- Write `infer` (the main inference loop) - Write =infer= (the main inference loop)
## Sources ** Sources
:PROPERTIES:
- [Vaughan 2008, §3](https://www.jeffvaughan.net/docs/hmproof.pdf) :CUSTOM_ID: sources
- [sdemos/type-inference](https://github.com/sdemos/type-inference) :END:
- [Wikipedia: Algorithm W](https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system#Algorithm_W) - [[https://www.jeffvaughan.net/docs/hmproof.pdf][Vaughan 2008, §3]]
- [[https://github.com/sdemos/type-inference][sdemos/type-inference]]
## Background - [[https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system#Algorithm_W][Wikipedia: Algorithm W]]
** Background
:PROPERTIES:
:CUSTOM_ID: background
:END:
Algorithm W takes an expression and returns a substitution + type: Algorithm W takes an expression and returns a substitution + type:
``` #+begin_example
infer(Γ, e) = (S, τ) infer(Γ, e) = (S, τ)
``` #+end_example
- `Γ` maps variables to type schemes - =Γ= maps variables to type schemes
- `e` is the expression to type - =e= is the expression to type
- `S` is a type substitution (unifies constraints found during inference) - =S= is a type substitution (unifies constraints found during inference)
- `τ` is the inferred monotype - =τ= is the inferred monotype
The algorithm uses a supply of *fresh type variables* to build constraints, The algorithm uses a supply of /fresh type variables/ to build constraints,
then unifies them. then unifies them.
## Exercises ** Exercises
:PROPERTIES:
```lean :CUSTOM_ID: exercises
:END:
#+begin_src lean
open MonoType open MonoType
open HMExpr open HMExpr
open TypeScheme open TypeScheme
@@ -149,8 +159,8 @@ def infer_id : Option (Subst × MonoType × Nat) :=
-- 14.7 — Exercise: infer the type of let x = λy. y in x x -- 14.7 — Exercise: infer the type of let x = λy. y in x x
def infer_self_app : Option (Subst × MonoType × Nat) := def infer_self_app : Option (Subst × MonoType × Nat) :=
inferW [] self_app_id 0 inferW [] self_app_id 0
``` #+end_src
--- --------------
← [Previous: Unit 13](13-hm-declarative.md) · Next: [Unit 15 — Soundness and Completeness](15-soundness-completeness.md) ← [[file:13-hm-declarative.org][Previous: Unit 13]] · Next: [[file:15-soundness-completeness.org][Unit 15 --- Soundness and Completeness]]

View File

@@ -1,28 +1,38 @@
# Unit 15 Soundness and Completeness of Algorithm W * Unit 15 --- Soundness and Completeness of Algorithm W
:PROPERTIES:
:CUSTOM_ID: unit-15-soundness-and-completeness-of-algorithm-w
:END:
*Tutorial 2: PL Semantics in Lean* · [[../README.org][← Back to README]]
**Tutorial 2: PL Semantics in Lean** · [← Back to README](../README.md) ** Goals
:PROPERTIES:
## Goals :CUSTOM_ID: goals
:END:
- Prove that Algorithm W is **sound**: every inferred type is derivable in the declarative system - Prove that Algorithm W is *sound*: every inferred type is derivable in the declarative system
- Prove that Algorithm W is **complete**: every derivable type can be inferred (up to generalization) - Prove that Algorithm W is *complete*: every derivable type can be inferred (up to generalization)
- Understand the relationship between inference and declarative rules - Understand the relationship between inference and declarative rules
## Sources ** Sources
:PROPERTIES:
:CUSTOM_ID: sources
:END:
- [[https://www.jeffvaughan.net/docs/hmproof.pdf][Vaughan 2008, §4]]
- [[https://github.com/sdemos/type-inference][sdemos/type-inference]] =Soundness.lean=, =Completeness.lean=
- [Vaughan 2008, §4](https://www.jeffvaughan.net/docs/hmproof.pdf) ** The Theorems
- [sdemos/type-inference](https://github.com/sdemos/type-inference) `Soundness.lean`, `Completeness.lean` :PROPERTIES:
:CUSTOM_ID: the-theorems
:END:
*Soundness*: If =infer(Γ, e) = (S, τ)=, then =Γ ⊢ e : τ= declaratively.
## The Theorems *Completeness*: If =Γ ⊢ e : τ= declaratively, then there exists =S, τ'= such that
=infer(Γ, e) = (S, τ')= and =τ= is a substitution instance of =τ'= (i.e., W finds the /most general/ type).
**Soundness**: If `infer(Γ, e) = (S, τ)`, then `Γ ⊢ e : τ` declaratively. ** Exercises
:PROPERTIES:
**Completeness**: If `Γ ⊢ e : τ` declaratively, then there exists `S, τ'` such that :CUSTOM_ID: exercises
`infer(Γ, e) = (S, τ')` and `τ` is a substitution instance of `τ'` (i.e., W finds the *most general* type). :END:
#+begin_src lean
## Exercises
```lean
open HMTyping open HMTyping
open MonoType open MonoType
@@ -78,8 +88,8 @@ theorem principal_types (Γ : HMEnv) (e : HMExpr) (σ : TypeScheme)
(∃ S', applySubst S' τ_principal = σ.body) := (∃ S', applySubst S' τ_principal = σ.body) :=
by by
exact completeness_W Γ e σ h exact completeness_W Γ e σ h
``` #+end_src
--- --------------
← [Previous: Unit 14](14-algorithm-w.md) · [← Tutorial 2 Index](.) · [← Back to README](../README.md) ← [[file:14-algorithm-w.org][Previous: Unit 14]] · [[file:.][← Tutorial 2 Index]] · [[../README.org][← Back to README]]