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 : R
thenR = T→T'
for someT'
, withΓ, x:T ⊢ t:T'
. - If
Γ ⊢ t t' : R
, then there is some typeT
such thatΓ ⊢ t : T→R
andΓ ⊢ 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
t1
can take a step, then (E-App1) applies tot
- If
t2
can take a step, then (E-App2) applies tot
. - If both
t1
andt2
are values, then the inversion lemma tells ust1
takes 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):