Click here to load reader

Wishnu Prasetya [email protected] Hoare Logic and Predicate Transformers

Embed Size (px)

Citation preview

  • Slide 1
  • Wishnu Prasetya [email protected] www.cs.uu.nl/docs/vakken/pv Hoare Logic and Predicate Transformers
  • Slide 2
  • Plan Specification Some basic inference rules Dealing with loop Predicate transformers GCL WLP transformer for GCL WLP of loops 2
  • Slide 3
  • Specifying terminating programs A popular way, using Hoare triples : partial correctness or total correctness interpretation. { #S>0 } Pr(S) { return S /\ ( x: x S : returnx) } 3 { x>0 } Pr(x) { return = x+1 }
  • Slide 4
  • Proving the validity of a specification Hoare logic provides a set of inference rules, such as the one below : Note : LN uses the notation |- O P { P } S { Q }, O P ------------------------------------------------ { O } S { Q } 4
  • Slide 5
  • Lets see few more rules { P } S 1 { Q }, { Q } S 2 { R } --------------------------------------------------------- { P } S 1 ; S 2 { R } 5 { P /\ g } S 1 { Q }, { P /\ g } S 2 { Q } ---------------------------------------------------------- { P } if g then S 1 else S 2 { Q }
  • Slide 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 } 6 - --------------------------------------- { Q[e/x] } x:=e { Q }
  • Slide 7
  • Loop A loop is correct if you can find an invariant : E.g. a trivial loop: 7 P I { g /\ I } S { I } I /\ g Q ---------------------------------------- { P } while g do S { Q } { i0 } while i>0 do i := i-1 { i=0 }
  • Slide 8
  • Loop, few more examples 8 { true } i:=0; while i
  • Examples 12 { i=0 /\ N 0 } while i0 do { if x>0 /\ random() { x := x-1 ; y := y+2 } else y := y-1 } { true}
  • Slide 13
  • Hoare logic cannot be directly automated Problem: Well switch to a predicate transformer-based verification. It is a function of type : Statement Predicate Predicate 13 { P } S 1 { Q }, { Q } S 2 { R } --------------------------------------------------------- { P } S 1 ; S 2 { R }
  • Slide 14
  • 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 Q 14
  • Slide 15
  • WP and WLP transformer wp S 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
  • Slide 16
  • 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 assert e, assume e 16
  • Slide 17
  • wlp wlp skip Q = Q wlp (x:=e) Q = Q[e/x] wlp (S 1 ; S 2 ) Q = wlp S 1 (wlp S 2 Q) We dont need to propose our own intermediate predicate! Example, prove: { x y } tmp:= x ; x:=y ; y:=tmp { x y } 17
  • Slide 18
  • GCLs exotic constructs wlp (assert e) Q = e /\ Q wlp (assume e) Q = e Q wlp (S T) Q = (wlp S Q) /\ (wlp T Q) If-then-else can be expressed as: if g then S 1 else S 2 (assume g ; S 1 ) (assume g ; S 2 ) 18
  • Slide 19
  • wlp of ite wlp (if g then S 1 else S 2 ) Q = (g wlp S 1 Q) /\ ( g wlp S 2 Q) Note that this is equivalent to : (g /\ wlp S 1 Q) \/ ( g /\ wlp S 2 Q) 19
  • Slide 20
  • 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 i Otherwise the wlp is g /\ Q May not return the weakest pre-cond! Losing completeness, but still sound. 20
  • Slide 21
  • What if we have no annotation? Note this first: while g do S if g then { S ; while g do S } else skip let W be the wlp of the loop wrt Q. Then : W = (g /\ wlp S W) \/ ( g /\ Q) We are looking for the weakest solution of the above equation. 21
  • Slide 22
  • Detour.... Well 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
  • Slide 23
  • 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
  • Slide 24
  • Expression and predicate An expression is a function val A (state) predicate is a function bool e.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
  • Slide 25
  • Predicate and set equivalence Let P : bool be a predicate. It describes this set: S P = { s | s /\ P s } Conversely, if you know the set, you can reconstruct the original P : ( s. s S P ) 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
  • Slide 26
  • 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
  • Slide 27
  • 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
  • Slide 28
  • 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 ; (S 1 ; S 2 ) s = (S 2. S 1 ) {s} Now you can prove the inference rule : { P } S 1 { Q }, { Q } S 2 { R } ------------------------------------------------------- { P } S 1 ; S 2 { R } 28
  • Slide 29
  • 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
  • Slide 30
  • Some bit of fix point theory The domain (pow(A), ) is a complete lattice. So, what can we say about Pred = 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
  • Slide 31
  • Some bit of fix point theory Consider now f : pow(A) pow(A). It is -continuous if for all decreasing chain X 0, X 1,... (over ) : f ( X 0 X 1 ... ) = f(X 0 ) f(X 1 ) ... Similarly, -continuous If f is -continuous, it is also monotonic. Is wlp -continuous ? 31
  • Slide 32
  • 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
  • Slide 33
  • FP iteration X := A ; while X f(X) do X := 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
  • Slide 34
  • Example 1 Lets try Q : y=0 W 0 = true W 1 = (y>0 /\ wlp S W 0 ) \/ ( (y>0) /\ y=0) = (y>0 /\ true) \/ (y=0) = y 0 W 2 = (y>0 /\ y-1 0) \/ ( (y>0) /\ y=0) = y 1 \/ y=0 = y 0 W 2 = W 1 34 while y>0 do { y := y1 }
  • Slide 35
  • Example 2 Lets try Q : d -- c,d are bool vars W 0 = true W 1 = (y>0 /\ wlp S W 0 ) \/ ( (y>0) /\ d) = (y>0 /\ c) \/ (y 0 /\ d) W 2 = (y>0 /\ wlp S W 1 ) \/ (y 0 /\ d) = (y>1 /\ c) \/ (y=1 /\ c /\ d) \/ (y 0 /\ d) W 3 = (y>2 /\ c) \/ (y=2 /\ c /\ d) \/ (y=1 /\ c /\ d) \/ (y 0 /\ d) does not terminate 35 while y>0 do { assert c ; x := x+y ; y := y1 ; }
  • Slide 36
  • Finite unfolding Define [while] 0 (g,S) = assert g [while] k+1 (g,S) = if g then { S ; [while] k (g,S) } else skip while 0 (g,S) = assume g while k+1 (g,S) = if g then { S ; while k (g,S) } else skip Iterate at most k-times. Iterate at most k-1 times, then miracle. 36
  • Slide 37
  • Replacing while with [while] k 37 while y>0 do { y := y1 } { y=0 } wlp ([while] 2 (y>0, y := y1)) (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. Wont work if P allows y>2. ( )
  • Slide 38
  • Replacing while with while k 38 wlp ( while 1 (y>0, y := y1)) (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. if y>0 then { y := y-1 ; assume (y>0) } else skip ( )
  • Slide 39
  • In pictures... 39 imagine, to verify {P} while g do S {Q} k iterations wlp while k wlp [while] k Q < k iterations wlp loop Q
  • Slide 40
  • How about verification of OO programs? GCL is not OO, but we can encode OO constructs in it. Well need few additional ingredients : local variables simultant assignment program call array object method 40
  • Slide 41
  • Local variable wlp (var x in x:=1 ; y := y+x end) (x=y) Rename loc-vars to fresh-vars, to avoid captures: wlp (var x in x:=1 ; y := y+x end) (x=y) Lets try another example : wlp (var x in assume x>0 ; y := y+x end) (x=y) 41
  • Slide 42
  • Simultant assignment For example: x,y := y, x+y { x=y } wlp (x,y := e 1,e 2 ) Q = Q[e 1,e 2 / x,y] Compare it with : (x=y) [y/x] [x+y/y] 42
  • Slide 43
  • Program and program call Syntax: Pr(x,y | r 1, r 2 ) body x,y are input parameters passed by value r 1, r 2 are output parameters, acting as multiple return values. Syntax of program call : Pr(e 1,e 2 ), not very useful in GCL a,b := Pr(e 1,e 2 ) Example : inc(x | r) { r := x+1 } 43
  • Slide 44
  • Encoding program call GCL does not have program call, but it can be encoded: a,b := Pr(e 1,e 2 ) body var x,y,r 1,r 2 in x,y := e1,e2 ; body ; a,b := r 1,r 2 end Rename to make the loc-vars fresh. example: wlp (x := inc(x)) (x>1) 44
  • Slide 45
  • Black-box call What if we dont 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
  • Slide 46
  • 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
  • Slide 47
  • 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
  • Slide 48
  • 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
  • Slide 49
  • 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 : assume J(x,y) ; x:=x+y ; assert J(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
  • Slide 50
  • 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. 50