@Democoder:
What do you consider a "Program"?
Its a finite sequence of instructions (however large) for me, and in that case you can certainly find a bijection between natural numbers & programms.
Define finite sequence. Do you mean countably infinite? The classic model for computation is the Turing Machine, and Turing Machines can have infinite inputs and outputs.
You can only construct a bijection between Turing computable functions/numbers and the natural numbers. The bijection defines the limits to which numbers are computable, for example.
But consider this:
You write down a list of every possible Turing Machine program, numbered 1,2,3,... You have a bijection between every program and the natural numbers, right?
I will now construct a program that is not on your list:
Code:
for(int step=1; ; step++)
{
run_for_one_step(complement(your_program_list[step])));
}
Don't concern yourself with how "complement" is implemented right now, it's not important. ( It just means "behave differently than the input program", which could just be logical negation, permutation of output, etc.)
This program steps through your list, and at each step I, it runs a program that behaves differently than program I for a single step. This program will behave differently than every program on your list (on step 1, it behaves differently than program 1, on step 2, it behaves different than program 2, etc), and therefore, it is not on your list, therefore your list does not ennumerate all possible programs. (for any possible program on your list, call it N, my new constructed program will behavior differently than your program at step N and therefore cannot be program N)
This is a very real program, since the enumeration procedure itself can be constructed. For example, I could simply represent programs as bitstrings, and program N simply becomes N in binary, so I need no array to 'store' the bijection. Whether or not bitstring 'N' represents a program which halts immediately (invalid) or not is irrelevent, since this is a list of all possible programs, is it not? You might be tempted to add my program to you list, but I assure you, there are an infinitely more of these type.
The fact of the matter is, size of the set of theorems which are true, or algorithms that can be specified are larger than the set of programs. This is a fundamental result of complexity theory or metamathematics if you prefer.
You can't avoid this unless you drastically limit the expressiveness of your instructions, and especially don't allow universal quantifiers. (for all x...there exists...) since the quantifiers encode potentially infinite work.