Quantcast
Channel: keeping simple
Viewing all articles
Browse latest Browse all 195

A hard theorem becomes easy over time.

$
0
0

IMG_20140910_141117_570Can it really be this simple?

Suppose we have simple programming language where variables represent non-negative integers and where the range of integers represented is limited only by available memory. This language has the usual arithmetic operators and recursion.  We also need to have the ability to pass functions as parameters. If we define f by f(x){ x(2)}  then f(g) = g(2). A function passed as a parameter is just a number that might be a pointer to function code or  the code itself, it doesn’t matter here. Now suppose we put this language on a computer with an infinite memory so that the integer variables can represent arbitrary integers, no matter how large, and function execution  never “overflows the stack”. Functions written in this language and executed on this imaginary computer may get stuck in infinite loops or in computations that never succeed. For example, Forever(x){ if(x< x+1)then return Forever(x+1) else return 1} never terminates because the integers are an infinite set. A function Solve(f,n){ if( f(n) = 0)return n else return Solve(f,n+1) } will just keep trying larger and larger n’s forever if there is no solution for a particular f and initial n.  It would be convenient if we could define a function “Terminates” so that Terminates(f,x)=1 if f(x) terminates (returns a value ) and Terminates(f,x)=0 if f(x) gets stuck. Of course  Terminates itself should always return some value and never get stuck in a loop. But we can’t write Terminates and that’s easy to prove.  If we could write Terminates as specified we could define a function G(f){ return Terminates(f,f) } which just tests to see if f(f) terminates. Remember, functions are just numbers.  But we could also write a sneaky function like this:

Diagonal(f){ if( Terminates(f, f)=1) then return Forever(0) else return 1}

If Terminates(f,f) =1  then Diagonal(f) calls Forever(0) which never returns. If Terminates(f,f)=0 then Diagonal(f) returns 1. If Terminates does what it is supposed to do, Diagonal(f,f) terminates if and only if f(f) does not terminate. But Diagonal is itself a function so we can ask the system to evaluate Diagonal(Diagonal) and this leads to a paradox.  If Terminates(Diagonal,Diagonal)=1  then Diagonal(Diagonal) will call Forever(0) and will not terminate. That is, if Terminates tells us Diagonal(Diagonal) does terminate, then Diagonal(Diagonal) does not terminate.  The only way to resolve this paradox is to admit that Terminate cannot work as specified. And notice that this construction of Diagonal doesn’t use many complex language features – Diagonal just needs Terminates, recursion, if/else and the ability to treat code as data (functions as integers).

For mathematics, this result has all sorts of interesting implications. For example, if it were not true, we could, in principal, write a function that tested numbers to see if they were odd perfect numbers and marched up the positive integers until it found one. If that function could be evaluated by Terminates, we’d know if there was such a number – something nobody seems to know right now. Any theorem Exists x, P(x) where P can be represented in  our language could be tested by evaluating Terminates on a function that tests P on consecutive integers until it finds a solution. Any theorem Forall x P(x) could be evaluated by seeing if a program that looks for a counter-example ever terminates. All that should indicate that Terminates is implausible as well as impossible. For computer science the implications are more subtle because the fact that we don’t really have computers with infinite memory matters in computer science.

 


Viewing all articles
Browse latest Browse all 195

Trending Articles