CIS6700-Spring2025/Homework 4.md

136 lines
4.1 KiB
Markdown

**Exercise 13.3.1**: I don't think you could model automatic garbage collection using single step semantics, given that it has no information about the outer evaluation context and whether a label will be used or not. We could write single step evaluation with an explicit context like this:
```
E ⩴ _ | t E | E v | !E | E := t | v := E | ref E
t | μ → t' | μ'
---------------------
E[t] | μ → E[t'] | μ'
```
and analyse for labels in `E`, but I think it would be cleaner to instead have an explicit freeing operator and error value:
```
t ⩴ ... | free t | error
┌───────────────┐
│ t | μ → t | μ │
└───────────────┘
t | μ → t' | μ'
-------------------------
free t | μ → free t' | μ'
--------------------------------
free l | μ → unit | μ[l ↦ error]
-----------------------
error t | μ → error | μ
-----------------------
v error | μ → error | μ
-------------------------
ref error | μ → error | μ
----------------------
!error | μ → error | μ
--------------------------
error := t | μ → error | μ
--------------------------
v := error | μ → error | μ
┌───────────────┐
│ Γ | Σ ⊢ t : T │
└───────────────┘
Γ | Σ ⊢ t : Ref T
---------------------
Γ | Σ ⊢ free t : Unit
-----------------
Γ | Σ ⊢ error : T
```
`free`ing updates the store with an `error` value , so the store still never shrinks. `error`s propagate upward, so if it's encountered anywhere inside a computation, the entire computation `error`s. The preservation theorem remains the same, but the progress theorem now says that either a well typed term evaluates to a value or it evaluates to `error` (if you don't consider `error` to be a value).
Unfortunately, the type system isn't strong enough to rule out usage after free (i.e. if a term is well typed then it never errors), and I'm not sure whether it would be possible to design a type system that does. Originally, I was thinking you could remove locations from the store typing, but then it's unclear which location should be removed when typing `free`, and even more unclear how to fix the preservation theorem.
_Theorem_ (preservation): If `Γ | Σ ⊢ μ`, `Γ | Σ ⊢ t : T`, `t | μ → t' | μ'`, then there exists `Σ'` such that `Γ | Σ' ⊢ μ'`, `Γ | Σ' ⊢ t' : T`, and `Σ ??? Σ'`.
We would want to allow, for instance, `t₁ := free (ref t₂)` where `t₁ ≠ t₂`, but not `t₁ := free t₁`, nor `(free t₁; t₁) := t₂`. All of these would shrink the store typing in some way, but it doesn't seem like there would be a way to combine the store typings from the two premises of typing assignment in a way that rules out the last two but not the first.
----
**Exercise 13.5.8**: First, suppose we had a sequencing operation `t₁; t₂`, which could be primitive, or just sugar for `(λ_. t₂) t₁` in our CBV language. Assuming the typing rules for the booleans and natural numbers from Chapter 8, as well as a `mult`iplication function, here is a factorial function:
```
(λn: Nat.
(λf: Ref (Nat → Nat).
λg: Ref (Nat → Nat).
f := λx: Nat.
if (iszero x)
then (succ 0)
else (mult x (!g (pred x)));
g := !f;
!g n)
(ref (λx: Nat. x))
(ref (λx: Nat. x)))
```
Given some concrete `n`, after evaluating the two initial references, this steps to the following:
```
lf ↦ λx: Nat. x
lg ↦ λx: Nat. x
lf := λx: Nat.
if (iszero x)
then (succ 0)
else (mult x (!lg (pred x)));
lg := !lf;
!lg n
```
After one step, we update `lf`:
```
lf ↦ λx: Nat.
if (iszero x)
then (succ 0)
else (mult x (!lg (pred x)))
lg ↦ λx: Nat. x
lg := !lf;
!lg n
```
After another step, we update `lg`:
```
lf ↦ λx: Nat.
if (iszero x)
then (succ 0)
else (mult x (!lg (pred x)))
lg ↦ λx: Nat.
if (iszero x)
then (succ 0)
else (mult x (!lg (pred x)))
!lg n
```
Then finally yield the factorial function we expect (dropping `lf` now that we no longer need it):
```
lg ↦ λx: Nat.
if (iszero x)
then (succ 0)
else (mult x (!lg (pred x)))
if (iszero n)
then (succ 0)
else (mult n (!lg (pred n)))
```