Program S, if executed beginning in a state satisfying Q, is guaranteed to terminate in a state satisfying R.We refer to Q as the pre-condition and R as the post-condition.
Technically, because E might not be defined in all states, the precondition should really be dom.'E' ∧ R[x:=E].
Without proof, Gries claims that R[x:=E] is the weakest precondition guaranteeing that execution of x := E will produce a state satisfying R. Let's develop some intuition as to why this is plausible by doing some examples:
In the first example, it is clear that we need x≥0 to ensure that adding two to x yields a state in which x≥2. But x≥0 is equivalent to x+2≥2, which is exactly what you get by evaluating the textual substitution (x≥2)[x:=x+2]. The other two examples are similar.
From the claim that R[x:=E} is the weakest precondition guaranteeing that execution of x:=E yields a state satisfying R, it follows that
In other words, the Hoare Triple {Q} x:=E {R} is valid as long as Q is stronger than (i.e., implies) the weakest predicate that can correctly serve as the precondition in that Hoare Triple.
Example from pp. 182-183: {x>0} x := x+1 {x>1}. To prove it, show x>0 ⟹ (x>1)[x:=x+1].
A more interesting example: {P} x,i := x+b[i],i+1 {P}, where P: x = (+k | 0≤k<i : b[k])
Note that the precondition really needs to be strengthened to say 0≤i<#b. Note use of (8.23) Split off Term!!
Reasoning about sequences of Assignments
You work backwards to compute wp.(x:=E; y:=F).R to get R[y:=F][x:=E].
A good example is to prove that the classic sequence of three assignment statements has the effect of swapping the values of two variables (see bottom of page 185).
We need to find E such that we can prove P ⟹ P[i,x := i+1,E]. So we go about trying to prove it, and in doing so derive a concrete expression for E:
Assume P.
P[i,x := i+1,E] = < defn. of P > (x = (+k | 0≤k<i : b[k]))[i,x := i+1,E] = < textual substitution > E = (+k | 0≤k<i+1 : b[k]) = < (8.23) Split off term > E = (+k | 0≤k<i : b[k]) + b[i] = < assumption P > E = x + b[i]
Strictly speaking, the step in which (8.23) was applied relies upon knowing that i≥0, because if that condition is not satisfied there is no term to split off! Thus, P really needs to include i≥0 as a conjunct.
Consider the Hoare Triple
Proving this reduces to proving these two Hoare Triples:
As an illustration, consider this Hoare Triple.
{x≠y} if x>y then z:=x else z:=y {x≠y ∧ z = x max y}
Proving it reduces to proving
And we already know how to prove a Hoare Triple whose program component is an assignment command.