>
CS 1323 Honors, Fall 1996

### Individual Project 4

Ecology Simulation

Due Wednesday, October 2, 4:30pm

DELAY: now due Friday, October 4, 4:59pm

• Four projects are described below. Team members listed first on their team's roster must do Project 4A; those listed second, Project 4B; third, Project 4C; fourth, Project 4D. If your team has five members, the member listed last on the roster must do Project 4A, independently of the other team member working on that project.
• Turn in a listing of the Haskell script you write for your project, following the required standards.
• Turn in a session transcript in which you show that your function operates correctly on arguments chosen to demonstrate the function's capabilities.
• Explain (handwritten on the transcript) what aspects of the function's behavior are illustrated by each of your choices of demonstration examples.

### Project 4A

Rabbits eat grass. Coyotes eat rabbits. There's plenty of grass, so coyotes are the primary obstacle to increases in the rabbit population. The coyote population increases with the food supply (rabbits). The following equations simulate the monthly changes in the rabbit population (R) and the coyote population (C).
R[next month] = (1 + i)R - eCR [this month]
C[next month] = (1 - s)C + egRC [this month]
These equations are a simplified form of the Lotka-Volterra model for predator-prey ecologies. The coefficients have the following meaning in the model:

i - fractional increase in rabbit population from births in a month
s - fractional decrease in coyote population from starvation
e - likelihood that a particular coyote will eat a particular rabbit
g - fractional increase in coyote population caused by eating one rabbit

Your task (at long last): Define a function called "rabbitCoyotePopulationTrajectory" that delivers a sequence recording the monthly populations of rabbits and coyotes.

The type of the function will be

rabbitCoyotePopulationTrajectory :: [Float] -> [Float] -> [[Float]]
The first argument of the population function will be the sequence [i, s, e, g] of coefficients prescribing the model. The second argument will be the sequence [R, C], which gives the populations of rabbits and coyotes in the first month. The function delivers the sequence of population figures for successive months, as determined by the equations of the model. Each population figure in this sequence will have the form [R, C], where R and C are the populations of rabbits and coyotes for one of the months in the simulation.

### Project 4B

Define a function called "makeChart" that charts a sequence of points, given the two-dimensional Cartesian coordinates of the points.

The type of the function will be

makeChart :: Char -> Int -> Int -> [[Float]] -> ([Float], [String])
The first argument will be the character to be used to chart the points. The second argument will be the width w of the picture representing the chart, measured in character positions across a line of text. (Read the description of Project 4C to find out what "picture" means, for purposes of this project.) The third argument will be the height h of the picture representing the chart, measured in lines down a page of text. The fourth argument will be the sequence of points. Each point in the fourth argument will be represented by a sequence of two numbers [x, y], giving the horizontal and vertical coordinates of the point.

The function delivers a tuple whose first component is a sequence of four numbers [minH, maxH, minV, maxV], where minH and maxH are the minimum and maximum values among the horizontal coordinates in the fourth argument and minV, maxV and the minimum and maximum values among the vertical coordinates in the fourth argument.

The second component of the tuple delivered by makeChart is a picture, in the sense of Project 4C, representing the sequence of coordinates in the fourth argument. The left border of the picture corresponds to the value minH, the right border to maxH, the top border to minV and the bottom border to maxV. A horizontal coordinate half way between minH and maxH would be represented in the picture by a dot located half way across the picture; vertical coordinates are charted similarly, but down from the top of the picture rather than across.

The exact position of the dot will be computed by the function digitize, which you can acquire from NumericUtilities. To get access to this function, copy the NumericUtilities.lhs file to your file space, and put the directive

import NumericUtilities
at the beginning of your script. Note: You no longer have to worry about loading the script containing the imported functions separately. Hugs chases down the imported files automatically. Just load your script, and the import directive will trigger an automatic load of NumericUtilities.

The invocation

digitize w minH maxH x
converts the horizontal coordinate x to the appropriate character position in the range [0 .. w - 1], where w is the width of the picture. Similarly, the invocation
digitize h minV maxV y
converts the vertical coordinate y to the appropriate line number in the range [0 .. h - 1], where h is the height of the picture.

You will also need to use the function updatePicture, described in Project 4C. I will send you by email a Haskell definition for this function that you can copy into your script. Of course, since some of your classmates will be defining updatePicture as their project, you must not share the definition I send you with any of your classmates.

### Project 4C

Define a function called "updatePicture" that inserts a dot into a picture at a specified point. The type of the function will be
updatePicture :: Char -> [Int] -> [String] -> [String]

The first argument will be the character c to used to mark the new dot in the picture. The second argument will be the coordinates [i, j] of the position of the new dot, where i is the distance from the left border, measured in character positions across a line of text, and j is the distance from the top border, measured in lines down a page of text.

The third argument will be the picture itself in its current form. This will be a sequence of strings. There will be h strings in all, where h is some integer greater than zero. Each string will be a line of text used to represent one horizontal cross-section of the picture. All of the strings in the sequence will be of the same length, w, where w is an integer greater than zero. You may assume that 0 <= i < w and that 0 <= j < h.

The value delivered by update will be identical to its third argument, except that element j in the sequence of strings (numbering the strings from zero up, so that the first string in the sequence is element zero) will have the character c in position i (numbering the positions from zero up, so that the first position in the string is position zero).

### Project 4D

Define a function called "displayChart" that constructs a string which, if printed as text, would exhibit, graphically, the information in a chart delivered by the function makeChart from Project 4C.

The type of your function will be

displayChart :: [String] -> ([Float], [String]) -> String
The first argument will be a sequence [labelH, labelV] of two strings to be used as labels for the horizontal and vertical axes. The second argument is a tuple with the same structure as one that could be delivered by the function makeChart from Project 4B.

The function displayChart delivers a string containing the lines from the picture in the second argument enclosed in a frame of appropriate visible characters and marked with the numeric ranges represented by the horizontal and vertical axes. Optionally, you may also label axes with the labels given in the first argument, but this is not a required characteristic of your function (that is, your function can ignore its first argument if you choose not to display labels on the axes). Take care to reorient the picture so that smaller values along the vertical scale appear at the bottom of the display and larger values at the top.

The display below provides an example to show how a string delivered by displayChart could look when printed. Yours need not look exactly like this, but should communicate the same information in a reasonable way (except that the labels on the axes, Coyotes and Rabbits in the example, are optional and may be omitted).

```50.8894|------------------------------|
|       **** *** *             |
|     **          * *          |
|    *               *         |
|   *                  *       |
|  **                   *      |
|  *                     *     |
| *                        *   |
| *                         *  |
|*                          *  |
|*                           * |
Coyotes|*                            *|
|*                            *|
|*                            *|
|*                            *|
|*                            *|
|*                           **|
|*                          ** |
|** *                     **   |
| ** ***             *****     |
|   ******************         |
4.96911|------------------------------|
|718.247        Rabbits        |3022.52
```

You may want to use one or more of the functions leftJustify, rightJustify, and reps, which you can acquire from SequenceUtilities. To get access to these functions, copy the SequenceUtilities.lhs file to your file space, and put the directive

import SequenceUtilities
at the beginning of your script. Note: You no longer have to worry about loading the script containing the imported functions separately. Hugs chases down the imported files automatically. Just load your script, and the import directive will trigger an automatic load of SequenceUtilities.

Ground Rules

• You may use any aspects of Haskell discussed in Lessons 1-15 of the Haskell text, in class, or in previous projects.
You may also use the function head, which delivers the first element of a non-empty sequence (head will choke on an empty sequence).