Why can\'t a computer program be proven just as a mathematical statement can? A mathematical proof is built up on other proofs, which are built up from yet more proofs and
The halting problem only shows that there are programs that cannot be verified. A much more interesting and more practical question is what class of programs can be formally verified. Maybe every program anyone cares about could (in theory) be verified. In practice, so far, only very small programs have been proven correct.
Just a small comment to those who brought up incompleteness -- it is not the case for all axiomatic systems, only sufficiently powerful ones.
In other words, Godel proved that an axiomatic system powerful enough to describe itself would necessarily be incomplete. This doesn't mean it would be useless however, and as others have linked to, various attempts at program proofs have been made.
The dual problem (writing programs to check proofs) is also very interesting.
Of course they can, as others have posted.
Proving a very small subroutine correct is a good exercise that IMHO every undergraduate in a programming-related degree program ought to be required to do. It gives you great insight into thinking about how to make your code clear, easily reviewable and maintainable.
However, in the real world it is of limited practical use.
First, just as programs have bugs, so do mathematical proofs. How do prove that a mathematical proof is really correct and doesn't have any errors? You can't. And for counter-example, any number of published mathematical proofs have had errors discovered in them, sometimes years later.
Second, you can't prove that a program is correct without having 'a priori' an unambiguous definition of what the program is supposed to do. But any unambiguous definition of what a program is supposed to do is a program. (Although it may be a program in some sort of specification language that you don't have a compiler for.) Therefore, before you can prove that a program is correct, you must first have another program that is equivalent and is known in advance to be correct. So QED the whole thing is futile.
I would recommend tracking down the classic "No Silver Bullet" article by Brooks.
I read a bit about this, but there are two problems.
First, you can't prove some abstract thing called correctness. You can, if things are set up properly, prove that two formal systems are equivalent. You can prove that a program implements a set of specifications, and it's easiest to do this by constructing the proof and program more or less in parallel. Therefore, the specifications must be sufficiently detailed to provide something to prove against, and therefore the specification is effectively a program. The problem of writing a program to satisfy a purpose becomes the problem of writing a formal detailed specification of a program to satisfy a purpose, and that's not necessarily a step forward.
Second, programs are complicated. So are proofs of correctness. If you can make a mistake writing a program, you sure can make one proving. Dijkstra and Gries told me, essentially, that if I was a perfect mathematician I could be a good programmer. The value here is that proving and programming are two somewhat different thought processes, and at least in my experience I make different sorts of mistakes.
In my experience, proving programs isn't useless. When I am trying to do something I can describe formally, proving the implementation correct eliminates a whole lot of hard-to-find errors, primarily leaving the dumb ones, which I can catch easily in testing. On a project that must produce extremely bug-free code, it can be a useful adjunct. It isn't suitable for every application, and it's certainly no silver bullet.
Further, what are the axioms of programming? The very atomic truths of the field?
I've TA'ed a course called Contract Based Programming (course homepage: http://www.daimi.au.dk/KBP2/). Here what I can extrapolate from the course (and other courses I've taken)
You have to formally (mathematically) define the semantics of your language. Let's think of a simple programming language; one that has global variables only, ints, int arrays, arithmetic, if-then-else, while, assignment and do-nothing [you can probably use a subset of any mainstream language as an "implementation" of this].
An execution state would be a list of pairs (variable name, value of variable). Read "{Q1} S1 {Q2}" as "executing statement S1 takes you from execution state Q1 to state Q2".
One axiom would then be "if both {Q1} S1 {Q2} and {Q2} S2 {Q3}, then {Q1} S1; S2 {Q3}"
. That is, if statement S1 takes you from state Q1 to Q2, and statement S2 takes you from Q2 to Q3, then "S1; S2" (S1 followed by S2) takes you from state Q1 to state Q3.
Another axiom would be "if {Q1 && e != 0} S1 {Q2} and {Q1 && e == 0} S2 {Q2}, then {Q1} if e then S1 else S2 {Q2}"
.
Now, a bit of refinement: the Qn's in {}'s would actually be statements about states, not states themselves.
Suppose that M(out, A1, A2) is a statement which does a merging of two sorted arrays and stores the result in out, and that all the words I use in the next example were expressed formally (mathematically). Then "{sorted(A1) && sorted(A2)} A := M(A1, A2) {sorted(A) && permutationOf(A, A1 concatened with A2)}"
is the claim tha M correctly implements the merge algorithm.
One can try to prove this by using the above axioms (a few others would probably be needed. You're likely to need a loop, for one).
I hope this illustrates a bit of what proving programs correct might look like. And trust me: it takes a lot of work, even for seemingly simple algorithms, to prove them correct. I know, I read a lot of attempts ;-)
[if you read this: your hand-in was fine, it's all the other ones that caused me headaches ;-)]
Let us assume a purely functional language (ie Haskell). Side effects can be taken quite cleanly into account in such languages.
Proving that a program produces the right result requires you to specify:
This set of specifications is called denotational semantics. They allow you to prove the reason about programs using mathematics.
The good news is that the "structure of programs" (point 3 above) and the "structure of mathematical sets" are quite similar (the buzzword is topos, or cartesian closed category), so 1/ the proofs you do on the math side will easily be transferred into programmatic constructions 2/ the programs you write are easily shown to be mathematically correct.