CSC 153 Grinnell College Spring, 2005 Computer Science Fundamentals Laboratory Exercise

# Program Correctness and Program Design

## Goals:

This laboratory exercise provides practice with several elements of program correctness and design:

## Pre- and Post-Conditions

1. State pre-conditions and post-conditions for procedures power, countdown, replicate and square-each-element from the lab on recursion.

2. Add tests of pre-conditions for procedures power and square-each-element from the lab on recursion.

1. Use the error procedure to test pre-conditions.
2. Run a few test cases, some that obey the pre-conditions and some that do not. Describe how processing proceeds in each case.
3. Change the error procedure to the warning to test pre-conditions.
4. Rerun your test cases, and compare the results.

## Husk-and-kernel programming

1. Write a husk-and-kernel version of the `replicate` procedure from the lab on recursion.

2. Write a procedure `sum-of-list` that takes any list of numbers and returns the sum of of the elements of the list. Have the procedure print a warning message if it is given an empty list. (The procedure should return 0 after issuing this warning message.)

3. Define a predicate `author?` that takes one argument and determines whether that argument is a list containing exactly three arguments, the first one a string and the second and third ones integers. (The predicate should return `#t` if all of these conditions are met, `#f` if any one of them is not satisfied.)

## Testing and Debugging

The reading for this lab included the following Scheme definitions. These are reproduced here for easy reference.

```(define longest-on-list
(lambda (ls)
;Pre-condition:  ls is non-empty list of strings
;Post-conditions:  returns error if pre-condition is not met
;                  otherwise, returns the string on ls of longest length

;; Check pre-conditions
(if (or (null? ls)
(not (list-of-strings? ls)))
(error 'longest-on-list
"the argument must be a non-empty list of strings"))

;; Find the longest string on the list.
(longest-on-list-kernel ls)))

(define longest-on-list-kernel
(lambda (ls)
;Pre-condition:  ls is non-empty list of strings
;Post-conditions:  returns the string on ls of longest length
(if (null? (cdr ls))
(car ls)
(longer-string (car ls)
(longest-on-list-kernel (cdr ls))))))
(define longer-string
(lambda (str1 str2)
(if (< (string-length str1) (string-length str2))
str2
str1)))
(define list-of-strings?
(lambda (ls)
;Pre-condition:  none
;Post-condition:  returns #t if ls is a non-empty list of strings
(or (null? ls)
(and (pair? ls)
(string? (car ls))
(list-of-strings? (cdr ls))))))
```
1. Identify tests cases that will cover a full range of situations that might be encountered in executing the longest-on-string procedure.

2. Develop a test plan for the tally-by-parity problem from the lab on recursion.

### Debugging in Chez Scheme

1. Replace define by trace-define in the definition of longest-on-list and longest-on-string-kernel in the code above, and then run several test cases. Describe the output obtained, and explain why it appears.

2. Revise longest-on-list and longest-on-string-kernel so they are defined with define rather than by trace-define. Then edit longer-string, so it is defined with trace-define. Run a few test cases, describe the output obtained, and explain why this output is obtained.

Notes

1. Edsger Dijkstra, ``On the Cruelty of Really Teaching Computer Science,'' Communications of the ACM, Volume 32, Number 12, December 1989, p. 1402.
2. Paragraph modified from Henry M. Walker, The Limits of Computing, Jones and Bartlett, 1994, p. 6.

This document is available on the World Wide Web as

```http://www.math.grin.edu/~walker/courses/153.sp05/labs/lab-correctness.shtml
```