UP | HOME
../../

Dutch National Flag Problem

1 Prelude

This is a "Correct by Design" example from the book by Dijkstra. This example is used as an early example to illustrate our expectations in using assertions.

2 Problem

An array a[1..n] is filled with elements colored red, white or blue. Design an algorithm that rearranges the elements so that all the red-elements are at the left, all the blues are at the right, and the whites are in the middle.

2.1 Non-functional Requirements

  1. Do not assume that (i) red, white and blue are named integer constants; (ii) nor that red < white < blue.
  2. We are expecting an O(n) algorithm.

2.2 Assertions

Focus on assertions.

3 Specs

We are going to be quite loose, for now, on our notation. Notes on "Assertions 101" has more details.

  1. RWB is a set, RWB ::= {red, white, blue}.
  2. a[x .. y] stands for [a[x], a[x+1], …, a[y]]. If x > y, a[x .. y] is empty.
  3. Is n > 0?
  4. a[i] is-in RWB. For all i. This is known as the entry assertion. Also called a pre-condition.
  5. As bags, original a equals final a. Original a is the array a as the algorithm is entered, final a is the same array a as the algorithm is exited. This is known as the exit assertion. Also called a post-condition.
  6. A bag is similar to a set, but may have duplicates.

4 Implementation

Here is an implementation so that you can relate to our discussion of correct-by-design.

/*@ pre: Exercise */
r = w = 0;
b = n+1;
while
 /*@ LI:: a[1..r] is-red and a[r+1 .. w] is-white and a[b..n] is-blue */
 (w+1 < b) {
  switch (a[w+1]) {
    case white:
      w ++;
      break;
    case red:
      w ++;
      exchange(w, r+1);  // exchange a[w] with a[r+1];
      break;
    case blue:
      b --;
      exchange (w+1, b); // exchange a[w+1] with a[b];
      break;
  }
}
/*@ post::  w+1 == b and a[1..r] is-red and
    a[r+1 .. w] is-white and a[b..n] is-blue */
  1. exchange(i, j) is a method not shown above. Equiv to {temp = a[i]; a[i] = a[j]; a[j] = temp;}
  2. The location of LI is immediately after the "while" token.
  3. The while loop terminates because the b - w gap guaranteedly decreases in every iteration.
  4. Exercise: Explain why/how the LI remains valid after each of the switch-cases.
  5. Exercise: It does have a pre-condition. Left it to you as a simple exercise.
  6. Exercise: Make a complete C++ program out of the above. Include main method, and several tests. Use enumeration to declare the array elements.
  7. Exercise: An enumeration declaration can force that red < white < blue. Can we use sorting to solve this problem?

5 Correct by Design

  1. How do/did we arrive at a/the solution?
  2. "Weaken" the post-condition. Use the weakened post-condition as the loop invariant LI.
    1. From the post, omit w+1 == b

dnf-array.jpg

Figure 1: Illustrated Loop Invariant

  1. In every iteration the LI after each iteration is stronger than what it was before.
    1. Is the white region larger?
    2. Is the red region larger?
    3. Is the blue region larger?
    4. One or more of the above must happen.
    5. The gap b - w should decrease.
  2. Design-by-Contract: Develop code S so that {LI-before} S {LI-after} [And, make sure that Li-before is not equivalent to Li-after.]
  3. Exercise: What is meant by "stronger" in general? E.g., if A implies B, between the two, which is stronger?
  4. Exercise: Correct by design is related to Design by Contract. How? Explain in a short paragraph.

6 References

  1. Dijkstra, Edsger Wybe, A Discipline of Programming, Prentice-Hall, 1976. A classic book. Includes many examples of Correct by Design. Dijkstra is a Turing Award Winner 1972. Reference.
  2. Prabhaker Mateti, Notes on "Correct by Design" ../../Design/correct-by-design.html
  3. Prabhaker Mateti, Notes on "Design by Contract (DbC)" ../../Design/design-by-contract.html
  4. Prabhaker Mateti, Notes on "Assertions 101" ../../Assertions/assertions-101.html

7 End


Copyright © 2020 pmateti@wright.edu www.wright.edu/~pmateti 2020-08-29