Download presentation
Presentation is loading. Please wait.
Published bySilas Woods Modified over 9 years ago
1
Wishnu Prasetya wishnu@cs.uu.nl www.cs.uu.nl/docs/vakken/pv Hoare Logic and Predicate Transformers
2
Plan Specification Some basic inference rules Dealing with loop Predicate transformers GCL WLP transformer for GCL WLP of loops 2
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 : return≥x) } 3 { x>0 } Pr(x) { return = x+1 }
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
5
Let’s 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 }
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 }
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 } { i≥0 } while i>0 do i := i-1 { i=0 }
8
Loop, few more examples 8 { true } i:=0; while i<#a do { a[i] := 3 ; i++ } { all elements of a is 3 } { i=2 /\ N 0 } while i<N do { i := i*2 } { even(i) /\ i N } To note: invariant can be used as abstraction!
9
Loop, few more examples A program to check if an array b contains ‘true’ : 9 { true } i = 0 ; found = false ; while i<#b /\ found do { found=b[i] ; i=i+1} { found = ( j: 0≤j<#b: b[j]) }
10
Loop, few more examples A variation of the previous problem : 10 { ( j: 0≤j<#b: b[j]) } i = 0 ; found = false ; while i<#b /\ found do { found=b[i] ; i=i+1} { found }
11
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 0 // m bounded below ---------------------------------------- { P } while g do S { Q } 11
12
Examples 12 { i=0 /\ N 0 } while i<N do { i = i*2 } { even(i) /\ i N } { x 0 /\ y 0 } while x+y>0 do { if x>0 /\ random() { x := x-1 ; y := y+2 } else y := y-1 } { true}
13
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 13 { P } S 1 { Q }, { Q } S 2 { R } --------------------------------------------------------- { P } S 1 ; S 2 { R }
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
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
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
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 don’t need to propose our own intermediate predicate! Example, prove: { x y } tmp:= x ; x:=y ; y:=tmp { x y } 17
18
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) If-then-else can be expressed as: if g then S 1 else S 2 (assume g ; S 1 ) (assume g ; S 2 ) 18
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
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
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
22
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
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
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
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
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
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
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
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
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
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
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
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
34
Example 1 Let’s 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 := y−1 }
35
Example 2 Let’s 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 := y−1 ; }
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
37
Replacing while with [while] k 37 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. ( )
38
Replacing while with while k 38 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. if y>0 then { y := y-1 ; assume (y>0) } else skip ( )
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
40
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 simultant assignment program call array object method 40
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) Let’s try another example : wlp (var x’ in assume x’>0 ; y := y+x’ end) (x=y) 41
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
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
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
45
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
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
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
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
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
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
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.