Simply-Typed Lambda Calculus
Grammar
There are 4 categories of expressions for simply-typed lambda calculus: terms, values, types, and contexts. Values are terms that “cannot be evaluated any further”, they’re as “simple” as possible. Contexts are used for making typing judgments, assertions regarding the type of a term.
“Pure” simply-typed lambda calculus has no base types. That is, the only types allowed are function-types.
The syntax for simply-typed lambda calculus has the following structure:
t ::= -- terms:
x -- variable
λx:T.t -- abstraction
t t -- application
v ::= -- values:
λx:T.t -- abstraction values
T ::= -- types:
T→T -- type of functions
Γ ::= -- contexts:
∅ -- empty context
Γ, x:T -- term variable binding
Evaluation t ⟶ t'
I am endeavouring to use ⟶ for evaluation, and → for function types. Formally, it is a binary relation, and when we have “t ⟶ t’” we state “the evaluation statement (or judgment) t ⟶ t’ is derivable.” For simply-typed lambda calculus, it is the ‘smallest’ one which satisfies three properties.
The first two describe how application “commutes” with evaluation, specifically “on the left” (E-App1) and “on the right” (E-App2)
| t1 ⟶ t'1 | (E-App1) |
|---|---|
| t1 t2 ⟶ t'1 t2 |
| t2 ⟶ t'2 | (E-App2) |
|---|---|
| t1 t2 ⟶ t1 t'2 |
We also have the hallmark of lambda calculus, beta reduction. This tells us how to substitute a value for a bound variable in a lambda-abstraction. Note the value v2 must be of type T11 for this to work out, otherwise we cannot evaluate the expression.
| (λ x:T11 . t12) v2 ⟶ [x ↦ v2]t12 | (E-AppAbs) |
Typing Γ ⊢ t : T
Typing statements involve a ternary-relation, the typing relation,
which is written “infix” as _ ⊢ _ : _. The first slot is filled by a
typing context, the second by a term, and the last by a type.
Typing statements first force us to discuss the typing context. A typing context is a sequence of variables and their types, and the “comma” operator extends the context by “pushing” a new binding on the right. A variable appears at most once in a typing context.
We have the property: a variable has whatever type we are currently assuming it to have. Formally, if we write “x:T ∈ Γ” for “We are assuming x has type T in the current context Γ”, then this property is represented by the typing rule:
| x:T ∈ Γ | (T-Var) |
|---|---|
| Γ ⊢ x:T |
Any variable that occurs must either be bound by a lambda-abstraction,
or appear in the typing context. If it appears in the typing context x:T' ∈ Γ,
then it may appear in the term t judged in the typing relation Γ ⊢
t:T. That is to say, to be more explicit, we may have Γ ⊢ t(x):T
where we indicate the possible dependence of t on x explicitly “as
if” it were a function.
For example, if we assume b is a boolean, then not(b) is
also a boolean. But b is a free variable in not(b) — it’s okay,
however, since it is in the typing context Γ=b:boolean. From this we
may assemble a lambda-abstraction, moving the b:boolean from the
typing context to the variable bound in the lambda expression.
More generally, if our typing context is Γ, x:T1,
and we have t2:T2 hold in this context,
then we may assemble a lambda-abstraction over x.
| Γ, x:T1 ⊢ t2:T2 | (T-Abs) |
|---|---|
| Γ ⊢ (λx:T1.t2) : T1→T2 |
The opposite property holds, if we’re given a lambda abstraction of type T11 → T12 and we’re given a term of type T11, then application produces a term of type T12.
| Γ ⊢ t1:T11 → T12, Γ ⊢ t2:T11 | (T-App) |
|---|---|
| Γ ⊢ (t1 t2) : T12 |
Properties
Degeneracy. Pure simply-typed lambda calculus is “degenerate”, in the sense that it has no terms.
Inversion Lemma.
- If
Γ ⊢ x:T, thenx:T ∈ Γ - If
Γ ⊢ λx:T . t : RthenR = T→T'for someT', withΓ, x:T ⊢ t:T'. - If
Γ ⊢ t t' : R, then there is some typeTsuch thatΓ ⊢ t : T→RandΓ ⊢ t' : T.
Proof: Immediate from the definition of the typing relation. (End of Proof)
Progress Theorem.
Suppose t is a closed, well-typed term (i.e., we have ⊢ t : T for
some type T).
Then either t is a value, or there is some t' with t
⟶ t'.
(End of Theorem)
Proof. By induction typing derivations. We see (T-Var) cannot contribute to this, nor can (T-Abs) — both involve terms that cannot be closed.
We are left with (T-App) as the only case we need to consider, where
t = t1 t2
with ⊢ t1 : T11 → T12
and ⊢ t2 : T11.
The inductive hypothesis tells us either t1 is a
value, or t2 is a value (or both are values). We
must examine these cases each in turn.
- If
t1can take a step, then (E-App1) applies tot - If
t2can take a step, then (E-App2) applies tot. - If both
t1andt2are values, then the inversion lemma tells ust1takes the formλx:T11 . t12, hence (E-AppAbs) applies tot.
(End of Proof)
Preservation Theorem.
If Γ ⊢ t:T and t ⟶ t',
then Γ ⊢ t':T.
(End of Theorem)
Proof. Again, by induction on a derivation of Γ ⊢ t:T.
- Case (T-Var):
- Case (T-Abs):
- Case (T-App):