Why can't programs be proven?

MathTheoryProofAxiomFormal Verification

Math Problem Overview


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 on down to axioms - those truths truths we hold as self evident.

Computer programs don't seem to have such a structure. If you write a computer program, how is it that you can take previous proven works and use them to show the truth of your program? You can't since none exist. Further, what are the axioms of programming? The very atomic truths of the field?

I don't have good answers to the above. But it seems software can't be proven because it is art and not science. How do you prove a Picasso?

Math Solutions


Solution 1 - Math

Proofs are programs.

Formal verification of programs is a huge research area. (See, for example, the group at Carnegie Mellon.)

Many complex programs have been verified; for example, see this kernel written in Haskell (repaired 404 link is for seL4, see also the moved to location and the project's website).

Solution 2 - Math

Programs absolutely can be proven to be correct. Lousy programs are hard to prove. To do it even reasonably well, you have to evolve the program and proof hand-in-hand.

You can't automate the proof because of the halting problem. You can, however, manually prove the post-conditions and preconditions of any arbitrary statement, or sequence of statements.

You must read Dijsktra's A Discipline of Programming.

Then, you must read Gries' The Science of Programming.

Then you'll know how to prove programs correct.

Solution 3 - Math

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.

Solution 4 - Math

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.

Solution 5 - Math

You can in fact write provably correct programs. Microsoft, for example, has created an extension of the C# language called Spec# which includes an automated theorem prover. For java, there is ESC/java. I'm sure there are many more examples out there.

(edit: apparently spec# is no longer being developed, but the contract tools will become part of .NET 4.0)

I see some posters hand-waving about the halting problem or incompleteness theorems which supposedly prevent the automatic verification of programs. This is of course not true; these issues merely tell us that it is possible to write programs which cannot be proven to be correct or incorrect. That does not prevent us from constructing programs which are provably correct.

Solution 6 - Math

If you're really interested in the topic, let me first recommend David Gries' www.amazon.com/Science-Programming-Monographs-Computer/dp/0387964800">"The Science of Programming", a classic introductory work on the topic.

It actually is possible to prove programs correct to some extent. You can write preconditions and postconditions and then prove that given a state that meets the preconditions, the resulting state after execution will meet the postconditions.

Where it gets tricky, however, is loops. For these, you additionally need to find a loop invariant and to show correct termination you need to find an upper bound function on the maximum possible number of iterations remaining after each loop. You also have to be able to show that this decreases by at least one after each iteration through the loop.

Once you have all this for a program, the proof is mechanical. But unfortunately, there's no way to automatically derive the invariant and bound functions for loops. Human intuition suffices for trivial cases with small loops, but realistically, complex programs quickly become intractable.

Solution 7 - Math

First, why are you saying "programs CAN'T be proven"?

What do you mean by "programs" anyway?

If by programs you're meaning algorithms don't you know Kruskal's? Dijkstra's? MST? Prim's? Binary Search? Mergesort? DP? All those things have mathematical models that describe their behaviors.

DESCRIBE. Math doesn't explain the why of things it simply draws a picture of the how. I can't prove to you that the Sun will rise tomorrow on the East but I can show the data where it has been doing that thing on the past.

You said: "If you write a computer program, how is it that you can take previous proven works and use them to show the truth of your program? You can't since none exist"

Wait? You CAN'T? http://en.wikipedia.org/wiki/Algorithm#Algorithmic_analysis

I can't show you "truth" I a program as much as I can't show you "truth" on language. Both are representations of our empirical understanding of the world. Not on "truth". Putting all gibberish aside I can demonstrate to you mathematically that a mergesort algorith will sort the elements on a list with O(nlogn) performance, that a Dijkstra will find the shortest path on a weighted graph, or that Euclid's algorithm will find you the greatest common divisor between two numbers. The "truth in my program" in that last case maybe that I'll find you the greatest common divisor between two numbers, don't you think?

With a recurrence equation I can delineate to you how your Fibonacci program works.

Now, is computer programming an art? I sure think it is. As much as mathematics.

Solution 8 - Math

I don't come from a mathematical background, so forgive my ignorance, but what does "to prove a program" mean? What are you proving? The correctness? The correctness is a specification that the program must verify to be "correct". But this specification is decided by a human, and how do you verify that this specification is correct?

To my mind, there are bugs in program because humans have difficulties expressing what they really want. alt text

So what are you proving? Bugs caused by lack of attention?

Solution 9 - Math

> 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 ;-)]

Solution 10 - Math

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.

Solution 11 - Math

Theres much research in this area.. as others have said, the constructs within a program language are complex, and this only gets worse, when trying to validate or prove for any given inputs.

However, many languages allow for specifications, on what inputs are acceptable (preconditions), and also allow for specifying the end result (post conditions).

Such languages include: B, Event B, Ada, fortran.

And of course, there are many tools which are designed to help us prove certain properties about programs. For example, to prove deadlock freedom , one could crunch their program through SPIN.

There are also many tools out there that also help us detect logic errors. This can be done via static analysis (goanna, satabs) or actual execution of code (gnu valgrind?).

However, there is no one tool which really allows one to prove an entire program, from inception (specification), implementation and deployment. The B method comes close, but its implementation checking is very very weak. (It assumes that humans are infalible in the translation of speicficaiton into implmentation).


As a side note, when using the B method, you'll frequently find yourself building complex proofs from smaller axioms. (And the same applies for other exhasustive theorem provers).

Solution 12 - Math

They can. I spent many, many hours as a college freshman doing program correctness proofs.

The reason it's not practical on a macro scale is that writing a proof of a program tends to be a lot harder than writing the program. Also, programmers today tend to build systems, not write functions or programs.

On a micro scale, I sometimes do it mentally for individual functions, and tend to organize my code to make them easy to verify.

There's a famous article about the space shuttle software. They do proofs, or something equivalent. It's incredibly costly and time-consuming. That level of verification may be necessary for them, but for any kind of consumer or commercial software company, with current techniques, you'll get your lunch eaten by a competitor who delivers a 99.9% solution at 1% of the cost. Nobody's going to pay $5000 for an MS Office that's marginally more stable.

Solution 13 - Math

If you are looking for confidence, the alternative to proving programs is testing them. This is easier to understand and can be automated. It also allows for the class of programs for which proofs are mathematically not possible, as described above.

Above all, no proof is a substitute for passing acceptance tests:*

  • Just because a program really does do what it says it does, doesn't mean it does what the user wants it to do.

    • Unless you can prove that what it says it does is what the user says they want.

      • Which you then have to prove is what they really want, because, being a user, they almost certainly don't know what they want. etc. Reductio ad absurdum.

*not to mention unit, coverage, functional, integration and all the other kinds of tests.

Hope this helps you on your path.

Solution 14 - Math

Something that has not been mentioned here is the B - Method which is a formal method based system. It was used to develop the safety system of the Paris underground. There are tools available to support B and Event B development, notably Rodin.

Solution 15 - Math

Not only can you prove programs, you can let your computer construct programs from proofs. See Coq. So you don't even have to worry about the possibility of having made a mistake in your implementation.

Solution 16 - Math

Godel's Theorems notwithstanding...What would be the point? What simplistic "truths" would you like to prove? What would you want to derive from those truths? While I may eat these words...where's the practicality?

Solution 17 - Math

Programs CAN be proven. It's quiet easy if you write them in language like for example Standard ML of New Jersey (SML/NJ).

Solution 18 - Math

Your statement is wide so it's catching lots of fish.

The bottom line is: some programs can definitely be proven correct. All programs can not be proven correct.

Here's a trivial example which, mind you, is exactly the same kind of proof that destroyed set theory back in the day: make a program which can determine whether itself is correct, and if it finds that it is correct, give an incorrect answer.

This is Gödel's theorem, plain and simple.

But this is not so problematic, since we can prove many programs.

Solution 19 - Math

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:

  1. a correspondance between data types and mathematical sets
  2. a correspondance between Haskell functions and mathematical functions
  3. a set of axioms specifying what functions you are allowed to build from others, and the corresponding contruction on the mathematical side.

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.

Solution 20 - Math

Read up on the halting problem (which is about the difficulty of proving something as simple as whether a program completes or not). Fundamentally the problem is related to Gödel's incompleteness theorem.

Solution 21 - Math

Some parts of programs can be proved. For example, the C# compiler that statically verify and guarantee type safety, if the the compilation succeeds. But I suspect the core of your question is to prove that a program performs correctly. Many (I do not dare say most) algorithms can be proved to be correct, but a whole program probably cannot be proved statically due to the following:

  • Verification requires all possible branches (calls, ifs and interupts) to be traversed, which in advanced program code has super-cubic time complexity (hence it will never complete within reasonable time).
  • Some programming techniques, either through making components or using reflection, makes it impossible to statically predict execution of code (i.e. you don't know how another programmer will use your library, and the compiler has a hard time predict how reflection in a consumer will invoke functionality.

And those are just some...

Solution 22 - Math

> Further, what are the axioms of programming? The very atomic truths of the field?

Are the opcodes the "atomic truths"? For example on seeing ...

mov ax,1

... mightn't a programmer assert as axiomatic that, barring a hardware problem, after executing this statement the CPU's ax register would now contain 1?

> If you write a computer program, how is it that you can take previous proven works and use them to show the truth of your program?

The "previous work" then might be the run-time environment in which the new program runs.

The new program can be proven: apart from formal proofs, it can be proven "by inspection" and by various forms of "testing" (including "acceptance testing").

> How do you prove a Picasso?

If software is more like industrial design or engineering than like art, a better question might be "how do you prove a bridge, or an airplane?"

Solution 23 - Math

If the program has a well defined objective and initial assumptions (ignoring Godel...) it can be proven. Find all primes,x, for 6<=x<=10, your answer is 7 and that can be proven. I wrote a program that plays NIM (the first Python program I ever wrote) and in theory the computer always wins after the game falls into a state in which the computer can win. I haven't been able to prove it as true, but it IS true (mathematically by a digital binary sum proof) I believe unless I made an error in the code. Did I make an error, no seriously, can someone tell me if this program is beatable?

There are some mathematical theorems that have been "proven" with computer code like the four color theorem. But there are objections, because like you said, can you prove the program?

Solution 24 - Math

proving a program correct can only be done relative to the specification of the program; it is possible but expensive/time-consuming

some CASE systems produce programs more amenable to proofs than others - but again, this relies on a formal semantics of the specification...

...and so how do you prove the specification correct? Right! With more specifications!

Solution 25 - Math

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.

Solution 26 - Math

As others pointed out, (some) programs can indeed be proven.

One problem in practice however is that you first need something (i.e. an assumption or theorem) that you want to prove. So to prove something about a program you first need a formal description of what it should do (e.g. pre- and post-conditions).

In other words, you need a formal specification of the program. But getting even a reasonable (much less a rigorous formal) specification is already one of the hardest things in software development. Therefore it is generally very difficult to prove interesting things about a (real-world) program.

There are however some things which can be (and have been) more easily formalized (and proven). If you can at least prove that your program will not crash, that's already something :-).

BTW, some compiler warnings/errors are essentially (simple) proofs about a program. E.g., the Java compiler will prove that you never access an uninitialized variable in your code (otherwise it will give you a compiler error).

Solution 27 - Math

I haven't read all of the answers, but the way I see it, proving programs is pointless, that's why no one does it.

If you have a relatively small/medium project (say, 10K lines of code), then the proof is probably gonna be also 10k lines, if not longer.

Think about it, if the program can have bugs, the proof can also have "bugs". Maybe you'll need a proof for the proof!

Another thing to consider, programs are very very formal and precise. You can't get any more rigorous and formal, because the program code has to be executed by a very dumb machine.

While proofs are going to be read by humans, so they tend to be less rigorous than the actual code.

The only things you'll want to prove are low-level algorithms that operate on specific data structures (e.g. quicksort, insertion to a binary tree, etc).

These things are somewhat complicated, it's not immediately obvious why they work and/or whether they will always work. They're also basic building blocks for all other software.

Solution 28 - Math

Most answers focused on the practice and that's ok: in practice you don't care about formal proofing. But what's in theory?

Programs can be proven just as a mathematical statement can. But not in the sense you meant! In any sufficient powerful framework, there are mathematical statements (and programs) which cannot be proven! See here

Solution 29 - Math

So much noise here, but I am going to shout in the wind anyhow...

"Prove correct" has different meanings in different contexts. In formal systems, "prove correct" means that a formula can be derived from other proven (or axiomatic) formulas. "Prove correct" in programming simply shows code to be equivalent to a formal specification. But how do you prove the formal spec correct? Sadly, there is no way to show a spec to be bug-free or a solution any real-world problem other than through testing.

Solution 30 - Math

Just my 2 cents, adding to the interesting stuff already there.

Of all the programs that can't be proven, the most common ones are those performing IO (some unpredictible interaction with the world or the users). Even automated proofs sometimes just forget that "proven" programs" run on some physical hardware, not the ideal one described by the model.

On the other side mathematic proofs don't care much of the world. A recurring question with Maths is if it describes anything real. It is raised every time something new like imaginary numbers or non-euclidian space is invented. Then the question is forgotten as these new theories are such good tools. Like a good program, it just works.

Solution 31 - Math

From a less abstract point fo view, proving something is a matter of reducing the field of uncertainty to a proven null set. That's wishful thinking because perfection just cannot be reached in the real world.

A computer program can be provably correct and fail in the real world if its environment are not (or cannot be) proven:

  • the OS kernel, drivers and all user-mode libraries and concurrently executed programs must be proven, including their direct and indirect short-term and long-term side-effects,

  • the hardware must always behave as expected (including with power-outages, water floods, earthquakes, EMF interferences, etc.),

  • end-users must always behave as expected (the famous factor 'X').

Automatic error-correction is implemented in various hardware components (RAM, disks, controllers, etc.) but nevertheless hardware failures still happen - creating cascading errors and/or failures in... provably correct programs.

And I am not even trying to epilogue about end-user creativity...

So, a program (correctly) rated provably correct does not means that it is provably safe in the real-life.

It means that, for the set considered in a defined study (which can only be a subset of the real world), this program will behave as expected.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Question4thSpaceView Question on Stackoverflow
Solution 1 - MathA. RexView Answer on Stackoverflow
Solution 2 - MathS.LottView Answer on Stackoverflow
Solution 3 - MathJohn D. CookView Answer on Stackoverflow
Solution 4 - MathSumudu FernandoView Answer on Stackoverflow
Solution 5 - MathWim CoenenView Answer on Stackoverflow
Solution 6 - MathBoojumView Answer on Stackoverflow
Solution 7 - MathandandandandView Answer on Stackoverflow
Solution 8 - MathNicolas DorierView Answer on Stackoverflow
Solution 9 - MathJonas KölkerView Answer on Stackoverflow
Solution 10 - MathDie in SenteView Answer on Stackoverflow
Solution 11 - MathAlex LimView Answer on Stackoverflow
Solution 12 - MathKenView Answer on Stackoverflow
Solution 13 - MathMike AView Answer on Stackoverflow
Solution 14 - MathJohnno NolanView Answer on Stackoverflow
Solution 15 - MathJay KominekView Answer on Stackoverflow
Solution 16 - MathJason PunyonView Answer on Stackoverflow
Solution 17 - MathvartecView Answer on Stackoverflow
Solution 18 - MathMoeView Answer on Stackoverflow
Solution 19 - MathAlexandre C.View Answer on Stackoverflow
Solution 20 - MathtimdayView Answer on Stackoverflow
Solution 21 - MathScofieldView Answer on Stackoverflow
Solution 22 - MathChrisWView Answer on Stackoverflow
Solution 23 - MathAlexView Answer on Stackoverflow
Solution 24 - MathSteven A. LoweView Answer on Stackoverflow
Solution 25 - MathDavid ThornleyView Answer on Stackoverflow
Solution 26 - MathsleskeView Answer on Stackoverflow
Solution 27 - MathhasenView Answer on Stackoverflow
Solution 28 - MathDavideView Answer on Stackoverflow
Solution 29 - MathChris BroskiView Answer on Stackoverflow
Solution 30 - MathkrissView Answer on Stackoverflow
Solution 31 - MathGilView Answer on Stackoverflow