Presentation is loading. Please wait.

Presentation is loading. Please wait.

Wishnu Prasetya Predicate-transformer–based Verification (LN Chapter 2)

Similar presentations


Presentation on theme: "Wishnu Prasetya Predicate-transformer–based Verification (LN Chapter 2)"— Presentation transcript:

1 Wishnu Prasetya wishnu@cs.uu.nl www.cs.uu.nl/docs/vakken/pv Predicate-transformer–based Verification (LN Chapter 2)

2 Plan Hoare logic Verification using predicate transformers Verification with “Guarded Command Language” (GCL) Objects and exceptions Should at end give an answer to “how to mechanically verify a real program”. 2

3 Specifying programs We can use “Hoare triples” : total and partial correctness interpretation. { #S>0 } max(S) body { return  S /\ (  x: x  S : return≥x) } 3 { true } plusOne(x) body { return = x+1 }

4 Hoare Logic Provides a set of “inference rules” to prove the validity of Hoare triples. Example: Note : LN uses the notation |- O  P { P } S { Q }, O  P ------------------------------------------------ { O } S { Q } 4

5 The logic’s general idea: break it down! { 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 }

6 Assignment Eventually, everything boils down to “assignments” An assignment is correct if..... Note: this assumes that the assignment only changes the value of x (it does not silently affect other variables) P  Q[e/x] --------------------------------------- { P } x:=e { Q } 6

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 } { k=1000 } while k>0 do k := k-1 { k=0 }

8 Few more examples 8 {¬s /\ k=0 } while k<#b do { s = s \/ b[k] ; k++} { s = ( ∃ m: 0≤m<#b : b[m]) } { s=0 /\ k=0 } while k<10 do { s := s+k ; k++ } { s = 45 }

9 Proving termination (of loop) Extend the previous rule to: P  I { g /\ I } S { I } I /\  g  Q { I /\ g } C:=m ; S { m 0 // m bounded below ---------------------------------------- { P } while g do S { Q } 9

10 Example 10 { x  0 /\ y  0 } while x+y>0 do { if x>0 then { x-- ; y := y+2 } else y-- } { x=0 /\ y=0 }

11 Hoare logic cannot be directly automated Problem: Let’s now look at “predicate transformer-based verification”. A predicate transformer is a function of type : Statement  Predicate  Predicate 11 { P } S 1 { Q }, { Q } S 2 { R } --------------------------------------------------------- { P } S 1 ; S 2 { R }

12 Forward and backward transformer cp  S P (forward) : transform a given pre-condition P to a post-condition. cp  S Q (backward) : transform a given post- condition Q to a pre-condition. Do they produce valid (sound) pre/post conditions? Yes if : { P } S { cp  S P } { cp  S Q } S { Q } 12

13 Forward and backward transformer Sound and complete if : { P } S { Q }  cp  S P  Q { P } S { Q }  P  cp  S Q 13

14 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. 14

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 assert e, assume e 15

16 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 don’t need to propose our own intermediate predicate! Example, prove: 16 { x  y } tmp:= x ; x:=y ; y:=tmp { x  y }

17 GCL’s exotic constructs wlp (assert e) Q = e /\ Q wlp (assume e) Q = e  Q wlp (S T) Q = (wlp S Q) /\ (wlp T Q) More constructs can be expressed as “syntactic sugar” of GCL construtcs. Example: if g then S 1 else S 2  (assume g ; S 1 ) (assume  g ; S 2 ) 17

18 wlp of ite We can reason about the correctness of such sugar through wlp. wlp (if g then S 1 else S 2 ) Q = (g  wlp S 1 Q) /\ (  g  wlp S 2 Q) Note : it is equivalent to (g /\ wlp S 1 Q) \/ (  g /\ wlp S 2 Q) 18

19 Dealing with loop Unfortunately, no general way to calculate wlp of loops. For annotated loop, let’s “define” : wlp (inv I while g do S) Q = I, provided I /\  g  Q I /\ g  wlp S I Otherwise, we can try wlp loop Q =  g /\ Q, but this is usually too restrictive. May not return the weakest pre-cond! Losing completeness, but still sound. 19

20 What if there is no I annotated ? Heuristics to construct invarints e.g. based on the form of the post-condition → not in scope. Dynamically infer invariants → not in scope. Non-heuristic approaches, simple; can be used as starting points. Fix point based Unfolding 20

21 Detour: set semantics of programs and specifications We will keep it simple, just to facilitate certain concepts needed later. What is a program state? Let’s abstractly represent it as a record, e.g: { x=0, y=9 } is a state where the values of the variable x and y are respectively 0 and y. If s is the above state, we refer to its component by s.x and s.y. Let  denotes the space of all possible states of the program we are talking about. 21

22 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) Equivalently, a state predicate P can be seen as a set of all the states on which P is true: “P as a set” = { s | s   /\ P s } Predicate operators translate to set operators, e.g. /\, \/ to  , negation to complement wrt . This ordering : |- P  Q translates to P  Q 22

23 wlp as a set-transformer Recall that wlp is a function of this type: Stmt → Pred → Pred But we can also treat it as a function of type: Stmt → Pow(∑) → Pow(∑) where Pow(∑) is the domain of all subsets of ∑. On this domain, we have: ∩ ∪ ⊆ ⊇ 23

24 wlp as fix point Note this first: while g do S  if g then { S ; while g do S } else skip let W = wlp loop Q. Then : W = F(W) where F : pow(∑)→ pow(∑) F(W) = (g /\ wlp S W) \/ (  g /\ Q) We are looking for the “weakest” solution of W = F(W) 24

25 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. Let (A,  ) be a complete lattice. 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). 25

26 The domain of state predicates, Pow(∑) Suppose ∑ (set of all states) = { s,t,u }. The domain Pow(∑), ordered by ⊆ : 26 { s,t,u } {s,t}{s,u}{t,u} {s} {t}{u} ∅ top ( )... corresponds to “true” bottom ( ).... corresponds to “false” related by ⊆ X ∪ Y (union) acts as the least upper bound of X and Y X ∩ Y (intersection) acts asthe greatest lower bound of X and Y

27 Some bit of fix point theory The domain (pow(∑),  ) is a complete lattice. ∑ = top ∅ = bottom A ∪ B : least upper bound (/\) A ∩ B : greatest lower bound (\/) So, if F defined before is monotonic within this domain, then it has a greatest fix-point. Is F monotonic ? Is wlp monotonic ? 27

28 Some bit of fix point theory Consider now f : pow(∑)  pow(∑). It is  -continuous if for all decreasing chain X 0 ⊇ X 1 ⊇ X 2... : f ( X 0  X 1 ... ) = f(X 0 )  f(X 1 ) ... If f is  -continuous, it is also monotonic. Is wlp  -continuous ? Analogous:  -continuous 28

29 FP iteration Define: f 0 (X) = X, f k+1 (X) = f ( f k (X)) Suppose f is  -continuous. Consider the series f 0 (∑), f 1 (∑), f 2 (∑)... Corollaries: f is also monotonic. The series is a decreasing chain. = f 0 (∑)  f 1 (∑)  f 2 (∑) ... is a fix point of f. is the greatest fix point of f. Similarly, = f 0 (∑)  f 1 (∑)  f 2 (∑) ... is the least fix point of f. 29

30 FP iteration How to compute  { f k (∑) | k  0 } ? compute f 0, f 1, f 2,... but notice you only need to keep track of the last. X := ∑ ; while X  f(X) do X := f(X) Will give the greatest FP, if it terminates. For wlp : W := true ; while W  F(W) do W := F(W) where F(W) = (g /\ wlp S W) \/ (  g /\ Q) 30

31 Example 1 Q is 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 31 while y>0 do { y := y−1 } { y=0 }

32 Example 2 Q is d -- c,d are bool vars W 0 = true W 1 = (y>0 /\ wlp S W 0 ) \/ (  (y>0) /\ d) = (y>0 /\ true) \/ (y  0 /\ d) W 2 = (y>0 /\ wlp S W 1 ) \/ (y  0 /\ d) = (y>0 /\ y>1) \/ (y=1 /\ d) \/ (y  0 /\ d) W 3 = (y>2 ) \/ (y=2 /\ d) \/ (y=1 /\ d) \/ (y  0 /\ d) does not terminate  32 while y>0 do { y := y−1 } { d }

33 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. 33

34 Replacing while with [while] k 34 wlp ([while] 2 (y>0, y := y−1)) (y=0) = ( y=2 \/ y=1 \/ y=0 ) Works if P says y is exactly that (0,1,2). Does not work if P is e.g. y=3 or y≥0 Such unfolding is sound, but incomplete. { P } while y>0 do { y := y−1 } { y=0 }

35 Replacing while with  while  k 35 wlp (  while  2 (y>0, y := y−1)) (y=0) = y≥2 \/ y=1 \/ y=0 P : y=0 \/ y=1... works P : 0≤y... “works” as well This unfolding is complete but unsound.

36 Verification of OO programs GCL is not OO, but we can encode OO constructs in it. We’ll need few additional ingredients : local variables simultant assignment program call array object method 36

37 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) Let’s try another example : wlp (var x’ in assume x’>0 ; y := y+x’ end) (x=y) 37

38 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] 38

39 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: a,b := Pr(e 1,e 2 ) Example : inc(x | r) { r := x+1 } x := inc(x) y := inc(x) 39

40 Encoding program call We will treat program call as syntactic sugar: 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. This allows you to using existing rules to calculate the wlp of calls (except when we have recursion, see next slide). example: wlp (x := inc(x)) (x>1) → x+1 > 1 40

41 Black-box call What if we don’t know the body? Assuming you still have the specification, e.g. : { x>0 } drop(x | r) { r 0 ; assume r < x } example: wlp (x := drop(x)) (x 0 /\ (r < x ⇒ r < 7) (assuming r is fresh!) Note: this allows us to handle call to recursive programs, if they provide specifications (but proving the correctness of a recursive program is still another problem to solve) 41

42 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. See LN, Rule 2.6.12. 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 42

43 Objects Introduce ‘heap’ H : [int][fieldname]  value N, representing the number of existing objects. 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++ } 43

44 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... ? 44

45 Exception Exception introduces non-standard flow of execution, which are often error prone; thus also security prone. The problem is, exception can be thrown from many points in the program, basically exploding the goals to solve for verification. But first... how to deal with exception in Hoare logic / wlp ? Extend post-condition to be a pair (Q n,Q e ) representing the desired situation when a program terminates normally, and when it terminates exceptionally. Or, introduce a variable exc to represent that the program has entered an exceptional state, and explicitly encode the flow in the wlp.  we will do this. 45

46 Exception Introduce a global variable exc : bool, initially false raise sets this variable to true entering a handler reset it to false A state where exc is true, is an ‘exceptional’ state, else it is a normal state. Multiple exception types can be encoded, but we will not do this. The obvious: wlp raise Q = Q[true/exc] 46

47 Sequential composition is now ugly S 1 ; S 2 is treated as: S 1 ; if exc then skip else S 2 Each “;” will double the size of wlp  However, you can statically check S 1 : if it does not contains raise, nor a program call that can potentially do raise,we don’t do the expansion. while g do S  while... /\  exc do S 47

48 Assignments and guards In GCL evaluating an expression does not crash; so you have to properly ‘annotate’ the expression to model crashes. E.g. : x := a[k]/y should be transformed to e.g. : if k<0 \/ k  #a then raise ; if y=0 then raise ; x := a[k]/y ; Deal with “;” as in the previous slide. Similar situation with guards in ite and loop. 48

49 Exception handler S ! H is treated as: S ; if exc then { exc:=false ; H } else skip (“;” should not be expanded here) 49

50 Summary You have now the full wlp-based logic to verify GCL programs. 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. wlp-based logic does not deal with concurrency. 50


Download ppt "Wishnu Prasetya Predicate-transformer–based Verification (LN Chapter 2)"

Similar presentations


Ads by Google