Discrete Math and Reasoning about Software Correctness Computer
Discrete Math and Reasoning about Software Correctness Computer Science School of Computing Clemson University Murali Sitaraman (murali@clemson. edu) http: //www. cs. clemson. edu/group/resolve/ This research is funded in part by NSF grants CCF-0811748, CCF‐ 1161916, DUE-1022191, and DUE-1022941.
Lecture 1 Computer Science School of Computing Clemson University Intro to Program Correctness
Overview School of Computing Clemson University o Software correctness proofs o Connections between software correctness and discrete math foundations
Discrete Math School of Computing Clemson University o Typical discrete math proof set up o P Q o Same as Assume P Confirm Q
Software Correctness School of Computing Clemson University o Code is correct if it meets its specifications. o Specification of an operation involves pre- and post-conditions, which are logical assertions o Basic set up Assume pre-conditions Code Confirm post-conditions
Software Correctness School of Computing Clemson University o Pre-conditions are givens or facts that you can assume o Post-conditions are guarantees or obligations that you must confirm (prove) o Basic set up Assume pre-conditions Code Confirm post-conditions
Software Correctness School of Computing Clemson University o Assuming the pre-conditions, if you execute the code that follows, would you be able to confirm the logical assertions at the end of the code? o For now: Assume that nothing goes wrong during the execution of the code.
Example #1: Is Code Correct? School of Computing Clemson University o Example #1 (b is a Boolean variable) Assume b; b : = not b; // : = is assignment Confirm b; o C code corresponding to the above Assume b; b = !b; Confirm b; // = is assignment o We will use : = for assignment, etc.
Example #1: Is Code Correct? School of Computing Clemson University o Example #1 (b is a Boolean variable) Assume b; b : = not b; Confirm b; o The code above means: Assume b = true; b : = not b; Confirm b = true;
Example #2: Is Code Correct? School of Computing Clemson University o Example #1 (b is a Boolean variable) Assume b; b : = not b; Confirm not b; o Same as: Assume b = true; b : = not b; Confirm b = false;
Correctness: A Method School of Computing Clemson University o Example #1 (I is an Integer variable) Assume true; I : = 0; Confirm I = 17; o Replace the value of I in the Confirm assertion with the “effect” of the code and remove the code o Above code becomes Assume true; Confirm 0 = 17;
Correctness: Method Continued School of Computing Clemson University o Above code becomes o o Assume true; Confirm 0 = 17; Same as true false; Same as not true false; Same as false;
Correctness: A Method School of Computing Clemson University o Example #1 (I is an Integer variable) Assume true; I : = 0; Confirm I = 17; o After many transformations, above code becomes false; o Code is incorrect
Correctness: A General Method School of Computing Clemson University o Example (I is an Integer variable) Assume … ; … -- some code I : = J; -- last statement Confirm I = 17; o Replace the value of I and reduce to: Assume … ; … -- some code Confirm J = 17; o Repeat the process till there are no
Correctness: Method School of Computing Clemson University o Code is reduced to a logical assertion (starting with the last statement in the method used here) o Code is correct if and only if the logical assertion is provable o We will use various techniques and results from discrete math to complete the proofs
A Slightly Larger Example School of Computing Clemson University o Software is correct if it meets its specifications. o Is the following code segment correct? Assume all variables are Integers. Assume I = #I and J = #J; Temp : = I; I : = J; J : = Temp; Confirm I = #J and J = #I;
Proof in 2 Parts School of Computing Clemson University o o Part 1: Assume I = #I and J = #J; Temp : = I; I : = J; J : = Temp; Confirm I = #J; Part 2: Assume I = #I and J = #J; Temp : = I; I : = J; J : = Temp; Confirm J = #I;
Proof of Part 1 School of Computing Clemson University Assume I = #I and J = #J; Temp : = I; I : = J; J : = Temp; Confirm I = #J; o Replace J in the Confirm assertion with the effect of the highlighted statement
Simplify School of Computing Clemson University Assume I = #I and J = #J; … J : = Temp; Confirm I = #J; o becomes (there is no J to be replaced in the confirm assertion!) Assume I = #I and J = #J; Temp : = I; I : = J; Confirm I = #J;
Simplify again School of Computing Clemson University Assume I = #I and J = #J; Temp : = I; I : = J; Confirm I = #J; o Becomes (replacing I with J) Assume I = #I and J = #J; Temp : = I; Confirm J = #J;
Simplify one more time School of Computing Clemson University Assume I = #I and J = #J; Temp : = I; Confirm J = #J; o Becomes (no change in the confirm assertion, because there is no Temp) Assume I = #I and J = #J; Confirm J = #J;
Correctness Established School of Computing Clemson University o Simplify one more time. Assume I = #I and J = #J; Confirm J = #J; o The above is the same as: (I = #I and J = #J) (J = #J); o true, because P and Q Q;
Proof of Part 2 School of Computing Clemson University Assume I = #I and J = #J; Temp : = I; I : = J; J : = Temp; Confirm J = #I; o Replace J in the Confirm assertion with the effect of the highlighted statement
Simplify School of Computing Clemson University Assume I = #I and J = #J; … J : = Temp; Confirm J = #I; o Becomes (J is replaced with Temp in the confirm assertion) Assume I = #I and J = #J; Temp : = I; I : = J; Confirm Temp = #I;
Simplify again School of Computing Clemson University Assume I = #I and J = #J; Temp : = I; I : = J; Confirm Temp = #I; o becomes (no I in confirm assertion) Assume I = #I and J = #J; Temp : = I; Confirm Temp = #I;
Simplify one more time School of Computing Clemson University Assume I = #I and J = #J; Temp : = I; Confirm Temp = #I; o Becomes (Temp is replaced with I in the confirm assertion) Assume I = #I and J = #J; Confirm I = #I;
Correctness Established School of Computing Clemson University o Simplify one more time. Assume I = #I and J = #J; Confirm I = #I; o The above is the same as: (I = #I and J = #J) (I = #I); o true, because P and Q P;
Correctness Summary School of Computing Clemson University o What did we just do? o Mathematically prove that a piece of code is correct using integer theory and logic. o The process is mechanical. You can do both parts in the proof simultaneously; we did it separately to make it easier. o This is unlike testing where we can only show presence of errors, but not their absence.
Demonstration School of Computing Clemson University o Demo site: www. cs. clemson. edu/group/resolve/ o Click on Components Tab at the top o Click on Facilities in the Finder o Click on Int_Swap_Example_Fac o Comment out operations Exchange 2 and Main and their procedure using (* … *) o Click on Verify
Demonstration School of Computing Clemson University o Specifications have the form Operation … o requires pre-conditions o ensures post-conditions o Given a piece of code to implement the above specification, we get: Assume pre-conditions Code Confirm post-conditions o This is the starting point
Demonstration School of Computing Clemson University o Specification Operation Exchange (updates I, J: Integer); o ensures I = #J and J = #I; o Values of parameters I and J are updated or modified by the operation o Operation has no requires clause (precondition) o In the ensures clause (post-condition), #I and #J denote input values
Demonstration School of Computing Clemson University o Specification Operation Exchange (updates I, J: Integer); o ensures I = #J and J = #I; o Implementation code (procedure) Temp : = I; I : = J; J : = Temp; o Putting it together get: Assume true; -- no pre-conditions Code Confirm I = #J and J = #I;
Demonstration School of Computing Clemson University o Actually putting it together get: Assume I = #I and J = #J; --system knows! Assume true; --no pre-conditions Code Confirm I = #J and J = #I; o So we have (same as our exercise in class): Assume I = #I and J = #J; --system knows! Temp : = I; I : = J; J : = Temp; Confirm I = #J and J = #I;
Demonstration Summary School of Computing Clemson University o Correctness proofs can be automated o It is mostly tedious work o Need an integrated specification- programming language like RESOLVE o There are many specifications languages, just like there are many programming languages ANNA, B, Dafny, Eiffel, JML, …VDM, Z All of them use discrete math notations!
Arithmetic Example School of Computing Clemson University o Example (Ans, I, and J are Integers) Assume true; Ans : = J - I; Confirm Ans : = I - J; o Is the code correct? o Why or why not?
Example: Is Code Correct? School of Computing Clemson University o Example (Ans, I, and J are Integers) Assume true; Ans : = J - I; Confirm Ans = I - J; o Is the code correct? o Substituting J - I for Ans, we have Assume true; Confirm J – I = I – J; o After more transformations: false //universal statement
Another Arithmetic Example School of Computing Clemson University o Example (Ans, I, and J are Integers) Assume true; Ans : = J + I; Confirm Ans : = I + J; o Is the code correct? o Why or why not?
Example: Is Code Correct? School of Computing Clemson University o Example (Ans, I, and J are Integers) Assume true; Ans : = J + I; Confirm Ans = I + J; o Is the code correct? o Substituting J + I for Ans, we have Assume true; Confirm J + I = I + J; o After more transformations: true // + is commutative!
Take Home Exercise #1: Prove School of Computing Clemson University o Assume all variables are Integers. Assume I = #I and J = #J; I : = I + J; J : = I - J; I : = I - J; Confirm I = #J and J = #I; o Do it in two steps. Confirm I = #J Confirm J = #I
Lecture 2 Computer Science School of Computing Clemson University Computational bounds and correctness with objects other than Integers
From Before: Is Code Correct? School of Computing Clemson University o Example (Ans, I, and J are Integers) Assume true; Ans : = J + I; Confirm Ans = I + J; o Is the code correct? o Substituting J + I for Ans, we have Assume true; Confirm J + I = I + J; o After more transformations: true // + is commutative!
Example Demonstration School of Computing Clemson University o Try the arithmetic example at the demo site o Type this in; comment out other ops; click verify and continue with slides! Operation Ans(eval I, J: Integer): Integer; ensures Ans = I + J; Procedure Ans : = J + I; -- same as return(J + I); end; o Are we able to prove it automatically? o Why or why not?
Computational vs. Math Integers School of Computing Clemson University o Cannot verify because assignment could cause an overflow or underflow! o We really need to confirm two things! Assume true; Confirm min_int <= (I + J) and (I + J) <= max_int; -- pre-condition for adding Ans : = J + I; Confirm Ans = I + J; o System knows! It puts in the confirm assertion before assignment.
Computational vs. Math Integers School of Computing Clemson University o To verify we need to include a bounds pre-condition! Try this. Operation Ans(eval I, J: Integer): Integer; requires min_int <= (I + J) and (I + J) <= max_int; ensures Ans = I + J; Procedure Ans : = J + I; end;
Computational vs. Math Integers School of Computing Clemson University o This is provable because now we get: Assume min_int <= (I + J) and (I + J) <= max_int; Confirm min_int <= (I + J) and (I + J) <= max_int; Ans : = J + I; Confirm Ans = I + J;
Computational vs. Math Integers School of Computing Clemson University o This is provable because now we get: Assume min_int <= (I + J) and (I + J) <= max_int; -- pre-condition Confirm min_int <= (I + J) and (I + J) <= max_int; -- system knows Ans : = J + I; Confirm Ans = I + J; -- code -- post-condition
Exercise: Part 1, Step 1 School of Computing Clemson University o Assume I = #I and J = #J; I : = I + J; J : = I - J; I : = I - J; Confirm I = #J; o becomes Assume I = #I and J = #J; I : = I + J; J : = I - J; Confirm I - J = #J;
Take Home Exercise #1: Prove School of Computing Clemson University o You know how to do the rest! o What all do we have to confirm (prove) to show correctness of this code? o Here’s the exercise. Assume I = #I and J = #J; I : = I + J; J : = I - J; I : = I - J; Confirm I = #J and J = #I;
Take Home Exercise #1: Prove School of Computing Clemson University o What all do we have to confirm (prove) to show correctness of this code? o 5 verification conditions (VCs)! Assume I = #I and J = #J; Confirm … -- system knows I : = I + J; Confirm … -- system knows J : = I - J; Confirm … -- system knows I : = I - J; Confirm I = #J and J = #I; -- 2 here
Take Home Exercise: Demo School of Computing Clemson University o Good exercise, but too tedious to work o o this out by hand. Comment out procedures Exchange and Main using (* … *) Click on the VC tab, not the verify tab! See 4 blue icons (labeled VC) pop to the left; there are 5 VCs (one VC icon corresponds to 2) Click on the VC button to the left of ensures and look at VC 0_4
Exercise, Example VC School of Computing Clemson University o Verification Condition VC 0_4 Ensures Clause of Exchange 2: Int_Swap_Example_Fac. fa(20) o Goal: ((I + J) - J)) = J o Given: (min_int <= 0) (0 < max_int) (Last_Char_Num > 0) (min_int <= J) and (J <= max_int) (min_int <= I) and (I <= max_int)
VC is the same as implication School of Computing Clemson University o Verification Condition VC 0_4 Ensures Clause of Exchange 2: Int_Swap_Example_Fac. fa(20) (min_int <= 0) and (0 < max_int) and (Last_Char_Num > 0) and (min_int <= J) and (J <= max_int) and (min_int <= I) and (I <= max_int) ((I + J) - J)) = J
Exercise, Example VC School of Computing Clemson University o Verification Condition VC 0_5 Ensures Clause of Exchange 2: Int_Swap_Example_Fac. fa(20) o Goal: ((I + J) - J) = I o Given: (min_int <= 0) (0 < max_int) (Last_Char_Num > 0) (min_int <= J) and (J <= max_int) (min_int <= I) and (I <= max_int)
Exercise, Unprovable VC School of Computing Clemson University o Verification Condition VC 0_1 Requires Clause of Sum in Procedure Exchange 2: Int_Swap_Example_Fac. fa(22) o Goal: (min_int <= (I + J)) and ((I + J) <= max_int) o Given: (min_int <= 0) (0 < max_int) (Last_Char_Num > 0) (min_int <= J) and (J <= max_int) (min_int <= I) and (I <= max_int)
Exercise, Remaining VCs School of Computing Clemson University o Verification Condition VC 0_2 Requires Clause of Difference in Procedure Exchange 2: Int_Swap_Example_Fac. fa(23) o Verification Condition VC 0_3 Requires Clause of Difference in Procedure Exchange 2: Int_Swap_Example_Fac. fa(24) o Are the above provable? o Don’t click on the verify button (the timer is set short so even provable things won’t verify!)
Demonstration Summary School of Computing Clemson University o Correctness proofs can be automated o It is mostly tedious work o System knows and uses all kinds of results from discrete math o Proof search might time out, so not all correct code might be proved automatically, but no wrong code would be proved!
Discussion and Demo School of Computing Clemson University o Math integers vs. computational integers o Assume and confirm assertions come from requires and ensures clauses of operations o Mechanical “proof” rules exist for all programming constructs, including if statements, while statements, objects, pointers, etc. o They all have discrete math foundations. o Demo site: http: //www. cs. clemson. edu/group/resolve/
More Complex Examples School of Computing Clemson University o Remaining Lecture: How do we deal with programs dealing with objects and operation calls on objects, beyond simple types like Integers o Future Lecture 3: How do we prove correctness of non-trivial code involving loops and recursion (Hint: induction)
Discrete Math and Math Modeling School of Computing Clemson University o Discrete structures, such as numbers, sets, etc. , are used in mathematical modeling of software o Example using another discrete structure: Mathematical strings o Strings are useful to specify and reason about CS structures, such as stacks, queues, lists, etc.
Discrete Structure: Math Strings School of Computing Clemson University o Unlike sets, strings have order Example: Str(Z) for String of integers o Notations Empty string (written empty_string or L) Concatenation ( alpha o beta ) Length ( |alpha| ) String containing one entry ( <5> )
Stacks and Queues School of Computing Clemson University o Stacks and Queues of entries can be mathematically viewed as “strings of entries” o Their operations can be specified using string notations
Stack Operations School of Computing Clemson University o Example operation specifications Operation Push (updates S: Stack, …) requires |S| < Max_Depth; ensures S = <#E> o #S; Operation Pop (updates S: Stack, …) requires |S| > 0; ensures … Operation Depth (S: Stack): Integer ensures Depth = |S|;
Demonstration School of Computing Clemson University o www. cs. clemson. edu/group/resolve/ o Click on Components Tab at the top o Click on Concepts in the Finder o Select Stack_Template from the list o Select Enhancements o Select Do_Nothing_Capability o Select Realizations o Select Do_Nothing_Realiz o Click on Verify
Do_Nothing, Example VC School of Computing Clemson University o VC 0_2 Requires Clause of Push in Procedure Do_Nothing: Do_Nothing_Realiz. rb(6) o Goal: (|S'| + 1) <= Max_Depth; o Given: (|S| <= Max_Depth) (|S| > 0) S = (<Next_Entry'> o S') o Here, S and S’ are values of Stack S in two different states
Discussion School of Computing Clemson University o How many VCs (verification conditions) are there? o Why? o Proofs of these VCs involve discrete structure results involving mathematical strings Theorem: x: , |<x>| = 1; Theorem: , : Str( ), | o | = | | + | |;
Take Home Exercise #2 School of Computing Clemson University o Do the string theory tutorial at this site http: //www. cs. clemson. edu/resolve/tea ching/tutor/mathematics/String. Theory/ Beg. Part 1. htm Do the exercises at the end of the tutorial
Lecture 3 Computer Science School of Computing Clemson University Induction and Correctness of Programs with Loops and Recursion
Example School of Computing Clemson University int sum(int j, int k) // requires j >= 0 // ensures result = j + k { if (j == 0) { return k; } else { j--; int r = sum(j, k); return r + 1; } }
Reasoning Pattern School of Computing Clemson University o Similar to an inductive proof o Base case (e. g. , j == 0) o Reason code works for the base case o Recursive case (e. g. , j != 0) o Assume that the recursive call j--; r = sum(j, k) works o Reason that the code works for the case of j o Show assumption is legit, i. e. , show termination
Recursion: Base case School of Computing Clemson University int sum(int j, int k) // requires j >= 0 // ensures result = j + k { if (j == 0) { return k; // Assume: (j = 0) ^ (result = k) // Confirm ensures: result = 0 + k } else {. . . } }
Recursion: Inductive Assumption School of Computing Clemson University int sum(int j, int k) // requires j >= 0 // ensures result = j + k { if (j == 0) {. . . } else { j--; int r = sum(j, k); // Assume: r = (j – 1) + k return r + 1; } }
Recursion: Inductive Proof Step School of Computing Clemson University int sum(int j, int k) // requires j >= 0 // ensures result = j + k { if (j == 0) {. . . } else { j--; int r = sum(j, k); return r + 1; // Assume: (r = (j – 1) + k) ^ // (result = r + 1) // Confirm ensures: result = j + k }
Reasoning: Recursive Case School of Computing Clemson University o For the inductive proof to be legit, the inductive assumption must be legit o This requires showing that an argument passed to the recursive call is strictly smaller o This is the proof of termination o To prove termination automatically, programmers need to provide a progress metric (j decreases in the example)
Discrete Math and Specifications School of Computing Clemson University o Discrete structures, such as numbers, sets, etc. , are used in mathematical modeling of software o Example using another discrete structure: Mathematical strings o Strings are useful to specify and reason about CS structures, such as stacks, queues, lists, etc.
Queue Flip Demonstration School of Computing Clemson University o Click on Components Tab at the top o Click on Concepts in the Finder o Select Queue_Template from the list o Select Enhancements o Select Flipping_Capability o Select Realizations o Select Recursive_Flipping_Realiz o Click on Verify
Discussion School of Computing Clemson University o Discuss select VCs
Theorems from string theory School of Computing Clemson University o Various theorems from string theory are necessary to prove software correctness o VCs in proving correctness of recursive realization o Ex. Theorem: string reversal theorem: , : Str( ), Reverse( o ) = Reverse( ) o Reverse( );
Reasoning about iterative code School of Computing Clemson University o Also appeals to induction o Loops need to include an “invariant” and a progress metric for termination o Invariant is established for the base case (i. e. , before the loop is entered) o Invariant is assumed at the beginning of an iteration and confirmed at the beginning of the next o Also needs a progress metric and a proof of termination
Stack Flip Realization School of Computing Clemson University o Click on Components Tab at the top o Click on Concepts in the Finder o Select Stack_Template from the list o Select Enhancements o Select Flipping_Capability o Select Realizations o Select Obvious_Flip_Realiz o Click on Verify
Discussion School of Computing Clemson University o Discuss select VCs
Summary School of Computing Clemson University o Discrete math foundations are central for developing correct software. o Modern programming languages are being enhanced with specification language counterparts to facilitate verification of software correctness o Example spec/programming language combinations include RESOLVE
- Slides: 81