Lecture 007

Generating Verification Conditions

Hoare Triple: when we want to prove P \to [\alpha]Q, we often write it as \{P\}\alpha\{Q\}. We assume:

  1. P, Q contain expression, not program. They are formulas of pure arithmetic.
  2. All formulas in \alpha are pure arithmetic.
\begin{array}{ll} \text{Pure Formulas} & P,Q ::= e_1 \le e_2 \mid e_1 = e_2 \mid \ldots \\ &\mid P \land Q \mid P \lor Q \mid P \rightarrow Q \mid P \leftrightarrow Q \mid \neg P \mid \top \mid \bot \\ &\mid \forall x.P(x) \mid \exists x.P(x) \\ \end{array}

Note that while quantifiers are allowed, allowing them might mean that our formulas might not be decidable.

Dynamic monitoring: track memory access and abort if unsafe.

Instrument it with guard: predict whether memory access would be unsafe.

Test: \textbf{ test } P is a program that checks whether P holds. If it does, it does nothing; if it doesn't, it loops forever.

Aborting programs is considered safe, because aborting is actually a well-defined operation that does no harm (except to the running program, but it is its own fault if it tries to execute an unsafe command)

Sandboxing

We can make a program safe by replacing:

Note that \textbf{ test } 0 \leq e < |M|; x := M[e] is different from t := e; \textbf{ test } 0 \leq t < |M|; x:= M[t]. Because we re-evaluated the expression in the first case.

Re-evaluation is fine in terms of correctness, but hurt performance.

Weakest Liberal Precondition

Sufficient Precondition: If P \to [\alpha]Q, then pure formula P is a sufficient precondition.

Liberal Precondition: If P \to [\alpha]Q, then pure formula P is a liberal precondition since we do not need to prove termination (i.e. total correctness).

P is stronger than Q if P \to Q. So the weakest precondition is P = \top (since it says nothing) while the strongest precondition is P = \bot (since it can prove anything).

We use \text{ wlp } \ \alpha \ Q to denote the weakest liberal precondition of \alpha with respect to Q. It has the following properties:

We can see \text{ wlp } \ \alpha \ Q \iff [\alpha]Q, but \text{ wlp } \ \alpha \ Q \neq [\alpha]Q because \text{ wlp } \ \alpha \ Q is a pure formula while [\alpha]Q is not pure.

For loops, we can construct a weakest liberal precondition with respect to the given loop invariants (from programmer).

Verification Conditions: Given a problem P \to [\alpha]Q, we can generate "verification conditions" by computing \text{ wlp } \ \alpha \ Q and then proving P \to \text{ wlp } \ \alpha \ Q. We call P \to \text{ wlp } \ \alpha \ Q the verification condition for proving P \to [\alpha]Q.

WLP for Assignment and Loops

Recall the following needs fresh variables: x' because Q(x') might contain program definitions (e.g. x = x+1), but we don't have such problen with \text{ wlp } since Q is pure.

\begin{array}{ll} \text{ wlp } \ (\alpha ; \beta) \ Q = \text{ wlp } \ \alpha \ (\text{ wlp } \ \beta \ Q) \\ \text{ wlp } \ (x := e) \ Q(x) = Q(e) \\ \text{ wlp } \ (\textbf{ if } P \ \textbf{ then } \ \alpha_1 \ \textbf{ else } \ \alpha_2) \ Q = (P \to \text{ wlp } \ \alpha_1 \ Q) \land (\neg P \to \text{ wlp } \ \alpha_2 \ Q) \\ \text{ wlp } \ (\textbf{ assert } P) \ Q = P \land Q \\ \text{ wlp } \ (\textbf{ test } P) \ Q = P \to Q \\ \end{array}

For loops, let's define white box:

\frac{\cdot \vdash P}{\Gamma \vdash \square P, \Delta} \square R
\omega \models \square P \iff (\forall \nu)(\nu \models P)

Therefore we have

[\textbf{ while }_J \ P \ \alpha]Q \iff J \land \square (J \land P \to [\alpha]J) \land \square (J \land \neg P \to Q)
\text{ wlp } \ (\textbf{ while }_J \ P \ \alpha) \ Q = J \land \square (J \land P \to \text{ wlp } \ \alpha \ J) \land \square (J \land \neg P \to Q)

Note that \square P(x) prevent substitution.

Table of Content