0% found this document useful (0 votes)
91 views

Weakest-Precondition Reasoning What Do We Mean by "Weakest"?

The document discusses weakest preconditions (WP) and how they can be used to reason about program correctness. It defines WP as the weakest condition that must be true before a statement for a given post-condition to be true after. Rules are provided for calculating the WP of assignment statements, sequential composition, and conditional (if-then-else) statements. Examples are used to illustrate applying the WP rules and composition property to prove loop invariants.
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
91 views

Weakest-Precondition Reasoning What Do We Mean by "Weakest"?

The document discusses weakest preconditions (WP) and how they can be used to reason about program correctness. It defines WP as the weakest condition that must be true before a statement for a given post-condition to be true after. Rules are provided for calculating the WP of assignment statements, sequential composition, and conditional (if-then-else) statements. Examples are used to illustrate applying the WP rules and composition property to prove loop invariants.
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 18

Weakest-Precondition Reasoning What do we mean by “weakest”?

l If A => B but not (B => A), then B is


l Reference: E.W. Dijkstra, A Discipline of “weaker” than A, and A is “stronger”
Programming, Prentice-Hall, 1976. than B.
l Starting with a post-assertion, what is l The weakest possible predicate is the
the weakest pre-condition that makes one that is identically
the assertion true? true
l In other words, what must be true
since A => true no matter what A is.
before to make the assertion true after? Similarly, the strongest possible
l [WP ^ [test&action] ] → Assertion predicate is
false

WP for an Assignment Statement WP for an Assignment Statement

l Consider the assignment statement l The answer is wp(x = F(ξ);, P) = P(F(ξ))


x = F(ξ); l The general rule is:
where ξ denotes the “state vector” l {P(F(ξ))} x = F(ξ); {P(x)}
(vector of all program variables).
l Examples, where we show the
l This statement is “all action”; the test is assertions within braces, and the wp to
vacuously true. be found as ??:
l If we want P(x) to be true after, what l {??} x = 5; {y > x}
must be true before?
WP for an Assignment Statement WP for an Assignment Statement

l The general rule is:


l Examples:
l {P(F(ξ))} x = F(ξ); {P(x)}
l {??} x = x+y; {y > x}
l Example:
l {y> 5} x = 5; {y > x} l {??} y = 2*y; {y < 5}
l i.e.
if we want y > x to be true after the
assignment x = 5; then we need, at a l {??} y = 2*y; {even(y)}
minimum, y > 5 before the assignment.
l Identify P(x) as y > x, and F (ξ) as 5, in the
rule to get WP: y > 5

WP for an Assignment Statement WP Convention

l Examples: l It is common to include logic simplification in


l {y > x+y} x = x+y; {y > x} the WP expression.
i.e. w p(x = x+y;, y > x) = y > x+y l Example: If working in the domain of integers,
then
l {2*y < 5} y = 2*y; {y < 5} even(2*y)
i.e. w p(y = 2*y;, y < 5) = 2*y < 5 would simplify to
true
while
l {even(2*y)} y = 2*y; {even(y)}
i +1 < n
i.e. w p(y = 2*y;, even(y)) = even(2*y)
would simplify to
i<n
Predicate Transformers Predicates and State Sets

l A program statement can thus be l A program statement can thus be


viewed as a “predicate transformer”, viewed as a “predicate transformer”,
transforming a post-condition into a transforming a post-condition into a
weakest pre-condition. weakest pre-condition.

l But a predicate is just a set of states,


so that WP transforms the set of states
after a statement to a set before.

WP Composition Rule Composition Rule Example

l Suppose we have two statements in a l Consider


sequence: {??} x = z+1; y = x+y; {y > 5}
S; T l wp(y = x+y;, y > 5) = x+y > 5
l The wp for composite obeys the l wp(x = z+1;, x+y > 5) = z+1+y > 5
following equation:
l So ?? is
wp(S; T, P) = wp(S; wp(T, P)) z+1+y > 5
l In other words, predicate transformers
compose in a manner similar to
functions.
Composition Rule Example Composition Rule Example (2)
l Consider the sequence and post-condition
{??} Working backword from
s1 = s1 + s2; {s1=(i+1) 3 s2=(i+2) 3-(i+1) 3 s3 = 6*(i+2)}

s2 = s2 + s3; l w p(s3 = s3 + 6; …) =
{s1=(i+1) 3 s2=(i+2) 3-(i+1) 3 (s3+6) = 6*(i+2)}
s3 = s3 + 6;
i = i+1;
{s1=i 3 s2=(i+1)3-i 3 s3 = 6*(i+1)} l w p(s2 = s2 + s3; …) =
{s1=(i+1) 3 (s2+s3)=(i+2) 3-(i+1) 3 (s3+6) =6*(i+2)}

l Working backward
w p(i=i+1; …) = l w p(s1 = s1+s2; …) =
{s1=(i+1) 3 s2=(i+2) 3-(i+1) 3 s3 = 6*(i+2)} {(s1+s2)=(i+1) 3 (s2+s3)=(i+2) 3-(i+1) 3 (s3+6) =6*(i+2)}

Using the Composition Rule to Prove Example: Using the Composition


a Loop Invariant Rule to Prove a Loop Invariant

l An assertion P is a loop invariant provided l We claim that


{(s1+s2)=(i+1) 3 (s2+s3)=(i+2) 3-(i+1) 3 (s3+6) =6*(i+2)}
that:
l P is true at the start of the loop l is implied by the original post-condition of the
l P => wp(loop-body, P) body:
{s1=i3 s2=(i+1) 3-i3 s3 = 6*(i+1)}

l Assume the latter post-condition. Then


l The second condition above is the same as l s1+s2 = i 3+(i+1) 3-i3
= (i+1) 3
the verification condition for the loop body.
l s2+s3 = (i+1) 3 -i 3 + 6*(i+1)
This equality is not so obvious.
= (i+2) 3-(i+1) 3
l s3+6 = 6*(i+1)+6
= 6*(i+2)
Showing the Non-Obvious Equality WP for a Test

l Show (i+1)3-i 3 + 6*(i+1)= (i+2)3-(i+1)3 l {??} if( Q(ξ) ) S else T {P(ξ)}


l LHS= (i3 + 3i2 + 3i + 1)-i 3 + 6i + 6
l wp(if(Q(ξ)) S else T, P)(ξ) =
= 3i 2 + 9i + 7

l RHS= (i 3 + 6i 2 + 12i+ 8)-(i 3 + 3i 2 + 3i + 1) Q(ξ) → wp(S, P)(ξ) ^


¬Q(ξ) → wp(T, P)(ξ)
= 3i 2 + 9i + 7

WP for a Test - Example WP for a Test - Example (2)

l {??} l {??}
if( x > y ) x = x-y; else y = y-x; if( x > y ) z = x; else z = y;
{gcd(x, y) = z} {z = max(x, y)}

l wp is wp’s of the assignment statements l wp is wp’s of the assignment statements

(x > y) → gcd(x-y, y) = z (x > y) → max(x, y) = x


¬(x > y) → gcd(x, y-x) = z ¬(x > y) → max(x, y) = y
which simplifies to true.
When the else part is missing WP for a Test without else

l If the else part is missing, then T is l {??}


effectively a “no-op” or “skip”: if( x > y ) y = x;
ξ = ξ; {y = max(x, y)}
l The wp is then
¬Q(ξ) → P(ξ) l wp is wp’s of the assignment statements
^ Q(ξ) → wp(S, P)(ξ)
¬(x > y) → y = max(x, y)
l since wp(ξ = ξ; P) = P (x > y) → x = max(x, x)
which simplifies to true.

Alternate WP for a Test Alternate WP for a Test

l wp(if(Q(ξ)) S else T, P)(ξ) = l (Q ^ A) ∨ (¬Q ^ B) =? (Q → A) ^ (¬ Q → B)


l For Q = true, this becomes A =? A.
(Q(ξ) ^ wp(S, P)(ξ)) ∨ l For Q = false, this becomes B =? B
(¬Q(ξ) ^ wp(T, P)(ξ)) l Therefore the two forms are equivalent.
l To see that this is equivalent to the
previous version, let wp(S, P) be A and
wp(T, P) be B. Then we are asking
whether (Q ^ A) ∨ (¬Q ^ B) is equivalent
to (Q → A) ^ (¬Q → B)
WP for a Loop Example: WP for a Loop
l {??} while(Q) S {P} l {??} while(x > 0) x = x -1; {x == 0}
l Consider this to be unrolled to a cascade l WP is
of if’s (without else’s) ¬(x > 0) → x == 0 ^
(x > 0) → [¬(x- 1 > 0) → x- 1 == 0 ^
l if(Q) {S; if(Q) {S; if(Q) {S; … }}}
(x-1 > 0) → [¬(x-2 > 0) → x-2 == 0 ^
l So WP is (x-2 > 0) → [… ]]]
¬Q( ξ) → P( ξ) ^
Q(ξ) → (w p(S, ¬ Q(ξ) → P( ξ) ^
Q(ξ) → (w p(S, …))))
l but this may be difficult to capture in
closed form.

which simplifies to which further simplifies to

l {??} while(x > 0) x = x-1; {x == 0} l {??} while(x > 0) x = x-1; {x == 0}


l WP is l WP is
x≤0 → x == 0 ^ x>0
(x > 0) ^ x ≤ 1 → x == 1 ^ l In other words, the loop will terminate with
(x > 1) ^ x ≤ 2 → x == 2 ^ x == 0 provided that x > 0 initially.
(x > 2) ^ x ≤ 3 → x == 3 ^
...
Recurrence for Loop WP Recurrence for Loop WP

l {??} while(Q) S; {P} l {??} while(Q) S; {P}


can be expressed as the predicate H(P)
= H0(P) ^ H1(P) ^ H2(P) ^ H3(P) ^ … l In particular, the WP H is the weakest
l where predicate satisfying the recurrence:
l H0(P) =¬ Q→ P lH → (¬ Q → P)

l Hk+1(P) = Q → w p(S, Hk(P)) lH → (Q → w p(S, H))

l In this sense, H is like a loop invariant,


but derived from post-conditions.

Example: Recurrence for Loop WP Example: Recurrence for Loop WP

l {??} while(x > 0) x = x-1; {x==0} l {??} while(x > 0) x = x-1; {x==0}
can be expressed as the predicate H(P) l Check that H = x > 0 satisfies the
= H0(x==0) H1(x==0) H2 (x==0) … recurrence:
l where lx > 0 → (¬ x > 0 → x==0)
l H0(x==0) = ¬ x > 0 → x==0 which is valid, and
lx > 0 → (x > 0 → w p(x=x-1;, x > 0))
l Hk+1(x==0) = x > 0 → w p(x=x-1;, Hk(x==0))
l But wp(x=x-1;, x > 0) is x > 1, so we
check
l x > 0 → (x > 0 → x>1), which is true (for integers)
Example: Alternate way to approach WP
Another way to approach WP for a loop for a loop

l wp(while(B) S, Q) l {??} while(x > 0) x = x-1; {x==0}


l (∃k > 0) Hk (Q) can be expressed as the predicate H(P)
l where
= H0(x==0) ∨ H1(x==0) ∨ H2(x==0) ∨ …
l where
l H0(Q) =¬B Q
l Hk+1(Q) = (B w p(S, Hk(Q))) ∨ (¬ B Q) l H0(x==0) =¬x>0 x==0

l Hk+1(x==0) = (x > 0 w p(x=x-1;, Hk(x==0)))


∨ (¬ x > 0 x==0)
l x == 0 ∨ x==1 ∨ x==2 ∨ ...

More on WP for a Loops Practical Example of a Loop WP

l Note that WP for a loop captures total l Consider the java code:
correctness. for( j = 0; j < a.length; j++ )
{
l Since it is generally difficult to derive if( a[j] == v )
WP in a closed form, we may be {
break;
content with finding a pre-condition that }
satisfies the recurrence but is not the }
weakest. assert: a[j] == v

l Such a condition implies the weakest. l What is the weakest pre-condition?


Further Standard Properties of
Practical Example of a Loop WP wp

l The weakest pre-condition is: l wp(S, false) = false


l wp(S, true) = condition under which S terminates
((∃j) (0 < j < a.length) a[j] == v) l wp(skip, Q) = Q
l wp(abort, Q) = false
l If Q → R then wp(S, Q) → wp(S, R)
l wp(S, Q R) = wp(S, Q) wp(S, R)
l wp(S, Q) ∨ wp(S, R) → wp(S, Q ∨ R)
(equality holds for deterministic S)

Structural Induction Structural Induction Proof (1)


l The Structural Induction Principle can also be
used for proving correctness. l Consider the following rex program:
l It generalizes conventional mathematical induction, in l shunt([ ], M) => M;
that it is on the formation of information structures,
such as lists (of which numbers are a special case). l shunt([A | L], M) => shunt(L, [A | M]);
l It has the advantage of proving total correctness in
one single technique. l We want to show:
l ( L)( M) shunt(L, M) returns the M appended to
l It is useful for functional and logic programs in
particular. the reverse of L, i.e.

l It can also be used for proving properties of


l ( L)( M) shunt(L, M) == append(reverse(L), M)
information structures themselves.
Structural Induction Proof (2) Structural Induction Proof (3)

l Show by induction “on L” l We are showing:


( L)( M) shunt(L, M) == append(reverse(L), M) l ( L)( M) shunt(L, M) == append(reverse(L), M)
l Basis: Show it true for L = the empty l Induction step: Assume for an arbitrary list L:
list: l ( M) shunt(L, M) == append(reverse(L), M)
l TBS: ( M) shunt([ ], M) == append(reverse([ ]), M)
l Show it is true for list [A | L], i.e. show:
l From the program, shunt([ ], M) => M. l ( M) shunt([A | L], M) ==
append(reverse([A | L]), M)
l But M == append([ ], M) == append(reverse([ ]), M). QED.

Structural Induction Proof (4) Structural Induction Proof (5)


l To show: append(reverse(L), [A | M] ) ==
l Show ( M) shunt([A | L], M) == append(reverse([A | L]), M).
append(reverse([A | L]), M). l append(reverse(L), [A | M]) =
l From the program, shunt([A | L], M) returns
from definition of append
the result of shunt(L, [A | M]).
l append(reverse(L), append([A], M)) =
l By the inductive hypothesis, this equals
append(reverse(L), [A | M] ), so we need to associativity of append

show l append(append(reverse(L), [A]), M) =


append(reverse(L), [A | M] ) ==
append(reverse([A | L]), M). from definition of reverse

l append(reverse([A | L]), M)
Try to Prove this by
Structural Induction Structural Induction

l ( a)( b)( c) app(app(a, b), c) == l ( a)( b)( c) app(app(a, b), c) ==


app(a, app(b, c)) app(a, app(b, c))
l Induct on a:
l Using the definition of app: l Basis: app(app([], b), c) ==
app([], app(b, c))
app([], b) => b; l By direct evaluation, this reduces to
app([x|a], b) => [x | app(a, b)]; app(b, c) == app(b, c),
which reduces to true.

Structural Induction Structural Induction

l ( a)( b)( c) app(app(a, b), c) == l TBS:app(app(cons(x, a), b), c)


app(a, app(b, c)) == app(cons(x, a), app(b, c))
l Induction Hypothesis: l By two symbolic evaluations, based on the
( b)( c) app(app(a, b), c) == app(a, app(b, definition of app this equation reduces to:
c)) l app(cons(x, app(a, b)), c) == cons(x, app(a,
l Induction Conclusion: app(b, c)))
( b)( c) app(app(cons(x, a), b), c)
== app(cons(x, a), app(b, c))
“Mathematical Induction”
Structural Induction is a special case of Structural Induction

l TBS: app(cons(x, app(a, b)), c) == l Mathematical induction says: “To prove


cons(x, app(a, app(b, c))) a property P for all natural numbers, it
l By one more symbolic evaluations, this suffices to prove:
reduces to:
l P(0)
cons(x, app(app(a, b), c)) ==
cons(x, app(a, app(b, c))) l( n)(P(n) → P(n+1))”
l Using the induction hypothesis, this is an l This is structural induction where
identity. number n+1 is thought to be
“constructed” from n by the +1 operator.

“Strong form of Mathematical Induction” Notes

l To prove a property P for all natural l Those items to which we appealed as


numbers, it suffices to prove: “definitions” on the previous slide could
l( n)( (( m<n)P(m)) → P(n) ) themselves be proved as lemmas using
l The strong form allows use of a structural induction.
stronger induction hypothesis, which l Automated tools such as ACL2 can be
may simplify a proof. used to do this form of proof on a
l The strong form can be derived from the computer.
ordinary form.
Theorem Prover
Overview of ACL2 Use-Case Diagram

l ACL2 = “Applicative Common Lisp 2”


l ACL2 is an interactive theorem prover
based on Lisp and structural induction
l History of ACL2:
l Boyer- Moore Theorem Prover
( Edinborough, PARC, UT Austin)
l Nqthm (Computational Logic Incorporated)
l ACL2 (UT Austin)

Sample Function Definition


ACL2 includes in ACL2

ACL2 !>
l Normal Lisp execution
(defun app (x y)
l Symbolic execution (cond ((endp x) y)
(t (cons (car x)
l Automated theorem proving (app (cdr x) y)))))
l Formalism for admitting axioms to the
system

endp checks for the list being empty


Sample Evaluations Sample Theorem
ACL2 !>(app nil '(x y z))
(X Y Z) This theorem asserts that function app is associative:

ACL2 !>(app '(1 2 3) '(4 5 6 7)) ACL2!>


(1 2 3 4 5 6 7) (defthm associativity-of-app
(equal (app (app a b) c)
(app a (app b c))))
ACL2 !>(app '(a b c d e f g) '(x y z))
(A B C D E F G X Y Z)

ACL2 !>(app (app '(1 2) '(3 4)) '(5 6))


(1 2 3 4 5 6)

This is just what we proved earlier


by Structural Induction ACL2 Theorem Prover Output

l (equal (app (app a b) c) (defthm associativity-of-app


(app a (app b c)))) (equal (app (app a b) c)
(app a (app b c))))
l In other words, Name the formula above *1.
( a)( b)( c) app(app(a, b), c) ==
app(a, app(b, c)) Perhaps we can prove *1 by induction. Three induction schemes are
suggested by this conjecture. Subsumption reduces that number to two.
However, one of these is flawed and so we are left with one viable
candidate.

(continued)
ACL2 Theorem Prover Output Simplification of the Induction Step

We will induct according to a scheme suggested by (APP A B). If we Subgoal *1/2


let (:P A B C) denote *1 above then the induction scheme we'll use
is (IMPLIES (AND (NOT (ENDP A))
(AND (EQUAL (APP (APP (CDR A) B) C)
(IMPLIES (AND (NOT (ENDP A))
(:P (CDR A) B C))
(APP (CDR A) (APP B C))))
(:P A B C)) (EQUAL (APP (APP A B) C)
(IMPLIES (ENDP A) (:P A B C))). (APP A (APP B C)))).
This induction is justified by the same argument used to admit APP,
namely, the measure (ACL2-COUNT A) is decreasing according to the relation
E0-ORD-< (which is known to be well-founded on the domain recognized By the simple :definition ENDP we reduce the conjecture to
by E0-ORDINALP). When applied to the goal at hand the above induction
scheme produces the following two nontautological subgoals.

Simplification of the Induction Step Simplification of the Basis

Subgoal *1/1
Subgoal *1/2' (IMPLIES (ENDP A)
(IMPLIES (AND (CONSP A) (EQUAL (APP (APP A B) C)
(EQUAL (APP (APP (CDR A) B) C) (APP A (APP B C)))).
(APP (CDR A) (APP B C))))
(EQUAL (APP (APP A B) C) By the simple :definition ENDP we reduce the conjecture to
(APP A (APP B C)))).
Subgoal *1/1'
But simplification reduces this to T, using the :definition APP, the (IMPLIES (NOT (CONSP A))
:rewrite rules CDR-CONS and CAR-CONS and primitive type (EQUAL (APP (APP A B) C)
reasoning. (APP A (APP B C)))).

But simplification reduces this to T, using the :definition APP and


primitive type reasoning.
Proof of a Theorem Controlling Rewrites

l Once the theorem is proved, it is saved l The problem with universal application
in the system to be used as a rewrite of a rewrite rule is that it can divert from
rule. the main problem.
l The system will henceforth rewrite l For example, resubmitting the previous
(app (app x y) z) theorem would cause an infinite loop in
as the form of repeated application of the
(app x (app y z)) rule.
l This is not necessarily a good thing. l This can be avoided, as shown next.

Example Use of the Associativity


Avoiding automatic rule application Theorem
(defthm trivial-consequence
(equal (app (app (app (app x1 x2) (app x3 x4)) (app x5 x6)) x7)
(defthm associativity-of-app (app x1 (app (app x2 x3) (app (app x4 x5) (app x 6 x7))))))
(equal (app (app a b) c)
(app a (app b c)))
ACL2 Warning [Subsume] in ( DEFTHM TRIVIAL-CONSEQUENCE ...):
The previously
:rule-classes nil) added rule ASSOCIATIVITY-OF-APP subsumes the newly proposed :REWRITE
rule TRIVIAL-CONSEQUENCE, in the sense that the old rule rewrites a
more general target. Because the new rule will be tried first, it
may nonetheless find application.
Example Use of the Associativity
Theorem ACL2 System Architecture
By the simple :rewrite rule ASSOCIATIVITY-OF-APP we
reduce the conjecture to

Goal'
(EQUAL (APP X1
(APP X2
(APP X3 (APP X4 (APP X5 (APP X6 X7))))))
(APP X1
(APP X2
(APP X3 (APP X4 (APP X5 (APP X6 X7))))))).

But we reduce the conjecture to T, by primitive type


reasoning.

Q.E.D.

You might also like