Send
Close Add comments:
(status displays here)
Got it! This site uses cookies. You consent to this by clicking on "Got it!" or by continuing to use this website.nbsp; Note: This appears on each machine/browser from which this site is accessed.
Program correctness
1. Program correctness
2. Mathematical program verification
Assertion-based axiomatic semantics methods attach assertions to flow of control arcs.
Partial correctness - when the loop (program) stops, the goal is achieved
Total correctness - the loop (program) is partially correct and also stops
The number of errors in a symbolic text is proportional to the number of symbols in that text. The larger the text, the more errors it contains.
3. Types of correctness
A partially correct program is a program that, when it stops, will have achieved the postcondition, given the precondition.
A totally correct program is a program that is partially correct and does, in fact, stop.
4. Checking preconditions
If preconditions are checked too much in code, the efficiency of the system can be degraded.
Not checking preconditions can cause subtle problems to arise.
This might happen, though, in large software projects where the programmers are responsible for their code to the extent that they need to show that, if a problem arises, it is not their fault.
5. Correctness hierarchy
There are three primary ways of showing correctness.
enumeration: assignment, input, output, if-then-else
induction: loops
abstraction: procedures, functions, modules, objects
6. Correctness via enumeration
Correctness via enumeration shows that every possibility is correct. Examples:
input statements
output statements
assignment statements
conditional statements (e.g., if/then/else)
7. Correctness via induction
Correctness via induction shows that, given a base case that is correct, and a step case that is correct and that follows from any preceding case, including the base case, all of the cases are correct.
repetition (e.g., loops)
recursively-defined structures (i.e., structural induction)
8. Correctness via abstraction
Correctness via abstraction is more encompassing method of showing correctness via preconditions and postconditions, etc.
procedures/functions/parameters
input/output interfaces
In complicated systems, abstractions is the only viable means of assuring ourselves that a program is correct.
9. Program correctness
If programs could be proven correct, no testing would be required.
{ pre: a[1..n] is sorted, n >= 0 }
a[0]:= key;
i:= n;
{ inv: key < a[i+1..n] }
while a[i] > key do begin
i:= i-1;
end;
{ post: a[1..i] <= key < a[i+1..n] }
In practice, testing is required.
The industry average is about
50 errors per
1000 lines of code.
10. Good news, bad news
Good news: If you can prove a part of a program correct, you do not need to test it.
Bad news: It can be very hard, or even impossible, to prove certain programs correct.
11. Testing for correctness
How can you test your program to make sure (verify) it works according to specification?
You cannot test your program to make sure (verify) it works according to specification?
12. Dijkstra: Program testing
Program testing can be used to show the presence of bugs, but never to show their absence! 1972.
Edsger Dijkstra (program testing) Dahl, O., Dijkstra, E., & Hoare, C. (1972).
Structured programming. New York: Academic Press., p. 6. .
Dijkstra has said that if debugging is the process of removing bugs from a program, then programming must be the process of putting them in.
13. Dijkstra: Computer bugs
As I have now said many times and written in many places: program testing can be quite effective for showing the presence of bugs, but is hopelessly inadequate for showing their absence. 1976.
Edsger Dijkstra (program bugs) Dijkstra, E. (1976).
A discipline of programming. Englewood Cliffs, NJ: Prentice-Hall., p. 20. .
14. Correctness of multiplication
Here is the reasoning adapted from Dijkstra. Consider showing the correctness of a method for multiplying two numbers. The method is correct if, given two numbers, a correct result is always supplied.
Let each number be represented by
32 bits. Then there are
232 * 232 = 264
possible ways to multiply the
2 numbers.
Smaller example to show method:
24 * 24 = 24+4 = 28 = 256 = 16 * 16 = 24 * 24
Let us also suppose that we have a table by which to check the results (this would be a big table). If we can check about
230 possibilities per second (a billion possibilities a second), it would take about
234 seconds to check all possible combinations. There are about
225 seconds in a year, so it would take
29 years (about
500 years).
15. 64 bits
Now let each number be represented by
64 bits. Then there are
264 * 264 = 2128
possible ways to multiply the
2 numbers.
Now the time is about this many years.
500*264
≈ 500*15,000,000,000,000,000,000 years
= 7,500,000,000,000,000,000,000 years
= 7,500 trillion trillion years
16. Testing and correctness
The hardware will fail before we can check even a tiny fraction of the possibilities. The same is true of software. The bottom line is that we buy computers that will only ever use a tiny fraction of all possible computations.
But we expect every one of them to be correct.
Obviously we cannot check correctness by exhaustive enumeration.
As a result, testing can never show the correctness of a program, but it can show the presence of errors. There are, however, mathematical ways to prove certain programs correct.
17. Program correctness
Programs, to a large extent, can be verified to be correct using various program correctness techniques.
The field is called software verification.
In a beginning programming course, one need only know that such techniques exist and that programs cannot be shown or proven correct by testing.
Who uses formal verification of software?
18. Formal verification
Formal software verification is very costly to use but is used when the cost of failure is very high.
NASA - space missions
Chip manufacturers (Intel, AMD, etc.) - cost of failed processors (Pentium bug) are very high.
Amazon - web and cloud services
19. Testing
Program testing is only useful for showing that a program appears to be good enough to use for some purpose.
A student can encounter such issues when a program works for them with some test data, but then does not work on another computer and/or with other test data.
20. Windows 2000
At the release of the Windows 2000 operating system in February, 2000, a "leaked" memo from Microsoft claimed more the 63,000 bugs and other known problems with the software, which, about three years behind schedule, was released anyway, on February 17, 2000.
21. Program assertions
assertions
bounds checking (i.e., range checking)
22. Testing distributed software
Distributed, concurrent, and/or parallel software systems are exponentially more difficult to show correct than are sequential software systems.
Testing is much harder because execution never follows the same sequence for any two runs of the program.
23. Static program analyzers
Current theorem provers can provide help in verifying program correctness.
Easy to verify a proof
Difficult to develop a proof from scratch
24. End of page
25. Multiple choice questions for this page
8 questions omitted (login required)