Countability in C

Act I: The Countable RAM

The year is 2150. Mankind has still not ventured into space, but they have made amazing strides in computer hardware. For better or worse, however, the C programming language has survived. We join two young hackers, Treitan and Aila, who explore the ramifications of their new computers on the programs they can write.

Aila: Trei, you have to see this new box!
Treitan: No way could it be as good as mine.
Aila: Are you kidding? We're talking a 4.8 petahertz quantum CPU with infinitely-precise registers...
Treitan: Yeah, yeah, got that.
Aila: An array of 65536 20 exabyte drives...
Treitan: I have my dog's quota set higher than that.
Aila: But here's what I really had to shell out for: infinite RAM.
Treitan: Infinite RAM?
Aila: Yup! Not only is there a memory cell for every number from 0 up, but every memory cell can hold an infinitely-precise real number.
Treitan: But what good is infinite memory if you can't fill it up?
Aila: Oh, but I can. Check out this code:
int* a = malloc(infinity);
for(int i=0; ;i++)
    a[i] = i;
Treitan: Are you kidding? That program obviously never terminates.
Aila: That's not the point. Name a number.
Treitan: Um, how about 131,072?
Aila: It eventually stores that number into a[131072].
Treitan: Okay, how about a santillion? A googleplex?
Aila: It eventually reaches those numbers too, and stores them into some place in the array a.
Treitan: Hmm, I see your point. It doesn't matter so much that it never terminates, as long as it eventually reaches any number I can name. But does this mean that this program stores all of the natural numbers in your RAM?
Aila: Effectively, yes.
Treitan: Ha! You call that power? You can't even fit all of the integers into your memory.
Aila: Sure I can.
Treitan: No you can't. You already filled it up with the natural numbers alone, how can you hope to fit more?
Aila: How about something (types rapidly) like this?
int* a = malloc(infinity);
a[0] = 0;
for(int i=1; ;i+=2) {
    a[i]   =  i;
    a[i+1] = -i;
}
Treitan: Hrm. So it seems like you're storing all the positive numbers at odd indexes and all the negative numbers at even indexes.
Aila: Works beautifully, doesn't it?
Treitan: So it seems like both the natural numbers and all the integers occupy the same amount of space. Hey, let me try something.
Aila: All right, but don't screw anything up.
(Treitan types a new program)
Treitan: There! Check it out, it writes all of the positive rational numbers, fractions, into the array.
int* a = malloc(infinity);
int i=0;
for(int numer=1; ;numer++)
    for(int denom=1; ;denom++)
        a[i++] = numer/denom;
Aila: (sigh) No, Trei, that's not going to work.
Treitan: C2132 does allow infinitely-precise divides, doesn't it?
Aila: Yes, but that's not the problem. Tell me, how long should I wait before your program stores, say, 2/3 into the array?
Treitan: Er, I guess it would be a long time.
Aila: An infinitely long time. Your inner loop never terminates, so numer is going to be 1 forever.
Treitan: Oh well. I should've guessed there's too many rational numbers to fit into your memory.
Aila: You want a bet? (edits the program) Check this out:
int* a = malloc(infinity);
int i=0;
for(int j=1; ;j++)
    for(int denom=1; denom < j; denom++)
        a[i++] = (j-denom)/denom;
Treitan: Hmm, I see. Now the inner loop always terminates, so j reaches every possible value. But how do I know it stores all the rational numbers?
Aila: That's easy. Give me a rational number.
Treitan: How about... 355/113?
Aila: Just wait until j=355+113 and denom=113.
Treitan: I see. Eventually we have to add every rational number. But how can this be true? You're assigning an index in your array to every rational number in the world. But there have to be more rational numbers than array indexes.
Aila: There's actually not, and this program proves it. It seems like there's a lot more rationals, but we can really assign a natural number to every one of them.
Treitan: Well, you still haven't covered all the rational numbers. What about the negative ones, and zero?
Aila: You were always a pain, you know that? If you insist, it's easy to fix. (types) There, see:
int* a = malloc(infinity);
a[0] = 0;
int i=1;
for(int j=1; ;j++)
    for(int denom=1; denom < j; denom++) {
        a[i++] = (j-denom)/denom;
        a[i++] = -(j-denom)/denom;
    }
Treitan: Oh, yeah. It's the same trick you did with the integers.
Aila: Easy as pie.
Treitan: This is really great. I bet you could fit anything into this computer's memory!
Aila: I'm not sure about that, Trei.
Treitan: Watch this! (quickly types and executes a new program)
Aila: What are you doing now?
Treitan: This program just wrote all of the real numbers between zero and one into your memory.
Aila: I don't believe it. Let me see the program.
Treitan: After the way you tore up my last one? I don't think so.
Aila: Fine, be that way. I can write a program that can prove that your program didn't work.
Treitan: (smugly) I'd like to see that.
Aila: (types) Here, check it out:
real new;
for(i=1; ;i++)
    if (digit(a[i],i) == 5)
        digit(new,i) = 4;
    else 
        digit(new,i) = 5;
Treitan: Hmm. So what is this program doing?
Aila: Simple. It's finding a new real number that your program didn't write into the memory. The digit(r,k) function just extracts the kth digit beyond the decimal point of the number r.
Treitan: How do you know that the new number is really new? You might just end up with a number that's already in the array somewhere.
Aila: But I won't, and here's why: notice that the ith digit of new is different from the ith digit of a[i].
Treitan: I can see that. When the ith digit of a[i] is 5, you assign 4, and when it's not 5 you assign 5. But what's the point?
Aila: The point is, if new has a different ith digit from a[i], it's certainly not equal to it, right?
Treitan: I'll buy that...
Aila: And if that's true for all the indexes i...
Treitan: Of course, I see now. It has to be different from every number in every index.
Aila: Right!
Treitan: Okay, so my program has a bug in it. Let me fix it.
Aila: No, Trei, you don't get it. It doesn't matter how you wrote your program. It could work with divine intervention for all I care. My program will still find a new real number that isn't there.
Treitan: So you're telling me there's no way to store all the real numbers in your memory?
Aila: Hrm. I guess you're right. The real numbers won't fit in my memory. There's just too many of them.
Treitan: So much for your fancy new machine!

Act II: The Continuum RAM

To be continued...

Other Moonflare documents

Moonflare home

All text and images, but not necessarily linked material, on this page ©1998-2006 Derrick Coetzee and Moonflare and may not be reproduced or used for any purpose without prior written permission except where otherwise indicated.