Chapter 10: Predicates and Programming

10.1 Specifications of Programs


10.2 Reasoning about Assignment

In axiomatic semantics, the meaning of the assignment statement can be defined by saying that it satisfies this Hoare Triple:

{ R[x:=E] } x := E { R }

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

{Q} x:=E {R}  ≡  Q ⟹ R[x:=E]

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).


10.3 Calculating Parts of Assignments

Consider this Hoare Triple in which the right-hand side of an assignment is to be computed:

{P} i,x := i+1,E {P}, where P : x = (+k | 0≤k<i : b[k])

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.


10.4 Conditional Statements (if-else)

Consider the Hoare Triple

{Q} if B then S1 else S2 endif {R}

Proving this reduces to proving these two Hoare Triples:

  1. {Q ∧ B} S1 {R}
  2. {Q ∧ ¬B} S2 {R}
That is, it suffices to show that execution of S1 (respectively, S2) yields a state satisfying R, assuming that it began in a state satisfying both Q and B (respectively, both Q and ¬B).

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

  1. {x≠y ∧ x>y} z:=x {x≠y ∧ z = x max y}
  2. {x≠y ∧ ¬(x>y} z:=y {x≠y ∧ z = x max y}

And we already know how to prove a Hoare Triple whose program component is an assignment command.