[Proof] λ→ is normalizing
by Sanjoy
I studied a proof today that I had been putting off for some time now; that a simply typed lambda calculus is normalizing -- every well-typed expression eventually reduces to a value. The proof is quite clever and that the exact wording of the proof in Types and Programming Languages is a bit terse so I think it will make for a good, juicy blog post.
In case you haven't already, you need to first read up (a little bit) on untyped and typed lambda calculus. Try reading to the point where you can comfortably state why
can not be well-typed. I'll wait right here, I promise. :)
I'll use the symbol
to mean "replace instances of
by
in the term
". We'll talk about a typed lambda calculus which has exactly one type
and only one value of that type,
. We'll evaluate in normal order.
Firstly, note (informally) that all types will look like
. It is not hard to see (or prove) that the set of types is isomorphic to a set of binary trees with every internal node a
and every leaf an
. This is important since we'll do structural induction on the binary tree corresponding to a type.
We now define a set of what are usually called reducibility candidates. They are a predicate on terms of the lambda calculus with the following conditions
if
halts.
halts and 
Since
is a predicate, we can safely say things like
is in
etc.
We aim to prove the following
- Every term in a set
(for any type
) is normalizable. Note that this follows from the definition of the reducibility candidates - Every term of type
is in
.
These two, combined, will allow us to draw the conclusion that every well-typed term in our simply typed lambda calculus halts.
Lemma 0: Every term in a reducibility candidate halts
This follows directly from the definition of a reducibility candidate.
Lemma 1: Reduction does not change the reducibility status of a term
Formally, we try to prove
. For this, we use the structural induction on binary trees isomorphic to each type we talked about above. There are two cases.
T is the atom type
This is the base case for our induction and also pretty obvious. From
we conclude
halts iff
halts. Since the only condition to be in
is halting,
.
T is a function type
Let
. In this case, each
has to satisfy the additional condition
. We begin by taking an arbitrary
in
.
Notice how
[1]? Also notice how
is a substructure of
? We can invoke structural induction here and say we already know
(statement 0). Also, since we're given
, we know for all
in
,
is in
(property of
) (statement 1). We can conclude from statement 0 and statement 1 that for any arbitrary
in
, we have
. This is the extra condition we needed to show
is in
.
Lemma 2: Every well typed term of type T is in
This is proved by proving a stronger assertion: if
and
for all
then
. This is a stronger assertion because this also applies to terms with free variables while, at the top level, we'll need to consider only closed terms. The assertion will be invoked on open terms only via induction.
To prove this assertion, we'll invoke induction on the size of a term. So, informally,
is greater than either
or
and
is greater than
. We make a case by case analysis on the various forms
can be in
A variable
This is obvious, since
for some
.
An application
This too is easy. Since
, we invoke induction on
and
separately and then use
to get our result.
An abstraction
We know, from its form that
is a value. The other thing left to prove is that, keeping types compatible,
.
is of the form
. Let
. We know, from lemma 0 that
will reduce to a value
. From lemma 1, we get
. The condition we're trying to prove is
. But this beta-reduces to
.
is a smaller term satisfying the requirements for this proposition, and we can say, via induction,
. From lemma 1 we get
, which is what we wanted to prove.
--
- In normal order. I haven't tried proving this in other evaluation strategies but I think I can go around by proving that the evaluation strategy does not matter in deciding the behaviour of a program in this lambda calculus.