1 / 49

Hoare Logic and Predicate Transformers

Hoare Logic and Predicate Transformers. Wishnu Prasetya wishnu@cs.uu.nl www.cs.uu.nl/docs/vakken/pv. Plan. Specification Some basic inference rules Dealing with loop Predicate transformers GCL WLP transformer for GCL WLP of loops. Specifying terminating programs.

eliot
Download Presentation

Hoare Logic and Predicate Transformers

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Hoare Logic and Predicate Transformers Wishnu Prasetya wishnu@cs.uu.nl www.cs.uu.nl/docs/vakken/pv

  2. Plan • Specification • Some basic inference rules • Dealing with loop • Predicate transformers • GCL • WLP transformer for GCL • WLP of loops

  3. Specifying terminating programs • A popular way, using “Hoare triples” : • partial correctness or total correctness interpretation. { x>0 } Pr(x) { return = x+1 } { #S>0 } Pr(S) { return  S /\ (x: xS : return≥x) }

  4. Proving the validity of a specification • Hoare logic provides a set of inference rules, such as the one below : • So, what does the rule say? • Note : LN uses the notation |- .OP { P } S { Q } , OP------------------------------------------------ { O } S { Q }

  5. ‘Let’s see few more rules { P } S1 { Q } , { Q } S2 { R } --------------------------------------------------------- { P } S1 ; S2 { R } { P /\ g } S1 { Q } , { P /\ g } S2 { Q } ---------------------------------------------------------- { P } ifgthenS1 else S2{ Q }

  6. Assignment • How to prove the correctness of an assignment? • Alternatively, because pre-cond can be weakened: PQ[e/x]--------------------------------------- { P } x:=e { Q } ---------------------------------------- { Q[e/x] } x:=e { Q }

  7. Loop • A loop is correct if you can find an “invariant” : • E.g. a trivial loop: P I { g /\ I } S { I } I /\ g  Q ---------------------------------------- { P } whilegdo S { Q } { i≥0 } whilei>0 doi := i-1 { i=0 }

  8. Loop, few more examples { i=2 /\ N0} whilei<N do { i:= i*2 } { even(i) /\ iN } { true } i:=0; whilei<#a do { a[i] := 3 ; i++ } { all elements of a is 3 } To note: invariant can be used as abstraction!

  9. Loop, few more examples • A program to check if an array b contains ‘true’ : { true } i = 0 ; found = false ; whilei<#b /\ founddo { found=b[i] ; i=i+1} { found = ( j: 0≤j<#b: b[j]) }

  10. Rule for proving termination (of loop) • Extend the previous rule to:P I { g /\ I } S { I } I /\ g  Q { I /\ g } C:=m ; S { m<C } // m decreasing I /\ g  m> 0 // m bounded below ---------------------------------------- { P } whilegdo S { Q }

  11. Examples { i=0 /\ N0} whilei<N do { i = i*2 } { even(i) /\ iN } { x0 /\ y0 } whilex+y>0 do{ if random() { x := x-1 ; y := y+2 } else y := y-1 } { true}

  12. Hoare logic cannot be directly automated • Problem: • We’ll switch to a predicate transformer-based verification. It is a function of type : Statement  Predicate  Predicate { P } S1 { Q } , { Q } S2 { R } --------------------------------------------------------- { P } S1 ; S2 { R }

  13. Forward and backward transformer • Forward : transform a pre-condition to a post-condition. Similarly: Backward • Sound transformer, if : { P } S { cp S P } { cp S Q } S { Q } • Sound and complete if : { P } S { Q }  cp S P  Q { P } S { Q }  P  cp S P

  14. WP and WLP transformer • wpS Q : the weakest pre-condtion so that S terminates in Q. • wlp S Q : the weakest pre-condition so that S, if it terminates, will terminate in Q.wlp = weakest liberal pre-conidtion. • Though, we will see later, that we may have to drop the completeness property of wp/wlp,but we will still call them wp/wlp.

  15. Guarded Command Language (GCL) • Simple language to start • Expressive enough to encode much larger languages • So that you can keep your logic-core simple • Constructs • skip , assignment, seq, while • raise , S ! H • S  T , if-then-else can be encoded • var x in S end , uninitialized local-var. • program decl, program call • primitive types, arrays • asserte , assumee

  16. wlp • wlp skip Q = Q • wlp (x:=e) Q = Q[e/x] • wlp (S1 ; S2) Q = wlp S1 (wlp S2 Q)We don’t need to propose our own intermediate predicate! • Example, prove:{ xy }tmp:= x ; x:=y ; y:=tmp { xy }

  17. GCL’s exotic constructs • wlp (asserte) Q = e /\ Q • wlp (assumee) Q = eQ • wlp (S  T) Q = (wlp SQ) /\ (wlpT Q) • If-then-else can be expressed as:ifgthen S1else S2 (assumeg ; S1 )  (assume g ; S2 )

  18. wlp of ite • wlp (ifgthen S1else S2) Q = (g wlpS1Q) /\ (g  wlpS2Q) • Note that this is equivalent to : (g /\wlpS1Q) \/ (g /\ wlpS2Q)

  19. Dealing with loop • Unfortunately, no general way to calculate wlp of loops. • For annotated loop:wlp (inv I while g do S) Q = I , provided • I /\ g  Q • I /\ g  wlp S Q • Otherwise the wlpis g /\ Q • May not return the weakest pre-cond! Losing completeness, but still sound.

  20. What if we have no annotation? • Note this first: whilegdo S  if g then { S ; whilegdo S } else skip • let W be the wlp of the loop wrtQ. Then : W = (g /\ wlp S W) \/ (g /\ Q) • We are looking for the “weakest” solution of the above equation.

  21. Detour.... • We’ll discuss two more approaches to deal with loops • Fix point based • Finite unrolling • For the first, we need some background in • Fix point theory • Set-interpretation of predicates; we can just as well present set-semantic of programs and specifications

  22. set semantics of programs and specifications • We will keep it simple, just to facilitate certain concepts needed later. • But you can also use it as a starting point for more a advanced semantic. • What is a program state? Can we abstractly represent it? • set of VariableNameValue • VariableName Value • Record, e.g. { x=0 , y=9 } • Let  denotes the space of all possible states of the program we are talking about.

  23. Expression and predicate • An expression is a function val • A (state) predicate is a function boole.g. x>y is modeled by (s. s.x > s.y) • Note that in terms of this semantic, operations on predicates e.g. P /\ Q , P  Q, etc operate thus on functions.|- P (the predicate P is valid), would then mean: (s: s : P s)

  24. Predicate and set equivalence • Let P : boolbe a predicate. It describes this set:SP= { s | s /\ Ps } • Conversely, if you know the set, you can reconstruct the original P : (s. s  SP ) • From this perspective, we can treat predicates as if they are sets. • Predicate operators translate to set operators, e.g. /\, \/ to   , negation to complement wrt . • This ordering : |- P  Q translates to P  Q

  25. Model of a deterministic program • Model a program by a function :T : pow()such that for any state s, T s gives us the set of all possible end-states if T is executed in s. • This model assumes T terminates.

  26. Set-semantic of specification • Now we have enough to define what a Hoare-triple specification means: { P } Stmt { Q } = (s:: P s  (t : tStmt s Q t))‏We assume S terminates (so, we use the partial correctness interpretation of Hoare triple).

  27. Semantic of SEQ • If f : A pow(A), we lift it to pow(A)  pow(A), overloading :f V =  { f x | xV } • Semantic of “;” (S1 ; S2) s = (S2 . S1) {s} • Now you can prove the inference rule : { P } S1 { Q } , { Q } S2 { R } ------------------------------------------------------- { P } S1 ; S2 { R }

  28. Some bit of fix point theory • (A,) where  is a p.o., is a complete lattice, if every subset X  A has a supremum and infimum. • Supremum = least upper bound = join \/ X  X • Infimum = greatest lower bound = meet /\ X  X • So, we will also have the supremum and infimum of the whole A, often called top and bottom. • Let f : AA. An x such that x = f(x) is a fix point of f. • Knaster-Tarski. If f : AA is monotonic over , and P is the set of all its fix points, then P is non-empty, and (P, ) is a complete lattice. • (thus, both  P and  P are also in P).

  29. Some bit of fix point theory • The domain (pow(A), ) is a complete lattice. • So, what can we say aboutPred =   bool ? • Recall this : W = (g /\ wlp S W) \/ (g /\ Q)We are looking for the “weakest” fix point. “Weakest” in the  ordering corresponds to “greatest” in the  ordering. So, we are looking for the greatest FP, over the domain (Pred,). • Is wlp monotonic ?

  30. Some bit of fix point theory • Consider now f : pow(A)  pow(A). It is -continuous if for all decreasing chain X0, X1, ... (over ) : f ( X0  X1  ... ) = f(X0)  f(X1)  ... • Similarly, -continuous • If f is -continuous, it is also monotonic. • Is wlp -continuous ?

  31. FP iteration • f 0 X = X • f k+1 X = f ( f k X ) • If f is -continuous, its greatest FP is { f k (A) | k0 }Since f is also monotonic, note that f k (A)  f k+1 (A) (by induction) • If f is -continuous, its least FP is { f k () | k0 }

  32. FP iteration • X := A ;while X  f(X) doX := f(X) • Will give the greatest FP, if it terminates. • For wlp : • initialize with X := true • f (W) = (g /\ wlp S W) \/ (g /\ Q)

  33. Example 1 • Let’s try Q : y=0 • W0 = true • W1 = (y>0 /\ wlp S W0) \/ ((y>0) /\ y=0) = (y>0 /\ true) \/ (y=0) = y0 • W2 = (y>0 /\ y-10) \/ ((y>0) /\ y=0) = y 1 \/ y=0 = y0 • W2 = W1 while y>0 do { y := y−1 }

  34. Example 2 while y>0 do { assert c ; x := x+y ; y := y−1 ; } • Let’s try Q : d -- c,d are boolvars • W0 = true • W1 = (y>0 /\ wlp S W0) \/ ((y>0) /\ d) = (y>0 /\ c) \/ (y0 /\ d) • W2 = (y>0 /\ wlp S W1) \/ (y0 /\ d)= (y>1 /\ c) \/ (y=1 /\ c /\ d) \/ (y0 /\ d) • W3 = (y>2 /\ c) \/ (y=2 /\ c /\ d) \/ (y=1 /\ c /\ d) \/ (y0 /\ d) • does not terminate 

  35. Finite unfolding • Define[while]0 (g,S) = assertg[while]k+1 (g,S) = ifg then { S ; [while]k (g,S) }else skipwhile0 (g,S) = assume gwhile k+1 (g,S) = ifg then { S ; whilek (g,S) }else skip • Iterate at most k-times. • Iterate at most k-1 times, then miracle.

  36. Replacing while with [while]k • while y>0 do { y := y−1 } { y=0 } • wlp ([while]2 (y>0 , y := y−1)) (y=0) = y=2 \/ y=1 \/ y=0 • Sound, but incomplete. Given { P } loop { y=0 } to verify, now we have to prove that P implies the above wlp. • Won’t work if P allows y>2. • Blind to unaffected fragments (see blue) /\ z=0 ( ) /\ z=0

  37. Replacing while with whilek • wlp (while1 (y>0 , y := y−1)) (y=0) = y>0 \/ y=0 • Given { y0 } loop { y=0 } to verify, now we have to prove that P implies the above wlp. Success! • The wlp is complete but unsound. • Can still handle unaffected fragments, wrt all iterations. /\ z=0 if y>0 then { y := y-1 ; assume(y>0) }else skip ( ) /\ z=0

  38. In pictures... imagine, to verify {P} whilegdo S {Q} > k iterations  k iterations wlp [while]k Q P P wlpwhilek  k iterations < k iterations But there are also those “unaffected fragments” which are not captured in these pictures.

  39. How about verification of OO programs? • GCL is not OO, but we can encode OO constructs in it. We’ll need few additional ingredients : • local variables • stimulant assignment • program call • array • object • method

  40. Local variable • wlp(varx in x:=1 ; y := y+xend) (x=y) Rename loc-vars to fresh-vars, to avoid captures:wlp(varx’ in x’:=1 ; y := y+x’ end) (x=y) • Let’s try another example :wlp(varx’ inassume x’>0 ; y := y+x’ end) (x=y)

  41. Simultant assignment • For example: x,y := y , x+y { x=y }wlp (x,y := e1,e2) Q = Q[e1,e2 / x,y] • Compare it with : (x=y) [y/x] [x+y/y]

  42. Program and program call • Syntax: Pr(x,y | r1 , r2) body • x,yare input parameters  passed by value • r1 , r2 are output parameters, acting as multiple return values. • Syntax of program call : • Pr(e1,e2), not very useful in GCL • a,b := Pr(e1,e2) • Example : inc(x | r) { r := x+1 }

  43. Encoding program call • GCL does not have program call, but it can be encoded:a,b := Pr(e1,e2) body var x,y,r1,r2inx,y := e1,e2 ; body ; a,b := r1,r2endRename to make the loc-vars fresh. • example: wlp (x := inc(x)) (x>1)

  44. Black-box call • What if we don’t know the body? Assuming you still have the specification, e.g. : { x>0 } inc(x | r) { r  x+1 }We treat this as having this body :inc(x | r) { assert x>0 ; assume r  x+1 } • example: wlp (x := inc(x)) (x>1)

  45. Arrays • Arrays in GCL are infinite. • Introduce the notation a(i repby e) to denote a clone of the array a, but differs at i-th element, which now has the value e. • Treat a[i] := e as a := a(i repby e) • Example :wlp (a[i] := 0) (a[i] = a[3]) • Encode a[i] := 0 in an RL language e.g. as :assert 0 i < #a ; a[i] := 0

  46. Objects • Introduce ‘heap’ H : [int][fieldname]  value • Currently existing objects are stored in H[0] ... H[N-1] • Two types of values : primitive values, or reference to another object. • Encoding : • x := o , unchanged, but note o is thus an int • o.fn := 3 is encoded by H[o][fn] := 3 • Suppose C has a single int-field named a x = new C() is encoded by { H[N][a] := 0 ; x:=N ; N++ }

  47. Methods • Let m(x|r) be a method of class C. It implicitly has the instance-object and the whole heap as input and output parameter. • Example: class C { a:int inc(d) { this.a := this.a+d ; } }The method is translated to:inc(this,H,d | H’) { H[this][a] := H[this][a] + d ; H’ := H } • call o.inc(3) is translated to ... ?

  48. How about concurrency? • Consider x := x+y in a method m • If m has exclusive access to x,y ; wlp as usual. • There may be other threads accessing x,y, but the whole assignment can be done atomically. A possible approach is propose a system invariant J over these x,y, and require that every thread maintains it :assumeJ(x,y) ; x:=x+y ; assertJ(x,y)Additionally all assignments to x or y must assert J as well! • Can be just good enough to prove safety; but not good enough to prove progress/liveness. • If the assignment is not atomic .... • Similarly for guards if ite and loop...

  49. Summary • You have now (almost) the full wlp-based logic to verify GCL programs. • Pending: exception. • The calculation of wlp is syntax driven. • If loops are annotated, the calculation of wlp is fully automatic, else you may have to do some trade off. • RL languages can be translated to GCD; we have shown how some core OO constructs can be translated.

More Related