210 likes | 231 Views
Mathematical Reasoning. Jason Hallstrom and Murali Sitaraman Clemson University. Overview. Methods for checking code is correct, i.e., it meets specification Testing Tracing or inspection Formal verification of correctness. Testing. Goal: To find bugs
E N D
Mathematical Reasoning Jason Hallstrom and Murali Sitaraman Clemson University
Overview • Methods for checking code is correct, i.e., it meets specification • Testing • Tracing or inspection • Formal verification of correctness
Testing Goal: To find bugs Method: Identify “adequate” test points Recall: Test point = (valid input, expected output) Method: Execute the code on those inputs Cannot test on all inputs Can only show presence of bugs, not absence
Tracing or Formal Inspection Goal: To find bugs Method: Identify “adequate” tracing points Tracing point = test point = (valid input, expected output) Method: Hand trace the code on those inputs Cannot trace on all inputs Can only show presence of bugs, not absence; but some logic check is done
Formal Verification Goal: To prove correctness Method: The rest of this presentation Can prove correctness on all valid inputs Can only show absence of bugs
Example Goal: Prove that the following code requires … ensures I = #J and J = #I; Code: I = sum(I, J); J = difference(I, J); I = difference(I, J);
Example Goal: Prove that the following code requires … ensures I = #J and J = #I; Code: I = sum(I, J); J = difference(I, J); I = difference(I, J);
Recall: Specification of Integer Operations • Think of ints as integers in math • constraints for all integer I • MIN_VALUE <= I <= MAX_VALUE • int sum (int I, int J); • requires MIN_VALUE <= I + J and I + J <= MAX_VALUE; • ensures sum = I + J; • int difference (int I, int J); • requires MIN_VALUE <= I - J and I - J <= MAX_VALUE; • ensures difference = I - J;
Example Goal: Prove that the following code requires … ensures I = #J and J = #I; Code: I = sum(I, J); J = difference(I, J); I = difference(I, J);
Establish the goals in state-oriented terms using a table Assume Confirm 0 … I = sum(I, J); 1 J = difference(I, J); 2 I = difference(I, J); 3 I3 = J0 and J3 = I0;
Establish assumptions (and obligations) Assume Confirm 0 … … I = sum(I, J); 1 I1 = I0 + J0 and … J1 = J0 J = difference(I, J); 2 J2 = I1 - J1 and … I2 = I1 I = difference(I, J); 3 I3 = I2 – J2 and I3 = J0 and J3 = J2 J3 = I0
Prove all assertions to be confirmed • Prove I3 = J0 and J3 = I0 • Proof of I3 = J0 • I3 = I2 – J2 • = (I1 – J1) – I1 substitution for I2 and J2 • = J1 simplification • = J0 substitution for J1 • Proof of J3 = I0 • exercise • Code is correct if all assertions to be confirmed are proved
Example: Confirm caller’s obligations (Why?) Assume Confirm 0 … … I = sum(I, J); 1 I1 = I0 + J0 and MIN_VALUE <= J1 = J0 (I1 – J1) <= MAX_VALUE J = difference(I, J); 2 ……
Confirm caller’s obligations Assume Confirm 0 … MIN_VALUE <= I0 + J0 <= MAX_VALUE I = sum(I, J); 1 … MIN_VALUE <= I1 – J1 <= MAX_VALUE J = difference(I, J); 2 … MIN_VALUE <= I2 – J2 <= MAX_VALUE I = difference(I, J); 3 … I3 = J0 and J3 = I0
Prove all assertions to be confirmed • Proofs - exercises • Given the goal • requires MIN_VALUE <= I + J and I + J <= MAX_VALUE; • ensures I = #J and J = #I; • The code below is correct I = sum(I, J); J = difference(I, J); I = difference(I, J);
Basics of Mathematical Reasoning • Suppose you are verifying code for some operation P • Assume its requires clause in state 0 • Confirm its ensures clause at the end • Suppose that P calls Q • Confirm the requires clause of Q in the state before Q is called • Why? Because caller is responsible • Assume the ensures clause of Q in the state after Q • Why? Because Q is assumed to work • Prove assertions to be confirmed
Another Example Specification: Operation Do_Nothing (restores S: Stack); Goal: Same as ensures S = #S; Code: Procedure Do_Nothing (restores S: Stack); Var E: Entry; Pop(E, S); Push(E, S); end Do_Nothing;
Exercise: Complete table and prove! Assume Confirm 0 … … Pop(E, S); 1 … … Push(E. S); 2 … …
Recall Specification of Stack Operations Operation Push (alters E: Entry; updates S: Stack); requires |S| < Max_Depth; ensures S = <#E> o #S; Operation Pop (replaces R: Entry; updates S: Stack); requires |S| > 0; ensures #S = <R> o S; Operation Depth (restores S: Stack): Integer; ensures Depth = |S|; …
Collaborative Exercise: Answers Assume Confirm 0 … |S| > 0 Pop(E, S); 1 S0 = <E1> o S1 |S| < Max_Depth Push(E. S); 2 S2 = <E1> o S1 S2 = S0 …
Discussion Is the code Correct? If not, fix it Important Idea: The reasoning table can be filled mechanically Principles of reasoning about all objects and operations are the same Need mathematical specifications VC generation and automated verification demo