240 likes | 334 Views
CSE 3341.03 Winter 2008 Introduction to Program Verification. extending pre-condition calculation to loops. reasoning about actions (Sec. 9.4). wp as a form of debugging: suppose we observe an undesireable result: what caused it? calculate the wp to diagnose the cause of the fault
E N D
CSE 3341.03 Winter 2008Introduction to Program Verification extending pre-condition calculation to loops
reasoning about actions (Sec. 9.4) • wp as a form of debugging: • suppose we observe an undesireable result: what caused it? • calculate the wp to diagnose the cause of the fault • confirm a theory about what could have happened (see Exercise 9.10)
a quick review • if W = wp(S, Q) and {P}S{Q}, what's the relationship between W and P? • Why is wp(S, not Q )not equivalent to not wp(S, Q )? Give a counter-example.
Ex. 9.14 • if A implies B, then wp(S, A) implies wp(S, B) proof? is {wp(S, A)} S {B} true? if wp(S, A) is a pre-condition for B, what does this imply about wp(S, B) ?
while-statements • define wp("while (B) do S", Q) = there exists n ≥ 0 such thatPn where P0 = (not B) and Q, and Pn = B and wp(S, Pn-1) . P1 is pre-condition for the loop running exactly once and then B is false. Pn is pre-condition for the loop running n times and then halting. technically correct, but not helpful. if we haven't found Pn, do we keep looking or give up?
halting problem • if the loop terminates, some Pn must be true but there is no general algorithm for determining whether an arbitrary loop halts (cf. the halting problem for TMs)
conditional correctness • figuring out a pre-condition which holds IF the statement halts shows the loop is conditionally correct wrt the pre- and post-conditions
invariance theorem (or an axiom for "while(B) S") Let W = “while (B) S”. If I and B implies wp(S, I) and I and not B implies Q, then I and wp(W, true) implies wp(W, Q), so {I and wp(“while (B) S”, true) } while (B) S {Q}.
3 while-problems pre(“while(B) S;”, Q) • three aspects: • finding an invariant • relating a pre-condition to B, S, and Q • proving the loop halts for some input states
find an invariant • if a problem is too hard to have practical solutions, we weaken our requirements we accept some pre-condition, rather than insisting on the weakest (most general) • for W = “while(B) S” pre(W, Q) = some invariant I for the loop body S, defined by • I and B implies wp(S, I) -- why do we want this? • I and not B implies Q - why is this appropriate? see diagram in 9.6
exercise 9.15 give a pre-condition for the do-while statement: • do S while (B); //{Goal} • ?
define {P} “do S while (B);” {Q} = {P} “S; while(B) S;” {Q}
while example |: while (i < n) |: //{ x = i*i and y = 2*i - 1} |: {y = y+2; x = x + y ; i = i + 1; |: //{ x = n*n }
proof-obligation(s)? • x=i*i and y=2*i-1 may not be an invariant. Cannot verify i*2-1=y and i*i=x and i<n implies i*i+i*2+1=y+x+2 and i*2+1=y+2 • // PRE: i*2-1=y and i*i=x and not i<n implies n*n=x
searching for an invariant • find a loop-invariant for the following code segment while ( x<>0 ) {x := x-1; y := y+1; } which holds as a precondition for the goal {y = 'old x' + 'old y'} if the loop terminates. • how can wp show that your invariant is a precondition for the goal. ? i. e., what's the specific proof-obligation? • is the computed precondition always true initially? Explain.
double loop z = 0; while (y != 0) //{ x * y + z = 'old x' * 'old y'} { while (even(y)) //{ x * y + z = 'old x' * 'old y' and not(y = 0)} { y = y div 2; x = x * 2;} z = z + x; y = y - 1; } //{z='old x' * 'old y'} x*y+z=old x *old y and not y=0 may not be an invariant. (for the inner loop) Cannot verify y * x+z=old y*old x and not y=0 and even(y) implies y div 2*x*2+z=old y*old x and not y div 2=0 • [ can you help wp prove any of this?]
PRE is calculated as true - what had to be proved? x*y + z = 'old x' * 'old y' and not y = 0 implies pre(inner-loop, x*y + z = 'old x' * 'old y' and not y = 0) • so wp proved: x*y + z = 'old x' * 'old y' and not y = 0 implies x*y + z = 'old x' * 'old y' and not y = 0 which simplifies to true.
adding a variant • variant is like a kitchen timer • counts down to 0, which triggers an exit from the loop
computing x**m //{ k = 0 and y = 1} while(k < m) //{invariant(y = x**k) and variant(m-k)} { y = y*x; k = k+1;} //{ y = x**m }
invariant and variant proof-obligations y=x**k may not be an invariant. Cannot verify x**k=y and k<m implies x** (k+1)=y*x m-k may not terminate loop. Cannot verify x**k=y and m-k<=0 implies not k<m.
possible pre-condition? // PRE: x**k=y and not k<m implies x**m=y Initial condition may not be compatible with the goal. Cannot prove y=1 and k=0 implies (x**k=y and not k<m implies x**m=y).
how to solve the 3*n + 1 problem? • p. 53: //{n > 0} while(n > 1) { if even(n)) n = n div 2; else n = 3*n + 1; }//{ n = 1} an easy invariant: n > 0 • check it achieves the goal if the loop halts: n > 0 and not n > 1 implies n = 1 but no variant known • if the loop were computable by simple recursion, there would be a variant. Why?