program proving notes
DESCRIPTION
Program Proving Notes. Ellen L. Walker. Formal Specification & Proof of Programs (Verification). Formally proving that a program satisfies a formal specification Alternative to testing to determine whether a program works as specified. One means of specifying program semantics. Definitions. - PowerPoint PPT PresentationTRANSCRIPT
Program Proving Notes
Ellen L. Walker
Formal Specification & Proof of Programs (Verification)
– Formally proving that a program satisfies a formal specification
– Alternative to testing to determine whether a program works as specified.
– One means of specifying program semantics
Definitions– Specification — description of what a program should do, usually in English.
– Formal specification — a specification using formal mathematical notation. Mathematical notation makes the specification more concise & more precise.
– Proving (verifying) a program — given a program and a formal specification, use formal proof techniques (e.g. induction) to prove that the program behavior fits the specification.
– Specification of a programming language (semantics) — formal specification for each statement in the language.
Formally Proving a Program
– Given:
•formal specification of program
•specification of programming language
•a program in the language
– Prove:
•the program executes according to specifications
Conditions in Specification
• Preconditions– Must hold before the program executes
• Postconditions– Must hold after the program executes
A formal specification always has both preconditions and postconditions
Notation
• P { S } Q– P is the precondition– S is the program (or statement)– Q is the postcondition
• P and Q are written in logic• S is written in the programming
language (or pseudocode)
Specification as Logic
• (P and execution of S) -> Q
• If this expression is always true we say the specification is valid
Example
• x > 0 { x = -x } x < 0– Precondition: x>0– Postcondition: x<0– Program: x = -x
• This specification is valid– When the precondition holds before the
program, the postcondition will always hold after the program.
Special Cases
• P { S } true– Valid for all programs and preconditions
• false { S } Q– Valid for all programs and postconditions– When the precondition is false before
program runs, the specification is valid no matter what!
Many Choices for P and Q
•true { y = x + 1} y > x
•x > 0 { y = x + 1} y > x
•x = 1 { y = x + 1} y > x
•x = 1 { y = x + 1} true
•x = 1 {y = x + 1} y > x
•x = 1 {y = x + 1} y > 1
•x = 1 {y = x + 1} y = 2
Logical Implication
• P->W (“P implies W” or “If P then W”)
P W P->W
True True True
True False False
False True True
False False True
Mathematical examples
• (a>b) -> (b < a) true• (a≥b) -> (a > b) false• (a>b) -> (a ≥ b) true• (a>b) -> (a > b+1) false• (a>b) -> (a ≥ b+1) false• (a>b) and a and b are integers -> (a≥b+1)
true
Rules of Implication
• Shorthand: “a->b” means “a->b is true”
• (A and B) -> A
• (A and B) -> B
• A -> (A or B)
• B -> (A or B)
• (A->B) is equivalent to (not B -> not A)
Strength of Conditions
• If P1 and P2 are conditions, and P1 -> P2,
• Then P1 is stronger than P2and P2 is weaker than P1
• Intuition: stronger conditions are more specific, have fewer “possibilities”
Strength of Conditions (continued)
• The strongest possible condition is false– False -> Q for all Q
• The weakest possible condition is true– P -> True for all P
• Not all conditions are comparable– (y > 1) is not comparable to (x > 0)– (y > 5) is not comparable to (y < 8)
• No implication either way
Weakest Precondition
–Many choices for Precondition•true { y = x + 1} y > x
•x > 0 { y = x + 1} y > x
•x = 1 { y = x + 1} y > x
–Choose the weakest for best specification•Avoids “unnecessary” specification
Why Weakest Precondition?
• Suppose P and W are preconditions and P->W (W is weaker)– Given W { S } Q and P true before the program
begins– Because P->W, W is also true before the program
begins– Therefore P { S } Q
• “W is the precondition that implies all other preconditions that allow S to run and guarantee Q as a postcondition”
• Notation: W = wp(S, Q)
Proving a Program Specification
Goal: prove P { S } Q1. Find wp(S,Q)
2. Prove that P -> wp(S, Q)
Work backwards from postcondition to precondition
Example
• Prove k>0 {x = 1/k } xk=1
• wp(x=1/k,xk=1) is k≠0
• (k>0) -> (k≠0) for all k
• Therefore, our specification is true.
More Examples
– Prove x = 1 {x = 1/x} x > 0• wp (x = 1/x, x > 0) is 1/x > 0, or x > 0
• Since 1>0, x=1 implies x > 0
• Therefore, the specification x =1 {x = 1/x} x > 0 is true.
– Prove x ≠ 0 {x = x + 1} x > 0• wp (x= x + 1, x > 0) is x' + 1 > 0 or x' > –1
• x ≠ 0 doesn't necessarily imply x > –1 (consider x = –5)
• Therefore, the specification x ≠ 0 {x = x + 1} x > 0 is false
Programming Language Semantics
• Language consists of Statements
• Complex statements derived from simpler statements and control structures– Conditionals (IF)– Loops (WHILE)
A Small Language
1. Empty statement (skip)
2. Assignment statement (x=y)
3. Sequence of statements ( { S1 S2 } )
4. Conditional ( if (C) S1 else S2 )
5. Loop ( while (C) S )
Specifying Language Semantics
• For each statement, determine the wp of the statement
• Statement wp depends on its parts– Using conditions (C) directly– Using wp of subordinate statements (S)
Semantics of skip
• The empty statement has no effect
• Therefore wp(skip, Q) is Q
• Example: wp(skip, x<0) is x<0
Semantics of Assignment
• Given x = E (where E is an expression)• Two cases:
– Postcondition does not contain x• Wp(x=E,Q) = Q because Q is unaffected
– Postcondition does contain x• Consider Q as a function of x• Wp(x=E, Q(x)) = Q(E)
• To be careful, we must add “and E is defined” to avoid cases such as x = 1/0
Assignment Examples
• Wp (x=y, y>5) is y>5– Q does not contain x
• Wp (x=y, x<2) is y<2– Q does contain x, so substitute y for x
• Wp (x = x+1, x>4) is x’>3– Use x’ as the “before” value of x
Assignment vs. Equality Test
• Be careful– x=0 {x=1} x=1
Semantics of a Sequence
• Given P {S1} R and R {S2} Q, we can write P { {S1 S2} } Q
• Therefore– Wp({S1 S2}, Q) = wp(S1, wp(S2, Q))
• Find wp of the second statement and the postcondition (R, above)
• Then find wp of the first statement with that wp (R) as the postcondition
Examples
• wp ({x=y; x= 1/x;}, x>0) is wp(x=y, wp(x=1/x, x>0)) iswp(x=y, 1/x > 0) is wp(x=y, x>0) isy > 0
• wp({x = 2*t; skip;}. x>5) iswp(x=2*t; wp(skip, x>5)) iswp(x=2*t, x>5) is2t > 5 is t > 2.5
One More Example
• true {x = 5; y = 2; x = x*y} x=10
Semantics of IF
• The conditional with test T and statements S1 and S2 is – if (T) S1 else S2– When there is no “else, write: if (T) S1 else skip
• Wp(if (T) S1 else S2) is (T and wp(S1,Q)) or ((not T) and wp(S2,Q))– If T is true, use S1’s precondition– If T is false, use S2’s precondition
• Equivalently,(T-> wp(S1,Q)) and ((not T)-> wp(S2,Q))
Proving a Loop
• Two things to prove– If the loop terminates, the postcondition is
true– The loop terminates
• Proving only the postcondition is called weak correctness
Weak Correctness Example
• True {while true x=1} x=1
• Weakly correct– If the loop ever terminated, x would be 1
• Not strongly correct– But the loop will never terminate
Semantics of WHILE
• Treat as a “repeated if”, where B must be true the last time
• Define Pk = wp(loop executes k times, Q)• wp(while (B) S, Q)
– P0 = Not B and Q – P1 = B and wp(S, P0)– P2 = B and wp(S, P1)– Pk = B and wp(S, Pk-1)
• wp(while (B) S, Q) = P0 or P1 or P2 or… Pk
How to Solve the Infinite OR
• Direct approach– Use mathematics to solve the infinite series– Nice if it works, but you have to see the
pattern
• Indirect approach– Prove weak correctness and termination
separately– Use “loop invariant”
Example: Direct Proof
• What is wp(while (i<n) i=i+1, i=n) ?
– H0 : not B and Q• not(i<n) and i=n
• i=n
– H1: B and wp(S, H0)• i<n and wp(i=i+1,i=n)
• i<n and i+1=n
• i+1=n
Direct Proof, continued
– H2: B and wp(S,H1)• i<n and wp(i=i+1,i+1=n)
• i+2=n
– Hk: B and wp(S,Hk-1)• i<n and wp(i=i+1,i+k-1=n)
• i+k=n
• H0 or H1 or H2 or H3 or …
• i=n or i+1=n or i+2=n or … i+k=n …– The above is equivalent to writing i≤n
Loop Invariants (Indirect method)
• A loop invariant is any statement that is true every time a loop executes.
• For example, consider the fragment:i = 1; x = 1;while (i < n ) { x = x * i; i = i + 1;}
• One invariants is: i<n (or the loop ends)
A Loop has Many Invariants
• 3 different invariants for the example loop:– i < n (because the loop will terminate if i ≥ n)
– true (an invariant of every loop)
– x = (i – 1)! (because x started at 1 and has been multiplied by 1, 2, 3 ... i
• This last invariant is most useful: it tells what the loop does.
Using Loop Invariants to Prove Weak Correctness
• Prove P { while B S} Q1. Invariant is true after each time S runs
B and inv {S} inv2. When the loop ends, Q is true
(Not B and inv) -> Q3. Invariant is true before the loop
P -> inv
Example Loop
i = 1 and x = 1 and n > 0 //pre{ while ( i < n ) { x = x * i; i = i + 1; }}x = (n – 1)! //post
• Prove, using inv: 0< i ≤ n and x = (i –1)!
Step 1
• B and inv {S} inv• B and inv is: (i<n) and 0< i ≤ n and x = (i –1)! , or 0<i<n and x=(i-1)!
• Wp(S, inv) is:Wp((x=x*i, i=i+1), 0<i≤n and x=(i-1)!) =Wp(x=x*i, wp(i=i+1, 0<i ≤ n and x=(i-1)!)) = Wp(x=x*i, 0<i+1 ≤ n and x=(i!))0<i+1 ≤ n and x*i = i!-1<i ≤ n-1 and x = (i-1)! (since i is integer, we know that -1< i < n)
• B and inv -> wp(s, inv), so step 1 is complete
Step 2
• Not B and inv -> Q(i>= n) and (0< i ≤ n and x = (i –1)! ) is
i = n and x = (i-1)!x = n-1!
• The above expression is Q, so Step 2 is complete
Step 3
• P -> inv– P is: i=1 and x=1 and n>0– Since n>0 and i=1, 0<I ≤ n– We define 0! = 1. Since x=1 and i=1,
x=(i-1)!
• Both parts of the invariant are proven, so Step 3 is complete
Finding the Invariant
• Invariant is an approximation to the weakest precondition
• Find it by working the loop body backwards, treating inv as a function with loop variables as parameters– Wp(inv(params), S) = B and inv(params)
• Your first guess is often too weak (it’s an invariant but won’t prove the loop)
Example
Find an invariant for the loopwhile (i < n) { i = i + 1; x = x * i;}
Note: the invariant also “explains” the loop
Proving Termination
• Somehow, we need to make an argument that:– The loop ends when B becomes false– Each iteration gets us “closer” to B
becoming false
• Formally, this is done using a “well-founded set”
Well-Founded Set
• An ordered set with a “bottom element”
• Any decreasing sequence in the set must reach the “bottom element” with a finite number of elements
• Examples:– [0-99]– Non-negative integers– Letters of the alphabet (bottom is “a”)
Proving Termination using WFS
• Find a well-founded set such that:– Every loop execution generates an
element of the set (e.g. value of n-I)– If the bottom element is reached, the loop
terminates (e.g. n-I becomes 0 when I=n)– The sequence of values generated through
multiple iterations of the loop is decreasing (e.g. since I gets bigger, n-I gets smaller)
Summary
• Axiomatic semantics allows any program in the language to be proven correct
• In the specification of a language, the weakest precondition for each statement type must be defined
• Loops can be proven directly using an OR of weakest preconditions, or indirectly using an invariant and a separate proof of termination