SE 504
Proving Correctness of a sequential composition of commands

The Hoare Triple law for sequential composition (also called catenation) says

{P} S1; S2 {Q}  ≡  there exists a predicate R such that {P} S1 {R} ∧ {R} S2 {Q}

Note that here S1 and S2 represent programs that may themselves be sequential compositions (i.e., they need not be individual commands).

Example 1: Prove {P ∧ k≥0} sum := sum + k; k := k+1 {P}, where P: sum = (+i | 0≤i<k : i).

The rule suggests that we find a prediate R such that both

{P ∧ k≥0} sum := sum + k {R}  and  {R} k := k+1 {P}

Utilizing the Hoare Triple rule for assignment, we have that

{P(k:=k+1)} k := k+1 {P}

Hence, we choose as a candidate for R the predicate P(k:=k+1). This is a good choice not only because it "automatically" validates the second Hoare Triple but also because, being the weakest such predicate that we could have chosen, it maximizes the chances that the first Hoare Triple is valid. (The weaker you make a Hoare Triple's postcondition, the more likely that it is valid.)

It remains only to show that

{P ∧ k≥0} sum := sum + k {R}

By the Hoare Triple rule for assignment, this is equivalent to

[P ∧ k≥0 ⇒ R(sum := sum+k)]

Here is a proof:

  Assume P and k≥0. 

     R(sum := sum + k)

  =     < defn of R >

     P(k:=k+1)(sum := sum + k)

  =     < defn of P >

     (sum = (+i | 0≤i<k : i))(k:=k+1)(sum := sum + k)

  =     < textual substitution >

     (sum = (+i | 0≤i<k+1 : i)(sum := sum + k)

  =     < textual substitution >
   
     sum + k = (+i | 0≤i<k+1 : i)

  =     < split off term (Gries 8.23)  (relying upon assumption
          k≥0 to guarantee that range is non-empty)           >

     sum + k = (+i | 0≤i<k : i) + k

  =     < algebra: subtract k from both sides >

     sum = (+i | 0≤i<k : i)

  =     < assumption P >

     true

Now suppose that we use the wp-approach instead of the Hoare Triple approach. Recall that the relationship between wp and Hoare Triples is

{P} S {Q}  ≡  [P wp.S.Q]

Because our program is a sequential composition of commands, in order to compute its weakest precondition we will make use of the wp sequential composition rule, which is

[wp.(S1;S2).Q  ≡  wp.S1.(wp.S2.Q)]

Here is a proof of [P ∧ k≥0 ⇒ wp.(sum := sum+k; k:=k+1).P]:

  Assume P and k≥0

     wp.(sum := sum+k; k:=k+1).P

  =     < wp sequential composition rule >

     wp.(sum:=sum+k).(wp.(k:=k+1).P)

  =     < wp assignment rule >

     wp.(sum:=sum+k).(P(k:=k+1))

  =     < wp assignment rule >

     P(k:=k+1)(sum:=sum+k)

As this is the second line in the proof above, we simply continue as in that proof.


Example 2: Prove {P: x=X ∧ y=Y} temp := x; x := y; y := temp {Q: x=Y ∧ y=X}.

Following the Hoare Triple approach, first we could parse the program as

(temp := x; x := y); y := temp

suggesting that we seek a predicate R making each of these Hoare Triples valid:

{P} temp := x; x := y; {R}   and   {R} y := temp {Q}

The best choice for R is wp.(y:=temp){Q}, which is (by the wpAL) Q(y := temp). We have that {R} y := temp {Q} is valid. We are left with the problem of proving this Hoare Triple:

{P} temp := x; x := y; {R}

which is itself a sequential composition and hence we need to find R' that validates both

{P} temp := x {R'}   and   {R'} x := y; {R}

Following the same reasoning as before, we choose R' to be wp.(x:=y).R, which is R(x:=y), leaving us with the problem of showing the Hoare Triple {P} temp := x {R'}. By the Hoare Triple Assignment Law (HTAL), this is equivalent to [P ⇒ R'(temp := x)]. Let's prove it:

    Assume P (i.e., x=X ∧ y=Y).

    R'(temp:=x)

=      < defn. of R' >

    R(x:=y)(temp:=x)

=      < defn of R >

    Q(y:=temp)(x:=y)(temp:=x)

=      < defn of Q >

    (x=Y ∧ y=X)(y:=temp)(x:=y)(temp:=x)

=      < textual substitution >

    (x=Y ∧ temp=X)(x:=y)(temp:=x)

=      < textual substitution >

    (y=Y ∧ temp=X)(temp:=x)

=      < textual substitution >

    y=Y ∧ x=X

=      < assumption >

    true

A more streamlined approach would have been to make use of the weakest precondition sequential composition law, which says

[wp.(S1;S2).Q  ≡  wp.S1.(wp.S2.Q)]

Recall the law relating HT's and wp: {P}S{Q} ≡ [P ⇒ wp.S.Q]. The P, S, and Q that interest us at the moment are

P: x=X ∧ y=Y     S: temp := x; x := y; y := temp     Q: x=Y ∧ y=X

So we prove that {P}S{Q} is valid by proving P ⇒ wp.S.Q:

   Assume P (i.e., x=X and y=Y)

     wp.S.Q

  =     < defn of S and Q >

     wp.(temp:=x; x:=y; y:=temp).(x=Y ∧ y=X}

  =     < wp seq. comp. law, with S1 := "temp:=x" and S2 := "x:=y; y:=temp" >

     wp.(temp:=x).(wp.(x:=y; y:=temp).(x=Y ∧ y=X))

  =     < wp seq. comp. law, with S1 := "x:=y" and S2:= "y:=temp" >

     wp.(temp:=x).(wp.(x:=y).(wp.(y:=temp).(x=Y ∧ y=X)))

  =     < wp assignment law >

     wp.(temp:=x).(wp.(x:=y).((x=Y ∧ y=X)(y:=temp)))

  =     < wp assignment law >

     wp.(temp:=x).((x=Y ∧ y=X)(y:=temp)(x:=y))

  =     < wp assignment law >

     (x=Y ∧ y=X)(y:=temp)(x:=y)(temp:=x)

  =     < textual substitution >

     (x=Y ∧ temp=X)(x:=y)(temp:=x)

  =     < textual substitution >

     (y=Y ∧ temp=X)(temp:=x)

  =     < textual substitution >

     y=Y ∧ x=X

  =     < assumption >

     true

We purposely wanted to arrive at the same formula (see 5th one from the bottom) here as in the previous proof. However, we would have obtained a proof with somewhat shorter formulas had we applied textual substitution immediately after each application of wpAL rather than waiting until all three applications of wpAL had been carried out. To demonstrate this, start with the fifth formula in the proof above:

     wp.(temp:=x).(wp.(x:=y).((x=Y ∧ y=X)(y:=temp)))

  =     < textual substitution >

     wp.(temp:=x).(wp.(x:=y).(x=Y ∧ temp=X))

  =     < wp assignment law >

     wp.(temp:=x).((x=Y ∧ temp=X)(x:=y))

  =     < textual substitution >

     wp.(temp:=x).(y=Y ∧ temp=X)

  =     < wp assignment law >

     (y=Y ∧ temp=X)(temp:=x)

  =     < textual substitution >

     y=Y ∧ x=X

  =     < assumption >

     true 

Sequential composition is associative; that is, the program

S1; S2; S3

can be viewed as being either (S1; S2); S3   or   S1; (S2; S3).

In the proof immediately above, we used the latter interpretation. (Notice the instantiations of S1 and S2 in the first step of the proof.) As an exercise, the reader should do the proof using the former interpretation.