Specifications of Tiny Example Programs
Table of Contents
- 1. Exercises on Tiny Examples
- 2. Mark Errors
- 3. Condense the List of Numbers
- 4. Simple Simultaneous Substitutions
- 5. Game of Tic-Tac-Toe
- 6. Game of Freecell Solitaire
- 7. Specifications of /bin/ls
- 8. The Telegram Problem of Peter Naur
- 9. The Problem of "Tabulate the Equations"
- 10. Pretty Print Java Source Code
- 11. Convert C++ to Java
- 12. The Common Words Problem solved by Knuth
- 13. References
Abstract: We describe how several small example programs can be specified rigorously and unambiguously. [Not all answers are linked here. If you want them, write to me.]
1 Exercises on Tiny Examples
For each of the following informally expressed functions, do two things. (a) Discuss the amibguities, if any, present in the English prose descriptions. (b) Write rigorous and unambiguous {\sl functional specifications}. Remember that the weaker the preconditions, the better the spec is. You can use any of the "well-known" functions. To keep this handout compact, I have dropped the phrase "A function that yields the …" from the beginning of each problem statement.
- second smallest number from the given set of integers.
- sum of two (a) matrices, (b) sets, (c) bags, (d) sequences.
- number of 1's in the binary representation of the given natural number.
- set of all prime factors of a given natural number. Examples: 12 mapsto {2, 3}; 256 mapsto {2}.
- sorted sequence from a given pair of sequences of integers that may or may not be sorted.
- reverse of the given sequence of characters. For example, given "abdbc" return "cbdba".
- value true iff the two sequences of characters are a permutation of each other. Some characters may appear more than once.
- pruned sequence of words, each of which contains at least three different vowels, from the given sequence of words.
- pruned sequence of words that have a prefix (i.e., initial substring) matching the given word. A dictionary of words is global.
- tab-free sequence s of lines from a given sequence t of lines that may contain tabs. Both s and t "look the same when printed". Assume that tab positions are set at every multiple of 8.
- number of white-space "rivers" in a given text file. Assume that the file does not contain tabs. When a text file is printed, rivers are seen as 2-dimensional connected chains of white spaces.
- magic squares of size n x n.
2 Mark Errors
In processing an input line of text, a program we are working on discovered errors. Each error is recorded as a pair \((p, e)\) of numbers. We wish to point to the \(p\)-th character that caused the error, and print the error number \(e\) next to it. Some times a single position in the input line triggers multiple errors. You are given a list of these pairs, and the input line. We need a procedure that prints this line, and the error numbers below it, properly located. Use no more lines than necessary. [An Exercise from Niklaus Wirth, Systematic Programming book, 197x]
Spec by Example 1
error list :(4,1), (7,2), (10, 2), (20, 2), (23, 2). column numbers :1234567890123456789012345 line of text : Thos broplem is peenuds. line of errors : ^1 ^2 ^2 ^2 ^2
Spec by Example 2
error list :(5, 9), (13, 9), (13, 787), (18,94), (18, 126), (25,73), (continued) :(30, 9), (30, 23), (30, 26), (39, 9), (40, 742). column numbers :12345678901234567890123456789012345678901234 line of text : if x > 0 anf y +) then 0 := x else f(x.y) ; line of errors : ^9 ^9 ^94,126^73 ^9,23,26 ^9 line of errors : ^787 ^742
[We can never specify software using examples. But, this is popular because it quickly communicates essential features. Where it typically fails is in the "edge" cases.]
Further details at ../Examples/Mark-Error-Pos
3 Condense the List of Numbers
Consider the informal description, given in the next paragraph, of a program. Give (a) requirements analysis, (b) precise specifications (using logic/discrete mathematics, or in carefully worded English), (c) a design, in pseudo-code.
{You are given a comma separated list of items in a text file. The list is terminated with a period. Each item is either a number, or a hyphen separated pair of numbers. Your program should condense this list as much as possible, as can be seen from the following examples.}
Acceptance Test Examples
1,3,4,2,6,5,8,5,7.
becomes 1-8.
9,100-4870,4993,4871-4875,5016,5118,7-250,5100-5123.
becomes
7-4875,4993,5016,5100-5123.
1103,1023-1100,87654321,1050-1150,1110,1250-1344.
becomes
1023-1150,1250-1344,87654321.
[This is also specifying by examples. This time we are pointing out the use of such things in acceptance tests.]
4 Simple Simultaneous Substitutions
This program should work like a Unix filter. It should translate a sequence of bytes input to it by replacing certain input bytes \(b_i\) by a byte sequence \(s_i\). The replacements required are given in a binary file as a set of ordered pairs \((b_i, s_i)\); it is possible that some \(s_j\) are empty sequences. {\sl You design the detailed format of this binary file.}
Non-Functional Specs: This program is intended to run on a rather primitive machine with a severe shortage of memory. The io operations available are also primitive. The open/close operations are similar to those of Unix, but the read/write primitives can read/write only sequences of bytes exactly 512-bytes long.
int open(const char *filename, char readwritemode)
. The mode char is
r
for reading w
for writing. It returns a filehandle integer.
int close(int filehandle)
.
int readblock(int filehandle, char * buffer)
will read the next
512 bytes (if available) into buffer[]
. If fewer than 512 bytes
are available, the readblock
will pad the buffer with ASCII
NUL characters. It returns the actual number of bytes read.
int writeblock(int filehandle, char * buffer)
will write {\sl the}
512-bytes given in buffer[]
.
5 Game of Tic-Tac-Toe
Specify the game in such a "good" way that someone who has not even heard of this game, but a capable programmer, can program it.
This is adding the complication of state-by-state change.
Read further at ../Examples/TicTacToe-JavaFX-UnRedo/
6 Game of Freecell Solitaire
Specify the game in such a "good" way that someone who has not even heard of this game, but a capable programmer, can program it.
This is adding the complication of state-by-state change.
Read further at ../Examples/Solitaire-FreeCell/
7 Specifications of /bin/ls
This is scaling up one step the size of programs we considered so far.
Consider the Unix standard command /bin/ls
, but invoked without any
arguments or options.
- The notion of Current Working Directory, and its contents.
- Raw Listing of CWD contents.
- Should
/bin/ls
take on the responsibility of "correct" CWD listing? - Columnizing the listing ../Examples/Columnize-Words
8 The Telegram Problem of Peter Naur
- "Write a program that takes a number w, then accepts lines of text and outputs lines of text, where the output lines have as many words as possible but are never longer than w characters. Words may not be split, but you may assume that no single word is too long for a line."
- ../Examples/Telegram-Problem
9 The Problem of "Tabulate the Equations"
- {Our mathematician friend wants a program that can "tabulate" a sequence of symbolic equations found in typical linear algebra into a matrix form.}
- ../Examples/Tabulate-Eqns
10 Pretty Print Java Source Code
- The design and construction of pretty printers is a solved problem
for decades.
- See Mateti ref below.
- indent for C, C++
apt-get install indent
- Builtin pretty printers in Eclipse, Intellij, et al.
- Problem Statement: Take indent, or one of the builtins. Specify.
- Read further at ../Examples/Pretty-Printer
- Mateti, Prabhaker. "A Specification Schema for Indenting Programs." Software: Practice and Experience, vol 13, no. 2 (1983): 163-179. http://onlinelibrary.wiley.com/doi/10.1002/spe.4380130206/abstract Required Reading.
- Mateti, Prabhaker, and Joxan Jaffar. "A Correctness Proof of an Indenting Program." Software: Practice and Experience, vol 13, no. 3 (1983): 199-226. http://onlinelibrary.wiley.com/doi/10.1002/spe.4380130302/abstract Recommended Reading.
11 Convert C++ to Java
- Problem Statement: We have a program P written C++. Compiles and links without errors. May be loaded with bugs. Convert this to Java. Without human intervention. Bug-for-bug equivalent? Must compile free of errors. Use well known C++ and Java libs.
- "Impossible" if we take "all of C++". But, almost all "useful" programs use a rather small subset of C++.
- If the program P is in this subC++, can we translate it to Java?
- Answer is a definite Yes.
- The new problem: Define subC++.
11.1 Defining subC++
- Too expensive in resources to
- Define the subC++ language (grammar, …)
- Write yet another compiler, with good error reporting, for subC++
- Let GNU g++ do its thing
- Parse its error messages to identify C++ usage outside of subC++.
- Generate an Abstract Syntax Tree for P in subC++.
- Traverse this AST, while writing out Java.
- This is just an outline.
12 The Common Words Problem solved by Knuth
- "Given a file of text, and a number k, print the k most common words."
- Used as an example of Literate Programming, the art of preparing programs for human readers. See ../../Design/design-doc.html.
- Our interest here: How to describe its spec + design?
Read further at ../Examples/Knuth-CWP