2 The simply-typed lambda calculus λ-st
2.1 Syntax
2.2 Dynamic semantics
eval(
) =
if
2.3 Static semantics
To type λ-st, we define typing contexts mapping variables to types:
Exercise 8. Extend λ-st with a product type .
You will need a form for
constructing products and projections for getting the components out. Add the
necessary reduction and typing rules.
Exercise 9. Extend λ-st with a sum type . You will need two
injection forms
and
to create sums, and one
case analysis form to eliminate them,
. The case analysis form takes a step once
reduces to a sum value:
,
and similarly for
. Add the necessary reduction and typing
rules.
2.3.1 Type safety
Before we can prove type safety, we need to prove several standard lemmas.
We use the judgment with no context to mean that
types in an empty context:
.
Lemma (Replacement). If then
for some
. Furthermore, for
any other term
,
.
Proof. By induction on the structure of :
: Then trivially, with
=
.
: By inspection of the typing rules, we know that if
has a type, that type is
. By inversion, we know that
has type
as well. Then by the induction hypothesis,
has some type
, and for any
having type
,
. Then by rule [succ],
.
: The whole term has a type
only if there is some type
such that
and
. Then by the induction hypothesis,
, and for any term
having type
,
. Then
.
: The whole term has a type
only if there is some type
such that
and
. Then by the induction hypothesis,
, and for any term
having type
,
. Then
.
Lemma (Substitution). If and
then
.
Proof. By induction on the type derivation for :
: If
=
then
=
, and
=
, which has type
. If
≠
, then
=
, which must type in
.
: This types in an environment.
: Then it must be the case that
. Then by induction,
, and reapplying rule [succ], we have that
.
cases are similar.
: This can be the case only if
. Without loss of generality,
≠
, so we can swap them, yielding
. Then by induction
. Then apply rule [abs], to get
.
Lemma (Preservation). If and
then
.
Proof. By cases on the reduction relation. There is one case:
. By the replacement lemma, we know that
. This only types if
and
. The former is only the case if
. Then by the substitution lemma,
, and by replacement,
.
QED.
Lemma (Canonical forms).
If then:
If
is
, then
is either
or or
for some
.
If
is
, then
is some lambda abstraction
.
Proof. By induction on the structure of the typing derivation. Only three rules form values, and those three rules correspond to the conditions of the lemma.
Lemma (Progress). If then either
is a
value or
for some
.
Proof. By induction on the structure of the typing derivation, considering the terms:
: Vacuous, open terms don’t type.
: A value.
: By induction,
steps or is a value of type
. If the former then the whole term steps; if the latter then the whole term is a value.
: By induction, each subterm steps or is a value. If the first subterm steps, then the whole term steps. If the first subterm is a value and the second steps, then the whole thing steps. If both are values, then by inversion of the [app] rule,
has a function type, and by the canonical forms lemma, that means it is a lambda abstraction
. Then the whole term steps to
.
: A value.
Theorem (Safety). 1) If and
then
. 2) If
then either
is a value or
for some
.
Exercise 10. Extend the type safety theorem to cover product and/or sum types.
2.4 An extension
pred =
add =
Exercise 11. Implement multiplication using the recursor.
Exercise 12. Implement factorial using the recursor.
Exercise 13. Implement a function that divides a natural number by two (rounding down).
Exercise 14. Extend the type safety theorem for the recursor.
Exercise 15. The recursor is currently call-by-name, in the sense that it
substitutes the whole recursive expression of
for
in the non-zero case.
The call-by-value form would compute the value of that subterm first and
then subtitute the value, but making it call-by-value
requires introducing an additional form.
will do.
(Why can’t we just use λ?) Show
how to add
to λ-st and how that can be used to make the
recursor call-by-value.
2.5 Normalization
A normal form is a form that doesn’t reduce any further, which for our purposes
(since we have eliminated stuck states) is a value. A term
normalizes, written
if it reduces to a normal form, that is,
a value.
Historically, when working with lambda calculi that allow free conversion (that is, redexes can by identified anywhere in a term, without a notion of evaluation contexts) authors have distinguished weak from strong normalization. A term weakly normalizes if it has some reduction sequence reaching a normal form; a term strongly normalizes if every of its reduction sequences reaches a normal form. However, we’ve defined our language to be deterministic, which causes weak and strong normalization to coincide.
We wish to show that all terms that have a type reduce to a value.
It is insufficient to do induction on typing derivations.
(Shall we try it?) What we end up needing is a (unary)
relation on terms, indexed by types, and defined by induction on types,
of the form , as follows:
iff
and
.
iff
and
and for all
such that
,
.
Exercise 16. How would we extend for product and/or sum types?
Lemma (SN preserved by conversion).
Suppose that and
. Then:
implies
.
implies
.
Proof. By induction on :
: If
normalizes then
normalizes by the same sequence because
takes a step to
, which then normalizes. We know this because our formulation of λ-st is determistic, and there is no other way to reduce the term. (We could prove this but haven’t.) Since it has type
, we have
If
normalizes then it does so via
, so
normalizes as well and by preservation it has the same type, so
.
: If
then we know that
normalizes and when applied to a good term, that normalizes too. We need to show that
does that same, that is, that
implies that
for arbitrary term
. We know that
. Since
, we know that
. Since
is a subexpression of
, we can apply the induction hypothesis at that type, yielding
as desired.
If
then we know that
normalizes and when applied to a good term, that normalizes too. We need to know that
does the same, that is, that
implies that
for arbitrary term
. We know that
. Since
, we know that
. Then by induction,
.
QED.
Note that if a substitution satisfies a type environment, this means that it contains values that typed in the empty type environment, meaning they are closed. Thus, the order of substitution doesn’t matter, as no variable in the substitution will interfere with any other.
Now we can prove a lemma that if we apply a substitution to a term that types in an environment consistent with the substitution, then the substituted term types in the empty environment:
Lemma (Mass substitution). If
and
then
.
Proof. By induction on the length of . If empty, then
is
empty, and the substitution has no effect. Otherwise,
=
,
where
=
and
and
. Then by the
substitution lemma,
.
Then by induction,
.
But that is
.
Lemma (Every typed term is good). If
and
then
.
Proof. By induction on the typing derivation:
: Appling
to
gets us a
such that
.
: Since
=
, and
and
, we have that
.
: By inversion, we know that
. Then by induction, we have that
. By the definition of NT for
, we have that
types in the empty context and reduces to a natural number. Then
does as well.
: By inversion, we know that
and
. By induction, we know that
and
. The former means that for any
such that
, we have
. Let
be
. Then
.
: Without loss of generality, let
be fresh for
. So then that term equals
. We need to show that
. To show this, we need to show three things:
To show
. It suffices to show that
for some
such that
, by the mass substitution lemma. That is what we have.
To show
. This is clear, because it is a value.
To show that for any
such that
,
. By the definition of SN, we know that
for some value
. Then we can take an additional step,
. Because SN is preserved by backward conversion, it suffices to show that this term is SN for
.
By the lemma that SN is preserved by forward conversion, we know that
. So then we can say that
. Now consider inverting the judgment that
. From this, we know that
. Then applying the induction hypothesis, we have that
. This is what we sought to show.
QED.
Strong normalization follows as a corollary.
Exercise 17. Extend the normalization proof to cover products and/or sums.
Exercise 18. Show that λ-st with the recursor still enjoys normalization.
2.6 Adding nontermination
We can add unrestricted recursion to λ-st by adding a fixed-point operator.
We will also add an construct, which lets us discriminate between
zero and non-zero and extracts the predecessor from a natural. (This is
redundant with the recursor, but easier to use. The resulting language is
equivalent to the classic PCF.)
Exercise 19. Define addition, multiplication, and factorial using
and
. How does it compare to using the recursor?
Exercise 20. Extend type safety for .
Exercise 21. Where does the normalization proof break down if we add ?
Exercise 22. Implement a union-find in STLC with records and vectors.