For assignment, wp(x := E, Q) = Q[x/E]. Substituting x + 3 for x in the postcondition x > 10 gives x + 3 > 10, which simplifies to x > 7. This is the weakest (least restrictive) condition on x before the assignment that guarantees x > 10 afterward.
Question 2 True / False
The weakest precondition is 'weakest' in the sense that any other valid precondition for the same command and postcondition must logically imply it.
TTrue
FFalse
Answer: True
If {P} C {Q} holds for some P, then P implies wp(C, Q). The weakest precondition is the most general — it accepts exactly the set of initial states from which C is guaranteed to establish Q. Any stronger precondition accepts a subset of those states. This is why wp is unique (up to logical equivalence): it is the weakest element in the lattice of valid preconditions.
Question 3 Short Answer
How does the weakest precondition calculus handle sequential composition? Given wp(C2, Q) = R, what is wp(C1; C2, Q)?
Think about your answer, then reveal below.
Model answer: wp(C1; C2, Q) = wp(C1, wp(C2, Q)) = wp(C1, R). You compute the weakest precondition from right to left: first determine what must hold before C2 to get Q, then determine what must hold before C1 to get that intermediate condition.
This right-to-left composition mirrors the backward nature of the entire calculus. For a sequence of n statements, you start with the final postcondition and propagate backward through each statement, producing a chain of intermediate assertions. This mechanical process is what makes wp amenable to automation in verification tools.
Question 4 Short Answer
Why does computing the weakest precondition for a while loop require a loop invariant, breaking the otherwise mechanical nature of the calculus?
Think about your answer, then reveal below.
Model answer: A while loop executes its body an unknown number of times, so there is no fixed formula for unwinding it. The weakest precondition of a loop requires finding an invariant I such that: I implies the postcondition when the loop exits, and I is preserved by each iteration. Finding this invariant is undecidable in general, which is why wp for loops cannot be fully automated without additional human input or heuristic search.
This is the fundamental limitation of mechanical verification. For straight-line code, wp is entirely algorithmic. But loops introduce unbounded computation, and Rice's theorem tells us that non-trivial semantic properties of programs are undecidable. The invariant is the human insight that tames this undecidability — once provided, the rest of the proof proceeds mechanically.