V. My Proof that You Can't Show that a LISP Expression is Elegant


Synopsis

Discusses a LISP run showing why you can't prove that a LISP expression is elegant if the LISP complexity of the axioms is substantially less than the size of the expression that you're trying to prove is elegant. More precisely, we show that a formal axiomatic system of LISP complexity N cannot enable you to prove that any S-expression more than N + 356 characters in size is elegant.


Discussion

In Chapter III we saw how Gödel constructs an assertion that says that it itself is unprovable. In Chapter IV we saw how Turing can use any solution to the halting problem to construct a program that halts iff it doesn't. Now let's start to work with program-size complexity. Let's do some warm-up exercises using LISP complexity, just to get in a ``program-size'' mood.

Recall that the size of an S-expression is defined to be the number of characters needed to write it in standard form, i.e., with a single blank separating successive elements of each list.

So I'll measure the LISP complexity H(X) of an S-expression X by the size in characters |Y| of the smallest expression Y with value X. Given an S-expression X, I'll use X* to denote a minimal-size LISP expression for X, i.e., one with the property that its value is X and its size |X*| is the complexity H(X) of X.

And, as I said in Chapter I, we call a LISP expression elegant if it has the property that no smaller expression has the same value. Thus the size of an elegant expression is precisely equal to the complexity of its value.

Okay, here are two exercises for you to think about. The answers are at the end of this chapter.

First exercise. First of all, I'd like you to show that the complexity H((X Y)) of a pair (X Y) of objects is bounded by a constant c added to the sum H(X) + H(Y) of the individual complexities. In other words, try to see why

H((X Y)) ≤ H(X) + H(Y) + c

and how big c is.

Hint. If you are given elegant expressions for X and Y, how can you combine them into an expression for the pair (X Y)? And how will the sizes of these three expressions compare with each other? In other words, how many characters c do you need to add to stitch elegant expressions for X and Y together into an expression for the pair (X Y)?

Second exercise. For the second exercise, I'd like you to think about the complexity of an elegant LISP expression E. Can you show that its complexity is nearly equal to its size in characters? I.e., can you bound the absolute value of the difference between the size of E, |E|, and the complexity of E, H(E)?

Okay, if you can do these two warm-up exercises, I hope you begin to have some feeling for why elegant expressions are interesting. We can now go ahead and see why a formal axiomatic system A can't prove that a LISP expression E is elegant if E is substantially larger than the LISP implementation of the proof-checking algorithm for the formal axiomatic system A.

What's the proof-checking algorithm for A? Recall that it's defined in Chapter III to be a LISP function (valid-proof? X) that returns nil if X is not a valid proof and that returns the theorem that was demonstrated if X is a valid proof. And the idea of my proof is that I will construct an expression B (for Berry) that searches through all possible proofs X until X proves an assertion (is-elegant E) in which E's size is larger than B's size. Then B returns E's value as B's value, which, if it actually happened, would contradict the definition of elegance. Why? Because B is too small to produce E's value because E is an elegant expression that's larger than B.

Okay, that's the idea. But to simplify matters, let's imagine that all possible proofs X are in a numbered list, so there's a first S-expression X, a second one, etc. And let's give the proof-checking algorithm valid-proof? the number for the proof X instead of giving it X directly. So in this chapter our formal axiomatic system A is implemented in LISP as a one-argument function (fas N) that returns nil if the Nth proof is invalid, and that returns the theorem that was demonstrated if the Nth proof is valid. Let's also allow the formal axiomatic system to give up and stop running by returning ``stop'', which means that there are no more valid proofs. I.e., there are no valid proofs for larger N. Okay?

So now we can think of our formal axiomatic system abstractly as a numbered list of theorems, that may either be finite or infinite, and in which there may be blanks, i.e., places in the list with no theorem. And we'll just look at (fas 1), (fas 2), etc. searching for a theorem of the form (is-elegant E) in which E is larger than the size of the LISP expression B that is doing the search. If B finds such an elegant expression E, then B stops searching and returns the value of E. (Of course, this should never happen, not if E is really elegant!).

So here is the Berry paradox expression B that does this:

define expression
       let (fas n) if = n 1 '(is-elegant x)
                   if = n 2  nil
                   if = n 3 '(is-elegant yyy)
                   [else]    stop
 
       let (loop n)
           let theorem [be] display (fas n)
           if = nil theorem [then] (loop + n 1)
           if = stop theorem [then] fas-has-stopped
           if = is-elegant car theorem
              if > display size cadr theorem 
                   display + 356 size fas
                 [return] eval cadr theorem
              [else] (loop + n 1)
           [else] (loop + n 1)
 
       (loop 1)
And I've put a simple formal axiomatic system in it, one that ``proves'' that x and yyy are elegant, and then stops. The constant 356 that enables B to know its own size was inserted in B by hand, because it turns out that B is exactly 356 characters larger than the lambda expression for the one-argument function fas. I.e., the size of B is exactly 356 more than the complexity of our formal axiomatic system. You can easily check that 356 is correct. Because as B loops through (fas 1), (fas 2), etc., it displays each theorem that it finds, and if the theorem is of the form (is-elegant E), B also displays the size of E and the size of B. So you frequently get to see what B thinks its own size is. After displaying these two numbers, B compares them. If the size of E is less than or equal to the size of B, then B keeps looping. Otherwise, B evaluates E and returns that value as its own.

Note that the way you do a loop in LISP is by having a function (loop N) which takes care of the Nth iteration of the loop. So during the Nth go round, to continue looping you just call (loop + N 1), which starts the N+1st iteration of the loop.

Now we'll run the proof of my incompleteness theorem on each of four different formal axiomatic systems. In each case the drill is like this. First we (re)define ``expression'' to be the paradoxical Berry expression B. B contains a list of theorems given by fas of N. Then we size the expression B so that we can see if it knows its own size. Then we evaluate the expression B, i.e., we run my proof. B will loop through all the theorems, displaying them and examining those of the form (is-elegant E). And either B will eventually run out of theorems and stop, or it will find an elegant expression E larger than B, and will return the value of E.

So there are four runs to show how this works. In the first run, the expressions that are proved to be elegant are very small, much too small to matter.

In the second run, we use exponentiation to construct a large ``elegant'' expression E = 1000... that's a number that is exactly one character bigger than B. Of course, that's a lie, E's not really elegant! But B doesn't know that.

In the third run, we use exponentiation again, but this time to construct a large ``elegant'' expression E = 1000... that's exactly the same size as B. This is to show that B knows what it's doing. This time the elegant expression E is not large enough.

And in the fourth run, we have an ``elegant'' expression E = (− 1000... 1) with 600 0's. So B thinks that E's big enough, B evaluates E, and B returns 999... as B's value. (And this proves that E was not really elegant.)

So you see my proof in action four times. You actually see the machinery working!


My Proof in LISP

LISP Interpreter Run

[[[[[

 Show that a formal axiomatic system (fas) can only prove 
 that finitely many LISP expressions are elegant.  
 (An expression is elegant if no smaller expression has 
 the same value.)

 More precisely, show that a fas of LISP complexity N can't 
 prove that a LISP expression X is elegant if X's size is 
 greater than N + 356.

 (fas N) returns the theorem proved by the Nth proof 
 (Nth S-expression) in the fas, or nil if the proof is 
 invalid, or stop to stop everything.

]]]]]

[
 This expression searches for an elegant expression 
 that is larger than it is and returns the value of 
 that expression as its own value.
]

define expression  [Formal Axiomatic System #1]
       let (fas n) if = n 1 '(is-elegant x)
                   if = n 2  nil
                   if = n 3 '(is-elegant yyy)
                   [else]    stop 

       let (loop n)
           let theorem [be] display (fas n)
           if = nil theorem [then] (loop + n 1)
           if = stop theorem [then] fas-has-stopped
           if = is-elegant car theorem
              if > display size cadr theorem 
                   display + 356 size fas
                 [return] eval cadr theorem
              [else] (loop + n 1)
           [else] (loop + n 1)

       (loop 1)

define      expression
value       ((' (lambda (fas) ((' (lambda (loop) (loop 1))) ('
             (lambda (n) ((' (lambda (theorem) (if (= nil theo
            rem) (loop (+ n 1)) (if (= stop theorem) fas-has-s
            topped (if (= is-elegant (car theorem)) (if (> (di
            splay (size (car (cdr theorem)))) (display (+ 356 
            (size fas)))) (eval (car (cdr theorem))) (loop (+ 
            n 1))) (loop (+ n 1))))))) (display (fas n))))))))
             (' (lambda (n) (if (= n 1) (' (is-elegant x)) (if
             (= n 2) nil (if (= n 3) (' (is-elegant yyy)) stop
            ))))))


[Show that this expression knows its own size.]

size expression

expression  (size expression)
value       456

  
[
 Run #1.

 Here it doesn't find an elegant expression 
 larger than it is:
]

eval expression

expression  (eval expression)
display     (is-elegant x)
display     1
display     456
display     ()
display     (is-elegant yyy)
display     3
display     456
display     stop
value       fas-has-stopped


define expression  [Formal Axiomatic System #2]
       let (fas n) if = n 1 '(is-elegant x)
                   if = n 2  nil
                   if = n 3 '(is-elegant yyy)
                   if = n 4  cons is-elegant 
                             cons ^ 10 509     [<=====]
                                  nil
                   [else]    stop 

       let (loop n)
           let theorem [be] display (fas n)
           if = nil theorem [then] (loop + n 1)
           if = stop theorem [then] fas-has-stopped
           if = is-elegant car theorem
              if > display size cadr theorem 
                   display + 356 size fas
                 [return] eval cadr theorem
              [else] (loop + n 1)
           [else] (loop + n 1)

       (loop 1)

define      expression
value       ((' (lambda (fas) ((' (lambda (loop) (loop 1))) ('
             (lambda (n) ((' (lambda (theorem) (if (= nil theo
            rem) (loop (+ n 1)) (if (= stop theorem) fas-has-s
            topped (if (= is-elegant (car theorem)) (if (> (di
            splay (size (car (cdr theorem)))) (display (+ 356 
            (size fas)))) (eval (car (cdr theorem))) (loop (+ 
            n 1))) (loop (+ n 1))))))) (display (fas n))))))))
             (' (lambda (n) (if (= n 1) (' (is-elegant x)) (if
             (= n 2) nil (if (= n 3) (' (is-elegant yyy)) (if 
            (= n 4) (cons is-elegant (cons (^ 10 509) nil)) st
            op)))))))


[Show that this expression knows its own size.]

size expression

expression  (size expression)
value       509


[
 Run #2.

 Here it finds an elegant expression 
 exactly one character larger than it is: 
]

eval expression

expression  (eval expression)
display     (is-elegant x)
display     1
display     509
display     ()
display     (is-elegant yyy)
display     3
display     509
display     (is-elegant 10000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            0000000000000000000000)
display     510
display     509
value       10000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            0000000000


define expression  [Formal Axiomatic System #3]
       let (fas n) if = n 1 '(is-elegant x)
                   if = n 2  nil
                   if = n 3 '(is-elegant yyy)
                   if = n 4  cons is-elegant  
                             cons ^ 10 508     [<=====]
                                  nil
                   [else]    stop 

       let (loop n)
           let theorem [be] display (fas n)
           if = nil theorem [then] (loop + n 1)
           if = stop theorem [then] fas-has-stopped
           if = is-elegant car theorem
              if > display size cadr theorem  
                   display + 356 size fas
                 [return] eval cadr theorem
              [else] (loop + n 1)
           [else] (loop + n 1)

       (loop 1)

define      expression
value       ((' (lambda (fas) ((' (lambda (loop) (loop 1))) ('
             (lambda (n) ((' (lambda (theorem) (if (= nil theo
            rem) (loop (+ n 1)) (if (= stop theorem) fas-has-s
            topped (if (= is-elegant (car theorem)) (if (> (di
            splay (size (car (cdr theorem)))) (display (+ 356 
            (size fas)))) (eval (car (cdr theorem))) (loop (+ 
            n 1))) (loop (+ n 1))))))) (display (fas n))))))))
             (' (lambda (n) (if (= n 1) (' (is-elegant x)) (if
             (= n 2) nil (if (= n 3) (' (is-elegant yyy)) (if 
            (= n 4) (cons is-elegant (cons (^ 10 508) nil)) st
            op)))))))


[Show that this expression knows its own size.]

size expression

expression  (size expression)
value       509


[
 Run #3.

 Here it finds an elegant expression 
 exactly the same size as it is: 
]

eval expression

expression  (eval expression)
display     (is-elegant x)
display     1
display     509
display     ()
display     (is-elegant yyy)
display     3
display     509
display     (is-elegant 10000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            000000000000000000000)
display     509
display     509
display     stop
value       fas-has-stopped


define expression  [Formal Axiomatic System #4]
       let (fas n) if = n 1 '(is-elegant x)
                   if = n 2  nil
                   if = n 3 '(is-elegant yyy)
                   if = n 4  cons is-elegant 
                             cons cons "- 
                                  cons ^ 10 600  [<=====]
                                  cons 1 
                                       nil 
                                  nil
                   [else]    stop 

       let (loop n)
           let theorem [be] display (fas n)
           if = nil theorem [then] (loop + n 1)
           if = stop theorem [then] fas-has-stopped
           if = is-elegant car theorem
              if > display size cadr theorem 
                   display + 356 size fas
                 [return] eval cadr theorem
              [else] (loop + n 1)
           [else] (loop + n 1)

       (loop 1)

define      expression
value       ((' (lambda (fas) ((' (lambda (loop) (loop 1))) ('
             (lambda (n) ((' (lambda (theorem) (if (= nil theo
            rem) (loop (+ n 1)) (if (= stop theorem) fas-has-s
            topped (if (= is-elegant (car theorem)) (if (> (di
            splay (size (car (cdr theorem)))) (display (+ 356 
            (size fas)))) (eval (car (cdr theorem))) (loop (+ 
            n 1))) (loop (+ n 1))))))) (display (fas n))))))))
             (' (lambda (n) (if (= n 1) (' (is-elegant x)) (if
             (= n 2) nil (if (= n 3) (' (is-elegant yyy)) (if 
            (= n 4) (cons is-elegant (cons (cons - (cons (^ 10
             600) (cons 1 nil))) nil)) stop)))))))


[Show that this expression knows its own size.]

size expression

expression  (size expression)
value       538


[
 Run #4.

 Here it finds an elegant expression 
 much larger than it is, and evaluates it: 
]

eval expression

expression  (eval expression)
display     (is-elegant x)
display     1
display     538
display     ()
display     (is-elegant yyy)
display     3
display     538
display     (is-elegant (- 10000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            00000000000000000000000000000000000000000000000000
            0000000000000000 1))
display     607
display     538
value       99999999999999999999999999999999999999999999999999
            99999999999999999999999999999999999999999999999999
            99999999999999999999999999999999999999999999999999
            99999999999999999999999999999999999999999999999999
            99999999999999999999999999999999999999999999999999
            99999999999999999999999999999999999999999999999999
            99999999999999999999999999999999999999999999999999
            99999999999999999999999999999999999999999999999999
            99999999999999999999999999999999999999999999999999
            99999999999999999999999999999999999999999999999999
            99999999999999999999999999999999999999999999999999
            99999999999999999999999999999999999999999999999999

End of LISP Run

Elapsed time is 0 seconds.


Subadditivity of LISP complexity

Theorem:

H((X Y)) ≤ H(X) + H(Y) + 19

Proof: Consider this S-expression

(cons X* (cons Y* nil))

Here X* is an elegant expression for X, and Y* is an elegant expression for Y. The size of the above S-expression is H(X) + H(Y) + 19 and its value is the pair (X Y). Crucial point: in my LISP there are no side-effects! So the evaluations of X* and Y* cannot interfere with each other. Hence the values of X* and Y* in this expression are exactly the same as if they were evaluated stand-alone, i.e., separately.


What is the complexity of an elegant expression?

Consider an elegant LISP expression E. What's E's LISP program-size complexity H(E)? Well, it's almost the same as E's size |E|.

Proof: (' E) has value E, therefore H(E) ≤ |E| + 4. On the other hand, consider an elegant expression E* for E. By definition, the value of E* is E and |E*| = H(E). Then (eval E*) yields the value of E, so |(eval E*)| = 7 + H(E) ≥ |E|, and therefore H(E) ≥ |E| − 7. Thus |H(E) − |E|| ≤ 7.