steve@hubcap.clemson.edu ("Steve" Stevenson) (01/06/90)
I'm trying to discover the real reason why people do not prove their programs are correct. I would like to collect those reasons --- even those snappy one liners that we all use as excuses. Please forward your comments ( short flames ok) to me by E-mail. I'll post the replies if there is sufficient interest. Thanks. -- Steve (really "D. E.") Stevenson steve@hubcap.clemson.edu Department of Computer Science, (803)656-5880.mabell Clemson University, Clemson, SC 29634-1906 -- Send compilers articles to compilers@esegue.segue.boston.ma.us {spdcc | ima | lotus}!esegue. Meta-mail to compilers-request@esegue. Please send responses to the author of the message, not the poster.
mmm@cup.portal.com (Mark Robert Thorson) (01/08/90)
There was an excellent article about 10 years ago in CACM on this. I believe the title was "The Social Process and Proofs of Program Correctness". This article marked the death of program verification; feelings which had echoed in the halls of academia and industry for more than a decade were expressed in a clear form in print, and from that point on the "conventional wisdom" was that program verification was a dead-end for research. In retrospect, it's hard hard to see why this wasn't obvious from the very beginning.
snorri@rhi.hi.is (Snorri Agnarsson) (01/10/90)
From article <25711@cup.portal.com>, by mmm@cup.portal.com (Mark Robert Thorson): > There was an excellent article about 10 years ago in CACM on this. > I believe the title was "The Social Process and Proofs of Program > Correctness". This article marked the death of program verification; > feelings which had echoed in the halls of academia and industry > for more than a decade were expressed in a clear form in print, > and from that point on the "conventional wisdom" was that program > verification was a dead-end for research. In retrospect, it's hard > hard to see why this wasn't obvious from the very beginning. I have not read this article and I must confess it is not obvious at all to me that verification is dead. Perhaps automatic program verification is dead, that would not surprise me, but I still believe all programmers should prove their programs while they write them, even if the proofs are only for their own consumption. I believe this is especially important for large projects with many procedures. To be able to maintain a large program you need to know the following for each procedure: 1) Under what circumstances is it allowed to call the procedure? (those are the procedures preconditions) 2) Assuming it is allowed to call the procedure, what will it's effect be? (postconditions) It is astonishing how often large projects are done without documenting the above information. -- Snorri Agnarsson | Internet: snorri@rhi.hi.is Taeknigardur, Dunhaga 5 | UUCP: ..!mcvax!hafro!rhi!snorri IS-107 Reykjavik, ICELAND
frazier@oahu.cs.ucla.edu (Greg Frazier) (01/11/90)
In article <1449@krafla.rhi.hi.is> snorri@rhi.hi.is (Snorri Agnarsson) writes:
+From article <25711@cup.portal.com>, by mmm@cup.portal.com (Mark Robert Thorson):
[delete]
+> verification was a dead-end for research. In retrospect, it's hard
+> hard to see why this wasn't obvious from the very beginning.
+
+I have not read this article and I must confess it is not obvious
+at all to me that verification is dead. Perhaps automatic program
[delete]
+To be able to maintain a large program you need to know the following
+for each procedure:
+
+ 1) Under what circumstances is it allowed to call the
+ procedure? (those are the procedures preconditions)
+
+ 2) Assuming it is allowed to call the procedure, what
+ will it's effect be? (postconditions)
Different versions of verification going on here. THe
first poster meant proof when he said verification. The second
poster confidence in correctness when he said verify. Being
confident a program will work is a far cry from proving that
it will work.
Greg Frazier
...................................................................
"They thought to use and shame me but I win out by nature, because a true
freak cannot be made. A true freak must be born." - Geek Love
Greg Frazier frazier@CS.UCLA.EDU !{ucbvax,rutgers}!ucla-cs!frazier
bzs@world.std.com (Barry Shein) (01/11/90)
Yes, the flap in the early 80's was over automatic program verification. It seemed that DOD was considering putting $150M into this so the debate became quite bloody. The automatic program verification proponents lost. Perlis gave a good talk on why, it went something like: In order to determine if a program is correct another program would have to build some sort of model to compare it against. This would be, presumably, from some sort of abstract specification of what the program is supposed to do. If the verifier could build that model it could translate the specifications into the program. So why bother to write a program to be verified at all? Why not just write a high-level specifications compiler (why indeed, no one knows how, but verification was being passed off as something palpable to work on, like just a big math proof generator.) There were some corrollary observations, like what exactly would such a verifier be able to tell us? Presumably either "yes this program is correct" or "no, this program is not correct". That's of questionable value. If it could tell us useful detail about why it was correct or not then, again, we are led to the conclusion that it could write the program. Also some amusing concerns about verifying the verifier. -- -Barry Shein Software Tool & Die, Purveyors to the Trade | bzs@world.std.com 1330 Beacon St, Brookline, MA 02146, (617) 739-0202 | {xylogics,uunet}world!bzs
bls@cs.purdue.EDU (Brian L. Stuart) (01/12/90)
In article <1990Jan11.015531.20996@world.std.com> bzs@world.std.com (Barry Shein) writes: > >The automatic program verification proponents lost. Perlis gave a good >talk on why, it went something like: > His arguments are significant and important practical considerations, but there is a more fundamental theoretical issue here. 1) No program can be verfied to be correct unless it is verified that it produces the correct output. 2) In verifying the correctness of the output, one verifies the existence of the output. 3) Assume that a program exists that can verify the existence of output. Now create a pre-processor that takes as input a program and produces as output the same program except that it halts after every output. (The construction of such a program is left as a excercize for the reader :-) Now the combination of this pre-processor with the assumed verifier is a program which will detect whether or not a program halts. Hopefully, everyone recognizes that this is impossible according to the halting theorem, so our assumption of a program that can verify the existence of output must be false and by 1) and 2) we cannot have a program that verifies the correctness of programs in general. The upshot of this is that for any language or programming methodology which is verifiable, there will be some programs that can be expressed on a Turing Machine which cannot be expressed in this language or methodology. When you ask for verifibility, you ask to sacrifice Turing-compatability. Be careful what you ask for, you may get it. Brian L. Stuart Department of Computer Science Purdue University
joshua@athertn.Atherton.COM (Flame Bait) (01/12/90)
"Proving your programs are correct" seems to mean different things to different people: One group thinks it means that your program does exactly what your spec says it should. Another group thinks it means that you can put complex assertions in your code and have the checker makes sure that these assertions are always true. The first sort of proof is obviously useless, the spec becomes the program, and bugs in the spec become bugs in the program. Also, specifing most programs is impossible; and if you could, then you could write a compiler for the specification language. The second sort of group is more interesting. It has these advantages: It is possible. It is not all or nothing (simple assertions can added now, and complex ones added later on). And these disadvantages: Doing it well requires specific skills, which need to be taught. It will never prove correctness; it only proves that some assertions are true. There are still problems getting test input data. Joshua Levy joshua@atherton.com home:(415)968-3718 {decwrl|sun|hpda}!athertn!joshua work:(408)734-9822
snorri@rhi.hi.is (Snorri Agnarsson) (01/12/90)
From article <30689@shemp.CS.UCLA.EDU>, by frazier@oahu.cs.ucla.edu (Greg Frazier): > In article <1449@krafla.rhi.hi.is> snorri@rhi.hi.is (Snorri Agnarsson) writes: > +From article <25711@cup.portal.com>, by mmm@cup.portal.com (Mark Robert Thorson): > [delete] > +> verification was a dead-end for research. In retrospect, it's hard > +> hard to see why this wasn't obvious from the very beginning. > +... > +To be able to maintain a large program you need to know the following > +for each procedure: > + > + 1) Under what circumstances is it allowed to call the > + procedure? (those are the procedures preconditions) > + > + 2) Assuming it is allowed to call the procedure, what > + will it's effect be? (postconditions) > > Different versions of verification going on here. THe > first poster meant proof when he said verification. The second > poster confidence in correctness when he said verify. Being > confident a program will work is a far cry from proving that > it will work. No, I meant PROOF. Not automatic proof, just the usual garden variety kind of proof. Of course proofs can be wrong, so all they can do is increase our confidence. While I don't believe automatic verification is ever going to be directly useful I do believe research on those lines is useful because it increases our understanding on how to program. You can use a lot of the same techniques manually, and it is not necessary to do them formally to increase your confidence in your programs. I think every programmer should know about loop invariants, pre- and postconditions, and their use. Every programmer should know the difference between weak and strong correctness, and should know how to prove weak correctness and termination independently. Every programmer should know how to prove weak correctness of mutually recursive procedures, and why the method works. Every programmer should be able to state and prove data invariants for their data types. I find it very hard to understand why some people claim we should not use these techniques just because they do not give us 100% confidence in our programs. Similar reasoning should tell us to abandon testing, and should tell mathematicians to stop writing theorems. -- Snorri Agnarsson | Internet: snorri@rhi.hi.is Taeknigardur, Dunhaga 5 | UUCP: ..!mcvax!hafro!rhi!snorri IS-107 Reykjavik, ICELAND
desnoyer@apple.com (Peter Desnoyers) (01/13/90)
In article <9220@medusa.cs.purdue.edu> bls@cs.purdue.EDU (Brian L. Stuart) writes: >[flawed proof that program verification is impossible.] Try this one instead. Given a program V that will verify whether or not program P run on input I will produce output O. We can transform P by deleting all output statements and having it output a single value O' before it halts. [ie. transform P() to P'(),print(O') where P'() is P() with all print statements deleted.] V(P',I,O') will then determine whether or not the output of P'(I) is O', which is equivalent to determining whether P(I) halts. Therefore V cannot exist. However, this result isn't as useful as it seems. First, there are important classes of programs where V is computable, even if it is not computable on all programs. Second, program verification often means proving whether or not P (the program) is equivalent to P' (the specification), which is a different problem entirely. (although probably not computable in the general case.) Peter Desnoyers Apple ATG (408) 974-4469
bls@cs.purdue.EDU (Brian L. Stuart) (01/13/90)
In article <6158@internal.Apple.COM> desnoyer@apple.com (Peter Desnoyers) writes: >In article <9220@medusa.cs.purdue.edu> bls@cs.purdue.EDU (Brian L. Stuart) >writes: >>[flawed proof that program verification is impossible.] > >Try this one instead. Given a program V that will verify whether or not >program P run on input I will produce output O. We can transform P by >deleting all output statements and having it output a single value O' >before it halts. [ie. transform P() to P'(),print(O') where P'() is P() >with all print statements deleted.] V(P',I,O') will then determine whether >or not the output of P'(I) is O', which is equivalent to determining >whether P(I) halts. > >Therefore V cannot exist. This appears to me to also be a valid proof from the case of verifiers with the specified form. >However, this result isn't as useful as it >seems. First, there are important classes of programs where V is >computable, even if it is not computable on all programs. Second, program >verification often means proving whether or not P (the program) is >equivalent to P' (the specification), which is a different problem >entirely. (although probably not computable in the general case.) Not entirely. Anytime a program is verified, the correctness of its output is verified either implicitly or explicitly. That is why I was careful to phrase my proof in a form that did not say that verification took place by verifying output, but instead took the general case of a verifier. I said that a by-product of the verification process was the verification of output and used that. Why do you feel that my proof was flawed? I know its not as rigorous as it could be, but I don't thing its wrong. Brian L. Stuart Department of Computer Science Purdue University
desnoyer@apple.com (Peter Desnoyers) (01/13/90)
In article <9237@medusa.cs.purdue.edu> bls@cs.purdue.EDU (Brian L. Stuart) writes: > Why do you feel that my proof was flawed? I know its not as rigorous > as it could be, but I don't thing its wrong. Your proof was of the form "take program P and transform it into program P'. Verifying that P produces any output is the equivalent of solving the Halting Problem for P'". In other words, you showed that you could use a program that decides the Halting Problem to decide the verification problem. That isn't a particularly interesting result (since halting problem deciders can compute just about anything :-) - what we need to prove that the verifier cannot exist is to show that you can use the verifier to solve the halting problem. Don't feel bad - I think I made the identical mistake on the net a year or two ago. Peter Desnoyers Apple ATG (408) 974-4469
snorri@rhi.hi.is (Snorri Agnarsson) (01/14/90)
From article <16479@joshua.athertn.Atherton.COM>, by joshua@athertn.Atherton.COM (Flame Bait): > "Proving your programs are correct" seems to mean different things > to different people: > > One group thinks it means that your program does exactly what your > spec says it should. > > Another group thinks it means that you can put complex assertions > in your code and have the checker makes sure that these assertions > are always true. And a third group (including myself) thinks it means you can put assertions in your code and in your interfaces and carefully try to see to it that those assertions are true at each time point. This is not very hard at all for good programmers (in fact I would claim that those who cannot do this cannot be good programmers), and has the extra advantage that the assertions act as documentation for future maintenance. -- Snorri Agnarsson | Internet: snorri@rhi.hi.is Taeknigardur, Dunhaga 5 | UUCP: ..!mcvax!hafro!rhi!snorri IS-107 Reykjavik, ICELAND
joshua@athertn.Atherton.COM (Flame Bait) (01/16/90)
kers@hplb.hpl.hp.com (Kers) writes: >I'll also think that the remark "specifying most programs is impossible" is >wrong. "bloody difficult, especially after the fact" is the predicate that >springs to mind. No problem. Specifiy the following programs, in a machine readable format useful to a program verifier. These should be commerical products, so they must look good and feel good so that people want to use them: A rule based expert system shell. Remember to specify input and output for an window based system. A source code control facility like SCCS or RCS If you use system calls you must have some way of proving that they do what your spec says they do. <Put most any real world program here> My last example points out a current problem with proving program correct. They must only use libraries which have been proven correct, must run on an operating system which has been proven correct, and must use hardware which is proven correct. All of this is impossible right now. I'm serious about this challenge. I hold that these program can not be specified in any kind of useful way, and that the set of programs which can be proven correct is so small as to be uninteresting. I assume everyone has heard the joke about three people (a chemist, a physist, and an economist) who are trapped on a desert island with only cans of food. The punch line is the economist saying "Imagine a can opener". I often think of this branch of the "software proof" camp in the same way. As long as they stick to mathmatical programs which do not have input, output, or any other real life constraints, they can create interesting examples. Joshua Levy joshua@atherton.com home:(415)968-3718 {decwrl|sun|hpda}!athertn!joshua work:(408)734-9822
joshua@athertn.Atherton.COM (Flame Bait) (01/16/90)
In article <1455@krafla.rhi.hi.is> snorri@rhi.hi.is (Snorri Agnarsson) writes: >From article <16479@joshua.athertn.Atherton.COM>, by joshua@athertn.Atherton.COM (Flame Bait): >> Another group thinks it means that you can put complex assertions >> in your code and have the checker makes sure that these assertions >> are always true. > >And a third group (including myself) thinks it means you can put >assertions in your code and in your interfaces and carefully >try to see to it that those assertions are true at each time point. I would group you into my second group. The assertions are checked both statically and dynamically. By the way, I agree that this is good programming practice and I do it myself, but it is not "proving a program correct". I consider it part of defence in depth. Joshua Levy joshua@atherton.com home:(415)968-3718 {decwrl|sun|hpda}!athertn!joshua work:(408)734-9822
markh@csd4.csd.uwm.edu (Mark William Hopkins) (01/16/90)
In article <16664@joshua.athertn.Atherton.COM> joshua@Atherton.COM (Flame Bait) writes: >My last example points out a current problem with proving program correct. >They must only use libraries which have been proven correct, must run on >an operating system which has been proven correct, and must use hardware >which is proven correct. All of this is impossible right now. A program verification would look like this: "This program is guaranteed to operate consistently with the specifications outlined in the adjoining document on a CORRECT compiler and operating system. Any apparent bugs found are solely attributable to one or more of the utilities used to form the environment of the program." (the document could be short for all we care, just so long as it specifies all the details relevant to the user). Just because a program may be operating in a faulty environment does not mean that verification cannot be done with it. Verification is ALWAYS done conditionally on the assumption that everything being used to support the software is correct. In this context, it's only purpose is to eliminate the sources of possible bugs (it can't be the software, so it must be the firmware or even the hardware(!)). And by verification I DO mean mathematical verification. Of course, you will do some actual run-time testing whose purpose is to aid in the discovery of the mathematical properties of the software. That way you can significantly automate much of the discovery process. That's how I've been able to detect bugs in system utilities, such as a local Pascal compiler, an assembler, and even circuitry quite a few times. Never managed to find fault with a chip yet though... It's funny, because a student once came to me with a 200-300 line Pascal program, trying to figure out what was wrong with it. I looked at it in detail, and simply by inspection could tell her that there was nothing wrong with it. Some software you can tell will work simply by looking at it -- that easy they are to prove correct. So ... it was the compiler. The mentality was so ingrained in people (which was actually picked up from the course) that programs are creatures to be analysed behaviorally, instead of mathematical constructs, that it simply never occurred to this person that she might be able to prove that the fault did not lie with her program. >I often think of this branch of the "software proof" camp in the same way. >As long as they stick to mathmatical programs which do not have input, >output, or any other real life constraints, they can create interesting >examples. The irony...
jimad@microsoft.UUCP (JAMES ADCOCK) (01/17/90)
Given that real-world commercial software products of typical size have thousands, if not tens-of-thousands of bugs discovered before shipping, and that most of those bugs have to be fixed, and a few passed over, it seems that one would be better off *not* trying to prove that your [non-trivial] piece of code is correct, but rather understanding when a piece of code fails, under what conditions, and make sure you have the most important day-to-day situations covered. The way one discovers bugs in one's software is not by trying to prove its correct, but rather by trying to show it is incorrect, and how. Trying to 'prove' software is correct does nothing to improve the quality of the software involved. Finding and removing bugs does. The trick is to try to find and fix as many bugs as cheaply as possible in a reasonable amount of time. Is a new, high quality car free of bugs? NO -- it has hundreds or thousands of engineering and manufacturing imperfections. Likewise any reasonably sized piece of software. Rather than try to 'prove' your auto is perfect, better to test that the wheels don't all fall off while driving down the freeway at 60 miles an hour. Again: 'proving' that software is correct does nothing to improve the quality of that software. Finding and removing bugs does improve the quality of software. Find and remove the worst bugs as cheaply as possible in order to create the highest quality of software you can produce. The cheapest bug to remove is the one that was never introduced. And you can't introduce bugs in code never written. So only write code for the most needed features. And make sure you wring most of the bugs out of those features. The proper approach to quality software has more to do with Shewhart and Deming than Turing. Standard disclaimer.
duncan@dduck.ctt.bellcore.com (Scott Duncan) (01/17/90)
In article <10289@microsoft.UUCP> jimad@microsoft.UUCP (JAMES ADCOCK) writes: > Trying to >'prove' software is correct does nothing to improve the quality of the software >involved. Finding and removing bugs does. The trick is to try to find >and fix as many bugs as cheaply as possible in a reasonable amount of time. Actually, as is pointed out below, the "trick" is to avoid introducing defects in the first place or find them before code gets written. While it is true that the writing of code can introduce defects, most people's investigations in defect analysis suggest that a substantial proportion of defects result from requirements, specification, or design problems rather than coding ones. >Is a new, high quality car free of bugs? NO -- it has hundreds or thousands >of engineering and manufacturing imperfections. Likewise any reasonably >sized piece of software. I would submit that the number of parts/pieces/etc. in many manufactured items relative to the number of critical ones -- ones that can cause malfunction -- is higher than that in software. That is, it is more likely that defects in software will produce malfunction than manufacturing imperfections since soft- ware describes a process more than a product. Each step of the process des- cription is important -- otherwise it shouldn't be there (as is also pointed out below). (I would agree that many defects in manufactured products make them less de- sirable to use, but many affects appearances and looks only rather than the safety issue implied by the example below. In software, even the "looks" of software systems can impair their effective use by the customer. Hence the concern for human factors in software.) > Rather than try to 'prove' your auto is >perfect, better to test that the wheels don't all fall off while driving >down the freeway at 60 miles an hour. I believe that the primary job of testing and quality assurance is to try to "prove" a product or software system is not perfect. And, hence, to point out problems in the process -- manufacturing or development -- which created it. I am somewhat in agreement with the attitude expressed here, therfore, and the implied philosophy of identifying what is critical and making sure that/these part(s) function properly. >Again: 'proving' that software is correct does nothing to improve the >quality of that software. True, but then the thrust, as I understand it, is not to improve the quality through proof, but to verify the quality (or lack of it). > Finding and removing bugs does improve the >quality of software. This approach, however "practical," does seem to suggest some giving-in to the inevitability of defects. Perhaps a better approach, all around, would be to investigate the applicability of statistical quality control methods which, if I read the literature on Japanese development efforts correctly, attempt to determine just how much testing is needed to remove cerrtain levels of defects. > Find and remove the worst bugs as cheaply as >possible in order to create the highest quality of software you can produce. Presumably, the statistical approaches are focused on doing just that. >The cheapest bug to remove is the one that was never introduced. And you >can't introduce bugs in code never written. So only write code for the >most needed features. As noted above, I quite agree. It is unfortunate that most productivity mea- sures applied to spftware (be they lines of code, function points, etc.) seem to emphasize producing more code or more features rather than meauring how little code or how few features can be producedd to accomplish the task. >The proper approach to quality software has more to do with Shewhart >and Deming than Turing. Speaking only for myself, of course, I am... Scott P. Duncan (duncan@ctt.bellcore.com OR ...!bellcore!ctt!duncan) (Bellcore, 444 Hoes Lane RRC 1H-210, Piscataway, NJ 08854) (201-699-3910 (w) 609-737-2945 (h))
ian@oravax.UUCP (Ian Sutherland) (01/17/90)
In article <10289@microsoft.UUCP> jimad@microsoft.UUCP (JAMES ADCOCK) writes: >The way one discovers bugs in one's software is not by trying to prove its >correct, but rather by trying to show it is incorrect, and how. Trying to >'prove' software is correct does nothing to improve the quality of the software >involved. Finding and removing bugs does. I have found bugs in software by trying to prove it's correct. In the course of trying to prove it's correct, you realize at some point that it is NOT correct, and the failure of the proof actually points out the bug. Here's a simple but amusing example. Consider the following C program which is intended to swap the values in 2 integer locations: void swap(x,y) int *x; int *y; { int temp; temp = *x; *x = *y; *y = temp; } Looks correct, doesn't it? I tried to verify this program as a simple example in a C verification system we built at the company I work for. In the course of trying to verify it, I started seeing various expressions being generated of the form "if the value in x and the location of temp are the same then A else B". I thought this was a bug in the verifier until I realized that there's nothing about the above program which ensures that swap is not passed a pointer to the location where temp gets put. In fact, once you think about this, it turns out to be pretty easy to get this bug to manifest itself. In other words, the above program does not correctly swap the contents of the 2 locations it's passed in all cases. Not only did attempting to verify the program turn up this bug, but it told us exactly under what circumstances the program will malfunction. It's my experience that verification not only helps you find bugs, but helps you find the ones that you'd be least likely to find by other methods. It's not economical to use on large systems at the moment, but it's getting there, and there are plenty of programs which are not so large whose correctness is nonetheless critical to the system they're a part of. -- Ian Sutherland ian%oravax.uucp@cu-arpa.cs.cornell.edu Sans Peur
markh@csd4.csd.uwm.edu (Mark William Hopkins) (01/17/90)
In article <10289@microsoft.UUCP> jimad@microsoft.UUCP (JAMES ADCOCK) writes: >Given that real-world commercial software products of typical size have >thousands, if not tens-of-thousands of bugs discovered before shipping,... You seem so overly predisposed to the prejudice of "programming as engineering" as to unnecessarily exclude a concept that is already proven to work. For example, the program I made reference to in a previous article as already having verified, optimized, and upgraded added to 4000 lines and the analysis took 2 weeks. Because of the enormous amount of knowledge of that software gathered during the proof process, I can literally go into it and make modifications to it in under a minute (whenever the specification is upgraded). In fact a 200 line extension took an hour to write, and was proven bugfree before the first run. On another occasion, a 1000 line parser generator took one night to prove consistent with its design, and was subsequentally coded in two days without a single error (though the design itself had one minor easily corrected flaw). So... size is simply not an obstacle. It's just a matter of having the competence to carry out such an analysis. >Again: 'proving' that software is correct does nothing to improve the >quality of that software. To prove a piece of software correct means to prove that is does not have any bugs in it (i.e. there is no inconsistency between specification and implementation). It also means to optimize the software using the newly found information gathered during the proof process on its implementation, and my experience has been that most if not all software beyond a certain scale (that has not already undergone this type of analysis) can be optimized by at least 50% if not more (while simultaneously upgrading its functionality, readibility, and verifiability). In my book, showing that a piece of software has no bugs in it is a MAJOR improvement on its quality, especially when done in conjunction with the subsequent optimizations. It leads major improvements in design. In addition, when the software is encumbered by the addition of signal processing routines and interrupts, it proves to be a NECESSITY to verify mathematically its proper functioning. I would consider it irresponsible design if such software was distributed and was not verified against race conditions and things of the like.
keithd@anvil.oz.au (Keith Duddy) (01/17/90)
steve@hubcap.clemson.edu ("Steve" Stevenson) writes: >I'm trying to discover the real reason why people do not prove their programs >are correct. I would like to collect those reasons --- even those snappy >one liners that we all use as excuses. What is your definition of proof? I spent the last year doing honours computer science as Queensland University, and 2 of my 4 subjects were quite devoted to the topic of proving programs correct. One was a specification and design subject - in which I came to the conclusion that any decent sized program (written in anything approaching a `natural' style) was not worth the effort, if it was possible. We studied 2 approaches to refining programs from specifications, both of which allowed a very restricted class of program to be refined with any ease (and once again I doubt the possiblity of refining large programs, or programs with interesting data structures.) The other subject was a functional programming subject, and we attempted a proof of a simple interactive mastermind program, using fixed point theory. Here it is also really a process of refining the program to make it easy to prove - ending up with some drastically warped code (some [unenlightened] people claim that all functional code is warped.) No one in the class, not even the most brilliant mathematical minds, managed to get a plauseable proof, and if they did I contend that it would be of no real assistance because, to my thinking, a proof's first purpose is to convice someone of correctness, and a proof-by-intimidation is not really convincing. Besides this the code you can write for most provable programs is intollerably dull - no recursion, no dynamic data stuctures, only arrays, or else you have to prove that you can't blow a stack, or run out of memory. If you accept testing as a means of `proof' (this does not conform to my definition), then even that is fraught with problems, how do you choose your test data, can you test all permuatations (in some cases this is impossible.) So in the end it comes down to doing reasonable testing and having a certain confidence in your code reading ability. -- keithd@anvil.oz.au (07)870 4999 Anvil Designs Pty Ltd PO Box 954, Toowong, 4066, Australia. -- Send compilers articles to compilers@esegue.segue.boston.ma.us {spdcc | ima | lotus}!esegue. Meta-mail to compilers-request@esegue. Please send responses to the author of the message, not the poster.
snorri@rhi.hi.is (Snorri Agnarsson) (01/17/90)
From article <16664@joshua.athertn.Atherton.COM>, by joshua@athertn.Atherton.COM (Flame Bait): > ... > My last example points out a current problem with proving program correct. > They must only use libraries which have been proven correct, must run on > an operating system which has been proven correct, and must use hardware > which is proven correct. All of this is impossible right now. This is simply a problem of programming in general and has very little to do with program proving. When you prove something you generally have to make some assumtions, in this case you would naturally assume that the descriptions you have for library and system subroutines are correct. Where is the advantage of NOT proving your program correct? > I'm serious about this challenge. I hold that these program can not > be specified in any kind of useful way, and that the set of programs > which can be proven correct is so small as to be uninteresting. In that case the set of useful, trustworthy programs you CANNOT prove correct must be large and interesting. Would you care to give us some examples? Perhaps at the same time you could prove that they are correct and trustworthy, but not provable! -- Snorri Agnarsson | Internet: snorri@rhi.hi.is Taeknigardur, Dunhaga 5 | UUCP: ..!mcvax!hafro!rhi!snorri IS-107 Reykjavik, ICELAND
snorri@rhi.hi.is (Snorri Agnarsson) (01/17/90)
From article <16665@joshua.athertn.Atherton.COM>, by joshua@athertn.Atherton.COM (Flame Bait): > In article <1455@krafla.rhi.hi.is> snorri@rhi.hi.is (Snorri Agnarsson) writes: >>And a third group (including myself) thinks it means you can put >>assertions in your code and in your interfaces and carefully >>try to see to it that those assertions are true at each time point. > I would group you into my second group. The assertions are checked > both statically and dynamically. By the way, I agree that this is > good programming practice and I do it myself, but it is not "proving > a program correct". I consider it part of defence in depth. I usually just check the assertions statically myself, unassisted, and the assertions are simply comments in the program text, not executable statements. Arguing about whether this is a proof or not will not get us far. I claim this is a proof in the usual mathematical sense. Some people seem to think a proof is not a proof until a proof checker has validated it. I disagree. Validation by a proof checker would give me more confidence in a proof, that's all. I agree that this is part of defence in depth, so perhaps we only disagree on the definition of the word "proof". -- Snorri Agnarsson | Internet: snorri@rhi.hi.is Taeknigardur, Dunhaga 5 | UUCP: ..!mcvax!hafro!rhi!snorri IS-107 Reykjavik, ICELAND
mayer@iuvax.cs.indiana.edu (Mayer Goldberg) (01/18/90)
I don't think that the proof theory which produces boring, unintuitive yet correct code, is meant for you to use to verify your own programs ... I would think it is meant for automatic code generation. This could be useful, and time saving. Mayer Goldberg mayer@iuvax.cs.indiana.edu -- Send compilers articles to compilers@esegue.segue.boston.ma.us {spdcc | ima | lotus}!esegue. Meta-mail to compilers-request@esegue. Please send responses to the author of the message, not the poster.
hawley@icot32.icot.jp (David John Hawley) (01/18/90)
In article <10289@microsoft.UUCP> you write: >... >The way one discovers bugs in one's software is not by trying to prove its >correct, but rather by trying to show it is incorrect, and how. Trying to >'prove' software is correct does nothing to improve the quality of the software >involved. Finding and removing bugs does. The trick is to try to find >and fix as many bugs as cheaply as possible in a reasonable amount of time. >Is a new, high quality car free of bugs? NO -- it has hundreds or thousands >of engineering and manufacturing imperfections. Likewise any reasonably >sized piece of software... I think this analogy is misguided. The proper analogy with manufacturing and software would be that the manufacturing process (software) has flaws and these result in unacceptably high-levels of flawed goods (output). It is important to note that there is one process and multiple instances of its output. It seems more efficient to fix the process than fix each output item. It's maybe even better to design the process the right way in the first place. Actually I agree with what has been said in this newsgroup about concentration on formal specifications obscuring the real problem which is modelling the real world, but it is also nice to know that your models are faithfully represented in your experiments (programs). Returning to the article quoted above, since the analogy is bad I can't see any merit in the conclusions.
barmar@think.com (Barry Margolin) (01/18/90)
In article <1248@oravax.UUCP] ian@oravax.odyssey.UUCP (Ian Sutherland) writes:
] void swap(x,y)
] int *x;
] int *y;
] {
] int temp;
]
] temp = *x;
] *x = *y;
] *y = temp;
] }
]In the course of trying to verify it, I started seeing various
]expressions being generated of the form "if the value in x and the
]location of temp are the same then A else B". I thought this was a bug
]in the verifier until I realized that there's nothing about the above
]program which ensures that swap is not passed a pointer to the location
]where temp gets put.
Since the expression &temp never appears, there is no valid way to have a
pointer to temp. It's possible to have a pointer which happens to have the
address of temp in it, but that would be due to invalid code elsewhere in
the program. For instance, if a pointer to an automatic variable is stored
in a global variable or returned from a function then it may later point to
an automatic variable in a different function. This is essentially the
same as using an uninitialized pointer variable.
When verifying a program, certain assumptions must be made. People have
already pointed out that you must assume that the supporting facilities
(the compiler, the runtime library, the hardware) behave as documented, you
must also assume that a function is called validly when verifying that
function in isolation. Otherwise, one could claim that the above function
doesn't operate properly when passed the wrong number of arguments, or when
passed integers (rather than pointers to integers), or when passed pointers
to non-integers. Verifying the above function amounts to saying that
adding it to a correct program will not make that program incorrect.
--
Barry Margolin, Thinking Machines Corp.
barmar@think.com
{uunet,harvard}!think!barmar
joshua@athertn.Atherton.COM (Flame Bait) (01/19/90)
This is a reply to article <1248@oravax.UUCP> ian@oravax.odyssey.UUCP, written by Ian Sutherland. Please look at that posting to see his bogus example. Ian: please learn C (and teach it to your proof system) before posting examples using it. In your example temp is an automatic (or local) variable, while a and b are parameters passed into the function which contains temp. There is no way in C for temp to be the same variable as either a or b. If temp were a static or a global, there would be a problem. Note that calling swap recursively will work fine given your example. This all assumes a working compiler, linker, and runtime, of course. Joshua Levy joshua@atherton.com home:(415)968-3718 {decwrl|sun|hpda}!athertn!joshua work:(408)734-9822
jug@itd.dsto.oz (Jim Grundy) (01/20/90)
From article <16773@joshua.athertn.Atherton.COM>, by joshua@athertn.Atherton.COM (Flame Bait): > This is a reply to article <1248@oravax.UUCP> ian@oravax.odyssey.UUCP, > written by Ian Sutherland. Please look at that posting to see his bogus > example. > > Ian: please learn C (and teach it to your proof system) before posting > examples using it. In your example temp is an automatic (or local) > variable, while a and b are parameters passed into the function which > contains temp. There is no way in C for temp to be the same variable > as either a or b. If temp were a static or a global, there would be > a problem. Note that calling swap recursively will work fine given > your example. Try this (The dummy var has been added so that this procedure has the same signature as the original swap and so a call to it will take up the same stack space) void GetAnAddressOffStack(AddressOnStack, dummy) int *AddressOnStack, dummy; { int TemporaryVariableOnTheStack; AddressOnStack = &TemporaryVariableOnTheStack; } main() { int *AddressOnStack, x, dummy; GetAnAddressOffStack(AddressOnStack &dummy); x = 1; *AddressOnStack = 2; swap(&x, AddressOnStack); printf("&d, &d", x, *AddressOnStack); } Now when swap is called, it's local variable temp will have the same address as the value contained its second parameter y. The printf is going to give you "1, 1". JIM Truely falme bait is what his name suggests
windley@cheetah.ucdavis.edu (Phil Windley/20000000) (02/03/90)
I keep hoping to let this one drop, but people keep making comments that I
just can't let go by. If you're tired of reading this, push "k" now.
In article <10417@microsoft.UUCP> jimad@microsoft.UUCP (JAMES ADCOCK) writes:
I think it is a gross distortion of reality to state that a program
that in actually crashes is "correct" because it has been "proven" to
be so. A real world customer tries running your "proven" correct
spreadsheet and finds that your program crashes when other than trivial
math expressions are requested of it. So said customer calls you up
and you say: "I'm sorry sir, but that program *has* been proven correct!"
BFD.
No one who knows what verification is would ever say that anymore than
Boeing would say in response to an airplane crash "I'm sorry, our
computational fluid dynamics models don't predict that failure, so you're
airplane must still be flying."
Verification *IS NOT* about proving things about real computers and real
programs running on real computers. It is about proving things about
models of real computation. Now, if your contention is that nothing a
model can tell me is worthwhile, then you'll never see any use in
verification (or most of applied mathematics). I'm here to tell you that
models are important and that the things that verification can tell you are
important. I'm not going to claim that it will prove that a program
works.
Verification does not provide "knowledge" in the philosophical sense, it
provides "justified true belief" which is the next best thing.
--
Phil Windley | windley@cheetah.ucdavis.edu
Division of Computer Science | ucbvax!ucdavis!cheetah!windley
University of California, Davis |
Davis, CA 95616 | (916) 752-6452 (or 3168)