Intuition on the Gödel Incompleteness Theorem via the Y combinator
|
|
In this note we will propose an informal analogy between Gödel's
incompleteness theorem and the Y combinator as a way of gaining
intuition into his approach.
|
|
Gödel devised a particularly
clever way of creating a self-referential formula in first
order logic. Newer presentations rely on diagonalization
arguments, but it is still instructive and illuminating
to delve into Gödel's original approach. It has renewed
relevance in view of developments in modern programming languages.
|
|
Gödel wanted to create a formula along the following lines:
|
|
"This formula has the property that neither it nor its negation has a proof."
|
|
There is no direct way in first order arithmetic to express
a notion of self-reference such as "this formula.."
|
|
Instead, Gödel came up with an "arithmetization" scheme,
in which formulas in first order logic (i.e., syntactically
well-formed finite sequences of symbols) could be mapped
to natural numbers. With this trick, it becomes possible
to reason within first-order arithmetic about these fancy
numbers, and thereby to engage in formal reasoning
about first-order formulas.
|
|
Consider the following two statements:
|
|
"There exists a formula with Gödel number M which possesses the property that
neither the formula nor its negation has a proof."
|
|
"Oh, by the way. The Gödel number of the above formula is M."
|
|
The first formula by itself might be false; there might be no such number.
|
|
However, in combination with the second statement, things get interesting.
If we were able to devise such a number "M", the formula would itself stand
as a witness to the existence of a formula with the property that it asserts.
So, we would be led to the conclusion that the formula is in fact true.
On the assumption that first order arithmetic is consistent (no falsehood
is provable), we have a formula that is true but not provable.
|
|
"M" in the above is an actual number. In the first statement, one has
an arithmetic expression (i.e., a sequence of symbols such as "3 + 4*5 + 12^100000 + ...")
that is short but that evaluates to a really large number.
|
|
After developing the idea of mapping formulas and proofs in first-order
logic to integers, Gödel needed to use his new tool to come up with
some way to express self reference. (The formula above has to have an
embedded arithmetic expression "M" that unwraps and evaluates to
the Gödel number of the entire formula.)
|
|
Gödel devised what we would today recognize as the Y combinator,
expressed in first order arithmetic.
|
|
The essential similarity of the key trick in Gödel's incompleteness
theorem and the Y combinator is a helpful way for those of us who are
familiar with functional programming, Lisp, JavaScript, Python,
etc. to gain intuition into the incompleteness result.
|
|
As an entry point, consider the standard lambda term with no normal form,
|
(lambda x. (x x)) (lambda x. (x x))
|
It is possible to make the syntax a little bit more verbose, and have an
expression that is legal python:
|
(lambda x: (x(x))) (lambda x: (x(x)))
|
Now consider Gödel's arithmetic expression
"Substitute(F, n)", which takes a number F, the Gödel number of a formula
with a single free variable, and another number n. It simplifies to a
number M which is the Gödel number of the formula F with n replacing all
instances of its free variable.
|
|
(Defining this function "Substitute" was itself a major undertaking.
One must code up a parser, implement something analogous to a symbol table,
develop list data structures and bidirectional mappings between
integers and lists of symbols, etc.)
|
|
One might interpret F (the first argument of "Substitute") as function-like,
in the sense that for any number
n, F [free_var := n] simplifies to some other number m.
|
|
Moreover, "Substitute(F, n)" acts like function application, taking a function
F and an argument n and returning F(n). This is analogous to beta reduction
in lambda calculus:
|
(lambda x. F(x)) (n) ⇒ F[x := n]
|
So now consider "Substitute(F, F)", which is suggestive of "(x x)"
in lambda notation.
|
|
Let M be the Gödel number of this formula, which has one free variable.
|
|
Finally, use an analogy to the above self-referential lambda term to
create the formula G, defined as "Substitute(M, M)".
|
|
To what number does this arithmetic formula with no free variables
simplify? The delightful answer is that it simplifies to its own Gödel
number!
|
|
"M" is the Gödel number of "Substitute(x,x)", a formula with one free
variable. If we substitute the number "M" for the two occurrences of
the free variable "x", we get precisely "Subsitute(M, M)", the Gödel
number of which is what is returned by the application of the
"Substitute" function.
|
|
If we wanted to imitate the divergent behavior of the original
formula in lambda calculus, we could do something like the following:
|
Given an integer M:
While possible:
Decode M into its corresponding arithmetic expression.
Simplify the expression to obtain an integer M'.
Repeat the process with this new integer M'.
|
Just as it is a short step from the above simple self-referential lambda
term to the Y combinator, so it is a short step from the above fact to the
standard Gödel formula for which neither it nor its negation has a proof.
|
|
So, the above connection may be helpful in
understanding the heart of Gödel's insight.
|
|
Here is the Y combinator.
The only change from the above lambda term with no
normal form is the introduction of a free variable "f".
|
(lambda x. f(x x)) (lambda x. f(x x))
|
(We have omitted the abstraction on "f" and left "f" as a free
variable for clarity. As above, it is easy to obfuscate the above
formula a little bit and come up with a valid executable python version.)
|
|
The crucial difference is that every time we apply "beta reduction" or
function application, we get the original term, but wrapped with "f":
|
f((lambda x. f(x x)) (lambda x. f(x x)))
|
We can repeat this process as many times as we like:
|
f(f(f(...f((lambda x. f(x x)) (lambda x. f(x x)))...)))
|
(This repeated unfolding is useful when using the Y combinator to work
with recursion, but it turns out to be unnecessary for Gödel's argument;
he just needed a single iteration to achieve his goal.)
|
|
Going back to our original goal, how might we construct the formula given
at the top of this note? How do we construct a numerical constant "M" that
makes the two assertions true?
|
|
We will abbreviate our hoped-for formula
|
|
"There exists a formula with Gödel number M which possesses the property that
neither the formula nor its negation has a proof"
|
f(M)
|
We start by replacing our placeholder "M" with a familiar looking
expression,
|
Substitute(x, x)
|
Here is the formula with that substitution.
|
|
"There exists a formula with Gödel number Substitute(x,x) which possesses the property that
neither the formula nor its negation has a proof."
|
|
The above formula has a single free variable, "x".
|
|
Using our abbreviation, we can concisely express the above as:
|
f((x x))
|
As a well-formed syntactically valid formula in first-order logic, the above
formula has a Gödel number; let's call its Gödel number "G".
|
|
Now, the coup de grace: We substitute the number G into our formula in
place of the free variable "x":
|
|
"There exists a formula with Gödel number Substitute(G,G) which possesses the
property that neither the formula nor its negation has a proof."
|
|
In terms of the abbreviated notation, this would become:
|
f(Substitute(f(x x), f(x x)))
^^^^^^ ^^^^^^
|
The highlighted sub-expressions above are instances of the Gödel number "G"
defined above.
|
Substitute(f(x x), f(x x)).
|
Using our analogy of "Substitute()" in first
order logic to beta-reduction in lambda calculus, this can be expressed as the clean-looking
lambda term:
|
(f(x x)) (f(x x)).
|
If we turn the crank
and perform the Substitute operation (or beta reduction), we get the
following term:
|
f(f(x x) f(x x))
|
The nested arithmetic expression has "unwrapped" to become exactly the Gödel
number of our original formula!
|
|
The number "G" is the Gödel number of a formula with a single free variable
"x"; we can substitute any number into this formula in place of "x" using
the Substitute function. In particular, it is completely reasonable to
do so with the number "G". The resulting substitution yields precisely
the Gödel number of our original formula.
|
|
So there we have it. We have used a version of the Y combinator expressed
in first order predicate logic that allows us to create an expression that
"unfolds" to the Gödel number of the formula that contains it as a
sub-expression.
|