Program Development by Stepwise Refinement Niklaus Wirth
Motivation Programming is usually taught via examples Examples normally demonstrate what a computer can do Examples are not normally chosen by their suitability for a technique Programming is not just mastering of a language – more important to master the methods of design and construction.
Aim The paper aims to demonstrate the development of an example program through a sequence of refinement steps Today, we refer to this approach as top-down design (or top-down decomposition) The program and data specification are refined in parallel
Refinement Each refinement implies design decisions It is important to make these explicit Be aware of the critieria for the refinement Be aware there are alternatives (after all, this might not work out) Decompose decisions as much as possible Defer decisions about data as long as possible
The 8-Queens Problem Given an 8X8 chessboard and 8 queens which are hostile to each other, find a position for each queen such that no queen may be taken by any other queen. NOTE: Eight-Queens on wikipedia has an animated example of the Recursive solution solving this problem
Brute Force Approach A = Set of candidates for the solution One exists that satisfies condition p Repeat Generate the next element of A and call it x until p(x) OR (no more elements in A) if p(x) then x = solution
Issues Problem space is too large We need a way to preselect solutions Computers at the time would take ~ 7 hrs We need a way to preselect solutions Criteria Smaller than A Elements easily generated Easier to test than p(x)
8-Queens: Unique Columns Every column must have exactly 1 queen Now we are just testing rows and diagonals We also need the ability to “try” a row for a queen and backtrack if the test for the row/diagonal fails.
Program At This Point repeat trycolumn; if safe then setqueen; considernextcolumn; else regress until lastcoldone OR regressoutoffirstcol
Define the Instructions Considerfirstcolumn Considernextcolumn Reconsiderpriorcolumn Advancepointer Testsquare Setqueen removeQueen
Refining the Instructions Upon realizing that we can store the indexes of occupied rows, and thru carefully choosing our array structures, we can reduce the instruction set to: testsquare setqueen regress movequeen
A recursive alternative View the problem as starting with one column Extend the board by one column at each step
Generalizing the Problem We often need to change our program based on new requirements… What if we want ALL possible solutions?
Conclusions Programs are constructed thru a sequence of refinement tasks Each task is decomposed into subtasks The degree of decomposition (modularity) will determine the ease with which we can modify the program
Conclusions Use a notation that is natural for the problem Each refinement implies a design decision, criteria include efficiency, storage, clarity The development of this simple problem formed a long story, programming is not trivial – simplifying the problem is important.