\documentstyle[12pt]{article}
%\documentstyle[dates,doublespace]{article} \setstretch{1.5}
\begin{document}
\newcommand\MySection[1]{{\noindent\large #1}\par}
\newcommand\population{{\tt Population}}
\newcommand\derivative{{\tt Derivative}}
\newcommand\biomass{{\tt Biomass}}
\newcommand\oo{{Object-Oriented}}
\newcommand\oop{{\oo\ Programming}}
\newcommand\OOP{{\sc OOP}}
\newenvironment{refs}{\MySection{References}\begin{list}{}{\leftmargin0.4cm\itemindent-0.4cm}}{\end{list}}
\parskip\baselineskip
\title{\oo\ Ecosystem Modelling}
\author{William Silvert \\
Biological Sciences Branch \\
Habitat Ecology Division \\
Bedford Institute of Oceanography \\
P. O. Box 1006 \\
Dartmouth, Nova Scotia \\
CANADA B2Y 4A2 \\
\\
Submitted to Ecological Modelling}
\date{\candate}
\maketitle
%\newpage
\begin{abstract}
\noindent
\oop\ (\OOP) provides an intuitively natural way
to approach ecosystem modelling.  The basic concepts of \OOP\ are similar
to those underlying the biological sciences, and the techniques used
for dealing with the internal structure of objects are appropriate for
resolving the problems of hierarchical structure that arise in
ecological and other types of complex systems.
Even the structure of \OOP\ ecosystem models has a strong resemblance
to the structure of the systems being modelled.  The relevant principles
of \OOP\ are discussed in an ecological context, and the application of
\OOP\ to ecosystem modelling is illustrated with several
object-oriented models and code segments to show how \OOP\ can simplify
model development and modification.

\end{abstract}

\section{Introduction}

\oop\ (commonly called \OOP) is an approach to
computer programming developed over the past twenty years.  In
principle it may be considered even older; as Haiduk (1989) puts it,
``\oop\ is old in that it represents the evolution of structured
programming methodology.''  \oop\ is based on the idea that programs
should represent the interaction between abstract representations of
real objects rather than the linear sequence of calculations commonly
associated with programming, which is technically referred to as
procedural programming.  The practical implications have been obscured
by the fact that \OOP\ usually involves either specialized languages like
SmallTalk or extensions of relatively unfamiliar languages like C,
which has spawned the object-oriented programming language C++.  An
additional problem is that relatively few object-oriented languages
support the use of floating-point numbers, and hence their use in
modelling has been confined to areas such as discrete event simulation
and queuing theory.  Until recently none of the languages most familiar
to ecologists and ecosystem modellers has offered the features that
object-oriented programming requires.

Recently \OOP\ has become more accessible to ecologists and other
scientists with the availability of object-oriented versions of Pascal,
and the costs of some other languages have fallen to a level that makes
experimentation feasible.  At the same time, the growing body of
\OOP\ literature in relatively non-technical magazines suggests widespread
interest in and acceptance of the object-oriented methodology.

Earlier ecological applications of \OOP\ have focussed on artificial
intelligence models (Saarenma {\it et al.} 1988, Folse {\it et al.} 1989),
although there have been interesting exceptions (Carruthers {\it et al.} 1988,
Sequeira {\it et al.} 1991).  The exploratory modelling on which this paper
is based shows that \OOP\ offers features that are indeed
appropriate for ecosystem modelling.

This paper summarizes some of the main features of \OOP\ as they
pertain to the types of problems common in ecology and illustrates how
they can be implemented with \OOP\ extensions to a procedural language,
specifically Turbo Pascal 5.5 and 6.0 (Borland 1988, 1990).  Part of
the paper deals with how to code a familiar model, the Lotka-Volterra
predator-prey system.  It also shows how even such a simple model
provides a basis for realistic models of red tides and other real-world
ecological problems.

The paper focuses on three major practical themes in ecological
modelling; the representation of individual populations, the
interactions between populations, and the ability to interface
object-oriented models to existing code.
The emphasis is on the use of Pascal with \OOP\ extensions, since this
is the language most likely to be familiar to ecosystem modellers, and 
the limited support for floating point calculations in many \OOP\ 
languages makes them inappropriate for most scientific work.

\section{Features of \oop}

There are many sources for technical information on \OOP; most of the
languages come with extensive documentation and sample programs, and
there is a burgeoning supply of books on most aspects of
object oriented programming.
Unfortunately, books on simulation of continuous
processes with object-oriented languages appear to be rare, although
the situation is rapidly changing (Zeigler 1990).  I shall therefore
discuss the major concepts in the context of some of their obvious
ecological applications.

\subsection{The Structure of \oo\ Models}

In order to appreciate the potential value of \oo\ Modelling
it helps to look at the relationship between models and the ecosystems
they are intended to represent.  Consider the following set of
definitions:

``Ecosystems consist of populations with complex internal dynamics
which interact with each other.  The rules of interaction are
determined by the properties of the populations.

``\oo\ simulation models consist of objects with complex
internal dynamics which interact with each other.  The rules of
interaction are determined by the properties of the objects.

``Procedural simulation models are lists of instructions describing how
variables change with time (Fortran, BASIC and Pascal are examples of
procedural languages).''

From these definitions it is evident that there is a strong
resemblance between \oo\ ecosystem models and the ecosystems
which these models puport to represent.
This leads to the natural question,
``Should the structure of a model reflect the structure of
the system being modelled?''

This is the basic question which this paper tries to answer.

\subsection{What is an Object?}

The central concept of \oop\ is the concept of {\bf class}, which is also
one of the most intuitive and appealing features of \OOP\ from the
viewpoint of the ecologist.  A class describes both the structure of an
object and a set of procedures for initializing and using it.  One
obvious example of a class is the definition of a population, the
basic building block for many ecological models.  Populations are
characterized by variables such as number of members and mean size, and
they also exhibit functions such as growth and reproduction.  Each type
of population can be described by a class.

A great advantage of using classes becomes clear when we introduce the
concept of {\bf inheritance}.  Each type of population is unique, but
there are many overall similarities which we can use to our advantage.
We know that all populations are descended from a common ancestor, and
differences arise as we move down the family tree.  Exactly the same
hierarchical structure holds for \OOP\ classes.  We can treat different
classes of populations as descendants of a common ancestor and need
only add those particular features which have changed within the
context of the model.  In fact, the concept of basing ecosystem models
on a hierarchy of subsystems which inherit some of their properties
from a common ``ancestor'' is not at all new (Goodall 1974).
Furthermore, since classes incorporate both variables and methods,
inheritance of classes can be used to pass on both quantitative
features (such as the number of limbs) and functional information
({\it e. g.}, herbivory).


As a simple example of how class definitions can be used, consider the
following hierarchy based on plant taxonomy (all examples are shown in
a simplified form of Pascal, with type declarations omitted):

\begin{verbatim}
Population = object
   Biomass;
end;

Plant = object(Population)
   r, K; { growth parameters }
end;

Algae = object(Plant)
   Ks; { half-saturation constant for nutrient uptake }
end;
\end{verbatim}
\noindent
Each of these objects has certain attributes associated with it,
including those inherited from its ancestor objects.
A \population\ has only one property, its \biomass.
An object of the {\tt Plant} class has three properties, since it inherits 
\biomass\ and adds two more of its own.  Objects of
the {\tt Algae} class are characterized by four quantities, the {\tt Ks}
(saturation) constant specific to their own class as well as \biomass\ and
the growth parameters {\tt r} and {\tt K} inherited from the other classes.
Furthermore, if we modify one of these classes, we automatically modify
all of its descendants.  For example, if we extend the definition of
\population\ to include the {\em C:N} ratio, then the {\tt Plant}
and {\tt Algae} classes also include this quantity.

\subsection{Hiding the Derivative.}

In order to use these objects in a model based on first-order
differential equations, we need to include the derivative as a variable
in the class definitions.  It is easy to redefine \population\ as
\begin{verbatim}
Population = object
   Biomass;
   Derivative;
end;
\end{verbatim}
\noindent
and the new variable \derivative\ automatically becomes inherited by the
{\tt Plant} and {\tt Algae} classes.  However, the derivative is a
different kind of variable from the biomass; it represents an abstract
concept that cannot be measured directly, and it should not appear
within the model code outside of the place where it is calculated and
passed on to the integration routine.

In \oop\ it is possible to {\bf hide} a variable so that it cannot be
accessed outside an object.  Instead one defines {\bf methods} that can
be used to manipulate the hidden, or {\bf private}, variable.
For example, we could expand the definition of \population\ to be
\begin{verbatim}
Population = object
   Biomass;
   procedure Initialize;
private
   Derivative;
end;
\end{verbatim}
\noindent
where the call to {\tt Initialize} sets \derivative\ to zero, but it
would not be possible for the user to write \verb"Derivative := 0;"
directly.

The advantage of hiding \derivative\ becomes evident when we look at
a model of the form $dx/dt=A+B+\cdots$ where the various terms $A$,
$B$, and so on correspond to different processes which properly belong
in different modules.  In order to break this single equation into
expressions appearing in different modules, we need to calculate the
total derivative by a series of incremental additions of the form
\verb"Derivative := Derivative + A;" which can appear in the different
modules.  This concept of a ``distributed derivative'' (Silvert 199x)
can lead to problems which can be avoided by the use of
suitable class definitions.
For example, a common error is to write \verb"Derivative := A;",
which ignores any terms that may already have been added to the
derivative.  This can be avoided by making it impossible to change the
\derivative\ by any method other than one specially defined as part of
the class.

In systems of differential equations it is difficult to identify a
single class definition that will work for all models because the
handling of derivative terms is dependent on the integration algorithm
used, and many numerical methods require that the derivatives be copied
into a linear array ({\it e. g.}, Press {\it et. al.} 1986).
Therefore a compromise approach is used in this paper, with a
\population\ class defined as follows:

\begin{verbatim}
Population = object { this is the base class }
   Public
      procedure Change(Amount);     { increment Derivative }  
      procedure SetMass(Amount);    { set Biomass }
      function GetBiomass: Real;
      function GetDerivative;       { returns Derivative }
   Private
      Biomass;                      { variable }
      Derivative;                   { variable }
end
\end{verbatim}
\noindent
(this example follows a mixture of Pascal and C++ style,
and {\tt Real} declarations have been omitted).
The variables \biomass\ and \derivative\ cannot be accessed
directly, but their values can be read and changed by public methods
associated with the class.  However, the only methods which should
appear within biological subroutines are {\tt Change} (to add a term
to \derivative\ and {\tt GetBiomass} (to find out what the biomass
is).  The other methods, {\tt SetMass} and {\tt GetDerivative},
are only used by the initialization and integration procedures.
These should actually be private methods, but it is cumbersome to 
implement this, so they have been left public for clarity.

We can define `{\tt Calanus}' to be a variable of type \population\ in
the same way that, for example, we define `{\tt Count}' to be a
variable of type {\tt Integer}.  {\tt Calanus} is then called an {\bf
instance} of the \population\ class.  However, because a class
definition is in general much more complex than the more traditional
type declarations (such as {\tt Integer}, {\tt Real}, and {\tt
String}), we access the constituent parts of a class object
differently;  if we want to use the biomass of the Calanus population
as {\tt Calanus.Biomass}.  We cannot access \derivative\ directly,
since it is a private variable and can only be used by the methods of
the \population\ class; the only way to change its value is by
using the procedure {\tt Change}, as in the expression ``{\tt
Calanus.Change(r*Calanus.GetBiomass)}'', which corresponds to
exponential growth.  (The procedure {\tt SetMass} sets
\derivative\ to zero, as will be discussed later, but this procedure should
only be used by the initialization and integration routines.)

To provide a fuller illustration of \oop, Appendix A
contains an object-oriented model corresponding to the familiar
Lotka-Volterra model of a predator-prey system given by the equations:

\begin{eqnarray}
         dx/dt = rx - fxy \nonumber \\
         dy/dt = fxy - Zy \nonumber
\end{eqnarray}
\noindent
where $x$ and $y$ are respectively the prey and predator
biomasses, $r$ is the intrinsic growth rate of the prey, $Z$
the mortality of the predator, and $f$ an interaction coefficient
giving the feeding rate of the predator on the prey.  The predator and
prey represent different populations, and in this simple model they are
characterized by biomasses and their derivatives.  The two populations
are functionally different -- for example, the predator is subject
to a constant natural mortality, but we ignore any mortality of the
prey other than that due to grazing.

In separating this model into separate predator and prey modules we have
to take into account that some of the terms can be easily identified
with one or the other population; the terms $rx$ and $-Zy$ represent
intrinsic properties of the prey and predator populations respectively,
but the $fxy$ feeding term links the two populations.

In a language like Turbo Pascal, the class definitions appear as follows
(this is not complete Pascal; type declarations and other parts of
the code have been omitted for brevity, and the \biomass\ and
\derivative\ variables are treated as {\bf public}\footnote{This code
is compatible with Turbo Pascal 5.5, which does not support the
{\tt private} keyword}):

\begin{verbatim}
Population = object                { this is the base class }
   Biomass, Derivative;            { variables }
   procedure SetMass(NewValue);    { method for setting Biomass }
   procedure Change(Amount);       { increment the Derivative }  
   procedure Grow;                 { redefined for each class }
end;

Prey = object(Population)          { descendant class }
   r;                              { growth parameter }
   procedure Grow;                 { redefined for each class }
end;

Predator = object(Population)      { descendant class }
   f, Z;                           { grazing and mortality }
   procedure Grow;                 { redefined for each class }
   procedure Eat(var Victim: Prey);
end;

{ Specify the methods associated with these classes }
procedure Population.SetMass(NewValue);
begin
   Biomass := NewValue;
   Derivative := 0.0;
end;

procedure Population.Change(Amount);
begin
   Derivative := Derivative + Amount;
end;

procedure Population.Grow;
begin
end;

procedure Prey.Grow;
begin
   Change(r * Biomass);
end;

procedure Predator.Grow;
begin
   Change(-Mortality * Biomass);
end;

procedure Predator.Eat(var Victim: Prey);
begin
   Victim.Change(-Appetite * Biomass * Victim.Biomass);
   Change(Efficiency * Appetite * Biomass * Victim.Biomass);
end;
\end{verbatim}

This sample of code uses three classes of objects; the basic {\tt
Population} class and two derived classes, {\tt Prey} and {\tt
Predator}.  These inherit all of the attributes assigned to {\tt
Population}, namely the variables \biomass\ and \derivative\ as
well as the {\tt SetMass} and {\tt Change} routines.  The {\tt
Population} class also defines a dummy {\tt Grow} procedure, and in the
{\tt Prey} and {\tt Predator} classes this is redefined in a way that
calculates the net growth of the biomass and assigns this value to the
\derivative\ term.  Both the {\tt Prey} and {\tt Predator} classes
include their own variables as well as the two inherited from the {\tt
Population} class, they each redefine the {\tt Grow} procedure, and the
{\tt Predator} class incorporates an additional {\tt Eat} procedure.

The {\tt Change} procedure makes it possible to decompose the system
dynamics by distributing the derivative terms, as described above.  A
differential equation of the form $dx/dt=a+b+c+\cdots$ is equivalent to
the series of calls {\tt x.SetMass; x.Change(a); x.Change(b);
x.Change(c); $\cdots$}, but each of the invocations of {\tt x.Change}
can occur in a different procedure.  This makes it possible to break
the code into distinct modules which can be worked on by different
groups of programmers and scientists (Holling 1978, Walters 1986).
This approach seems to have been ignored in the simulation literature,
but it is widely used by ecosystem modellers; for example, the {\tt
SOURCE} terms in the sample code from Baretta and Ruardij (1988) are
distributed between different subroutines in this fashion.

Inheritance provides a powerful tool for generalizing models.  The
Lotka-Volterra model describes populations in terms of their
biomasses.  Generalizing the model to include additional
characteristics like organism size would normally involve a fair amount
of recoding if it were constructed with a procedural language.
However, if we simply add the variable {\tt Size} to the definition of
the \population\ class it automatically becomes inherited by the
{\tt Prey} and {\tt Predator} classes.  The ability to modify and
reuse code in this very simple way is one of the great advantages of \oop.

Of course, the fact that we add {\tt Size} to the definition of the
\population\ class does not do us any good until we use this new variable
in our calculations.  This is one of the reasons why the definition of
class includes not only variables, but also the methods associated with
these variables.  In fact, one of the basic principles of \oop\ is that
the internal variables associated with a class should be accessible
only through the methods associated with that class.  This principle,
called {\bf encapsulation} or {\bf data hiding}, may sound like a
hindrance at first, but it is central to the efficient use of \oop.

To illustrate this point, consider some possible modifications to make
the model more realistic.  By working within the class definitions we
may need few if any changes to the rest of the model code.  We could
for example specify that the prey population consists of a plant with a
finite carrying capacity {\tt K}, as defined in the logistic equation.  To do
this we add the code:

\begin{verbatim}
Plant = object(Prey)
   K;   { add the variable K }
   procedure Grow; { new method }
end;

procedure Plant.Grow;
   Change(r * Biomass * (1 - Biomass / K));
end;
\end{verbatim}
\noindent
where the \biomass\ term in the {\tt Grow} procedure is inherited
from the original definition of \population.

Our model now contains several different versions of the {\tt Grow}
routine, including the exponential {\tt Prey.Grow} procedure and the
logistic {\tt Plant.Grow}.  If we did not redefine growth in the
definition of the {\tt Plant} class, the method would be inherited from
the ancestor class {\tt Prey}.  However, we can {\bf override} any of
the existing methods by simply redefining them, so the new definition
of growth is the one that is used.  This flexibility lets us refine the
model as we build new classes.  The ability to identify a single method
which has different implementations for different classes is called
{\bf polymorphism} and is one of the features of \oop\ which is
particularly useful in ecological modelling.  It means that we can use
the fact that every population is represented by a class that includes
a {\tt Grow} procedure without knowing the precise details of how
growth is calculated, and it means that changes in the {\tt Grow}
procedure for certain classes, that is to say changes in the
representation of the physiology of individual populations, do not
require changes in the overall structure of the ecological model.


This is the point at which the concept of hierarchy naturally arises.
One of the great difficulties in ecosystem modelling, as in any type of
modelling of hierarchical systems, is that it is difficult to draw the
line between processes relevant to the model and those which operate on
different levels and cannot reasonably be included.  The Lotka-Volterra
model is an ecosystem-level model, and it is confusing to
try to incorporate details about the physiology of the component
populations, the biochemical process going on in their internal organs,
the molecular dynamics underlying these processes, and so on.
\OOP\ offers a mechanism that lets us {\bf hide} this more detailed
information in the internal description of objects, so that we can use
it without having to describe it explicitly in our models.

\section{Inheritance}

To illustrate the \OOP\ principle of inheritance and how it facilitates
the reuse of code, consider the development of a model of red tides,
such as those caused by the toxic dinoflagellates {\it Gonyaulax} spp.
In describing the Lotka-Volterra model we have developed four classes
of objects, \population\ and the subclasses {\tt Predator}, {\tt
Plant}, and {\tt Prey}.  We can extend these definitions by adding
further properties such as size, lipid content, and any other variables
of interest.  If we know at the outset that we are only going to model
{\it Gonyaulax} blooms we can proceed directly to a comprehensive class
definition, but in most cases we develop models from simpler and more
general examples like the Lotka-Volterra model shown above.

We can proceed by describing first plants, then algae, and
then dinoflagellates.  At each stage we want to add or modify
information appropriate to the level of description.  This involves the
principles of {\bf inheritance} and {\bf overriding}.  A simplified
block of Pascal declarations for this might be:

\begin{verbatim}
Population = object
   Biomass, Derivative;
   procedure Initialize; { set parameter values }
   procedure SetMass(NewValue);
   procedure Change(Amount);
   procedure Grow;  
end;

Plant = object(Population)
   r, K;
   procedure Initialize(Set_r, Set_K);
   procedure Grow;  
end;

Algae = object(Plant)
   Ks;
   procedure Initialize(Set_r, Set_K, Set_Ks);
   procedure Grow;  
end;

Dinoflagellate = object(Algae)
   Cysts;
   procedure Initialize(Set_r, Set_K, Set_Ks, Encyst);
   procedure Explode;  
   procedure Grow;  
end;
\end{verbatim}
\noindent
This gives us a hierarchy of four classes, each based on the one above it.
{\tt Plant}s include two parameters beyond those shared by all
populations, namely an intrinsic growth rate {\tt r} and a carrying
capacity {\tt K}.  {\tt Algae} share these properties but also have a
nutrient limitation characterized by a half-saturation constant {\tt Ks}.
This is why {\tt Grow} is redefined in the {\tt Algae} class.
Dinoflagellates include an {\tt Explode} procedure which corresponds to
the appearance of new cells arising from dormant cysts, but in all
other respects they behave like other algae (at least in this
formulation).

The various properties of {\tt Dinoflagellate}s are inherited from the
nearest ancestor class for which these properties are declared.  Thus
the \biomass\ variable is a basic property of all {\tt
Populations}, but the {\tt r} and {\tt K} parameters are associated
only with plants and their descendants, and the nutrient limitation
term comes from {\tt Algae}.  The same is true of the methods
associated with each class:  each class has a special initialization
procedure {\tt Initialize}, but the {\tt Initialize} procedure for the
Dinoflagellate class is inherited from the {\tt Algae} class.  The
procedure {\tt SetMass}, which changes the \biomass\ for
initialization and for integration, is a method inherited all the way
back from the \population\ class.

In some cases we need to change a method that was defined in an
ancestor class.  For example, the {\tt Grow} procedure is different for
{\tt Plant}s, where it depends on {\tt r} and {\tt K}, than for {\tt Algae},
where it also depends on {\tt Ks}.  In this case the new definitions
override the old ones.  This very important feature of \oop\ makes it
possible to combine inheritance with a high degree of flexibility.

It is possible to use inheritance in defining methods.  The
initialization procedures for these classes can be defined as follows:

\begin{verbatim}
procedure Population.Initialize;
begin
   Derivative := 0.0;
end;

procedure Plant.Initialize(Set_r, Set_K);
begin
   Population.Initialize;
   r := Set_r;
   K := Set_K;  
end;

procedure Algae.Initialize(Set_r, Set_K, Set_Ks);  
begin
   Plant.Initialize(Set_r, Set_K);
   Ks := Set_Ks;  
end;

procedure Dinoflagellate.Initialize(Set_r, Set_K, Set_Ks, Encyst);  
begin
   Algae.Initialize(Set_r, Set_K, Set_Ks);
   Cysts := Encyst;
end;
\end{verbatim}

\noindent

One of the advantages of inheritance
is that changing an inherited method automatically changes all of the
classes that inherit that method.  Thus if we add some initialization
code to the definition of {\tt Population.Initialize} it automatically
gets passed on to the descendant classes.

One feature of \oop\ that seems most directly applicable to
ecological modelling is the convenient way it offers to deal with the
problem of growing biological diversity in models.  Most modelling
projects start off with a small set of key populations or more highly
aggregated taxonomic groups, but the models become more complicated as
more and more populations groupings and other details are introduced.

In some cases, different populations can be treated as distinct {\bf
instances} of a single class.  We can for example treat both of the
phytoplankters {\tt Gonyaulax} and {\tt Nitzschia} as instances of the
{\tt Algae} class, having the same qualitative description but different
parameter values (the parameters refer to such quantities as growth
rate, nutrient requirements, etc.).  The code for defining these two
types would simply be:
\begin{verbatim}
var Gonyaulax: Algae;
var Nitzschia: Algae;
\end{verbatim}
\noindent
However, we can expand the definition of {\tt Gonyaulax} by changing the
definition to {\tt var Gonyaulax: Dinoflagellate;}, and this change
involves virtually no modification of the code other than initializing
the value of {\tt Gonyaulax.Cysts}.
The elegance of using inheritance to define these classes is
that the above definitions remain valid even if we refine the
description of the underlying {\tt Algae} class.

\section{Writing Code with Objects}

Although the class definitions required by \oop\ may seem to complicate
programming, the fact that these classes include their own
methods is an important aid to program development.  For example, here
is a section of code that integrates (in a very simple way) the
population dynamics of {\it Gonyaulax}, declared as a variable of type {\tt
Dinoflagellate}, and {\it Nitzschia}, declared as type {\tt Algae}
({\it Nitzschia} is a diatom).  In the program we begin by defining
{\tt Gonyaulax} and {\tt Nitzschia} to be variables of type
{\tt Dinoflagellate} and {\tt Algae} respectively, just as we
define {\tt Time} to be an integer and {\tt Step} a real variable
(in preceding code examples these type declarations were omitted for
simplicity).

\begin{verbatim}
var Gonyaulax: Dinoflagellate;
    Nitzschia: Algae;
    Time: Integer; Step: Real;

Gonyaulax.Initialize(2, 50, 0.5, 4.8); { population parameters }
Nitzschia.Initialize(4, 30, 0.2)     ; { population parameters }
Gonyaulax.SetMass(20);  { initial value }
Nitzschia.SetMass(30);  { initial value }
for Time := 1 to 20 do begin
   Gonyaulax.Grow; Gonyaulax.Explode;
   Nitzschia.Grow;
   Gonyaulax.SetMass(Gonyaulax.Biomass + Gonyaulax.Derivative * Step);
   Nitzschia.SetMass(Nitzschia.Biomass + Nitzschia.Derivative * Step);
end;
\end{verbatim}
\noindent
Note that the {\tt Initialize} procedures take different parameter
lists, because they are associated with different class defintions,
and the {\tt Explode} procedure is defined for {\tt Gonyaulax} but
not for {\tt Nitzschia}.
The methods used are those defined in the following classes:

\begin{center}
\begin{tabular}{|l|l|} \hline
Method & Class \\ \hline
\tt Initialize, SetMass, Change & \tt Population \\
\tt Grow & \tt Algae \\
\tt Explode & \tt Dinoflagellate \\ \hline
\end{tabular}
\end{center}

The difference between object-oriented modelling and the more familiar
procedural modelling with which we are all acquainted is that objects,
once defined, develop according to the methods associated with them,
while in procedural modelling we are constantly deciding what to do
with our state variables.  The \oop\ approach seems very close to what
goes on in real ecosystems.


\section{Modelling Interactions}


So far the emphasis in this paper has been on modelling individual
populations, and this is the area where object-oriented methods appear
to be most effective.  However, an equally important aspect of
modelling is the treatment of interactions, which can be very complex
nonlinear phenomena.  In developing the models on which this paper is
based, several alternate approaches were taken to the modelling of
interactions.


The most straightforward way to translate the Lotka-Volterra equations
into object-oriented code would be to represent the system of
differential equations by code which is almost the same
as what one might write in ordinary Pascal; the following example
represents a model of marine herbivory (in order to keep the model and
terminology simple, zooplankton are ignored):

\begin{verbatim}
var Plankton: Plant; Fish: Animal;

procedure Interact;
var Consume: Real;
begin
   Consume := Fish.Appetite * Fish.Biomass * Plankton.Biomass;
   Plankton.Derivative := Plankton.Growth * Plankton.Biomass - Consume;
   Fish.Derivative := Fish.Efficiency * Consume -
                       Fish.Mortality * Fish.Biomass;
end;
\end{verbatim}
\noindent
Unfortunately, any advantages of object-oriented programming evaporate
if we write interactions in this cumbersome way!  There are however 
better ways to model interactions.

It is best to think of ecological models not as systems of differential
equations, but as representations of different processes; the
differential equations represent the cumulative effects of these
processes, but the processes themselves do not have to be lumped into
the same equation.  It is therefore possible to associate the various
interactions with different classes and to calculate the derivatives as
sums of terms calculated in different processes.  This is what has been
done in the code described earlier; with each population we associate
an intrinsic rate of growth, which is given by the {\tt Grow} method
associated with each class.  In addition, the {\tt Animal} class has a
procedure called {\tt Eat} which describes its feeding behaviour.  Given a
prey population such as {\tt Plankton}, the call {\tt Fish.Eat(Plankton)}
computes the changes in both the {\tt Fish} and the {\tt Plankton}
populations and adds these changes to the respective derivative terms.

One approach that seems promising is to make interactions part of the
methods of one of the interacting populations.  For example, in the
Lotka-Volterra model described above, the predator knows how to feed on
a prey population (the procedure {\tt Predator.Eat}), and the program
generates the feeding interaction with the command {\tt
Fish.Eat(Plankton)}.  This can be extended by including in the predator
class a list of prey populations, and by including in the {\tt Grow}
procedure a process of going through this list, evaluating the
biomasses of the various prey and consuming them.  An implementation of
this approach which can easily be extended to more than two populations
is described in detail in Appendix A.  It is consistent with the idea
that programs should not consist of lengthy procedures for manipulating
the internal variables of objects, but rather than objects should be
sent messages that tell them to use their internal methods to operate
on these variables; as Thomas (1989) puts it, ``Future programming
systems will be based on the concepts of object and message.''  One way
of viewing this is by observing that it is not the responsibility of
the modeller to feed {\tt Plankton} to {\tt Fish;} once the behaviour
of {\tt Fish} has been coded into their class description, {\tt Fish}
should know how to do their own grazing!

\section{Integration Procedures}

The problem of integrating the equations of motion of a model is
closely related to the modelling of interactions.  In the
{\it Gonyaulax-Nitzschia}
population dynamics example above a single population was integrated
over time, but in ecological problems the entire system of equations
for the interacting community has to be integrated, and this cannot be
done by integrating each population separately.

This is best done by interfacing the model to well-tested numerical
methods, which need not be written in object-oriented code to be
useful.  Fortunately, languages like Turbo Pascal and C++ can easily be
interfaced to existing numerical methods, such as those described in
Press {\it et al.} (1986, 1988).  For example, their
%4\raise.5ex\hbox{th}-order
4\th{}-order
Runge-Kutta integration subroutine RK4 can
easily be interfaced to an object-oriented ecosystem model by simply
copying the biomasses and derivatives into arrays which can be passed
to the integration subroutine.  An implementation of this approach is
illustrated in the example in Appendix A.

The approach to integrating equations of motion represented by the
above code and by the example in Appendix A is basically the same as
that used in simulation packages that emphasized structured programming
and modular code, such as BSIM\footnote{The BSIM package is a
set of Fortran programs and code developed at the former Marine Ecology
Laboratory in 1982.  Further information is available from the author.}.
Expressed in \OOP\ terminology, the procedure is as follows:

\begin{enumerate}
\item
For each object, set \derivative\ to zero.  This is included in the
procedure {\tt SetMass}, which is defined for the \population\ class
and inherited by all descendant classes.

\item
Send the message {\tt Grow} to each object.  The objects then either modify
their own derivatives or, in the case of interactions, send messages to
other objects to modify their derivatives.  For example, the procedure
{\tt Fish.Grow} could invoke the procedure {\tt Eat(Plankton)}, which would
contribute to the \derivative\ term for {\tt Fish} but would also send the
message {\tt Plankton.Change(-Consume)} which would tell {\tt Plankton} to subtract
{\tt Consume} from its \derivative.

\item
Copy the \derivative\ terms into a vector which can be passed to an
integration routine.  This information, along with a population vector
copied from the \biomass\ terms, can be used to calculate a new
population vector at the end of the specified timestep.

\item
Copy the new population vector back into the object \biomass es.
This is also done by {\tt SetMass}, so actually steps
1 and 4 are the same.  \end{enumerate}

\section{Maintaining and Updating \oo\ Models}

One of the most useful features of \oop\ is the ease with which major
changes in models can be introduced with a minimum of recoding.  For
example, suppose that we want to modify the {\it Gonyaulax-Nitzschia}
model by testing
whether the environmental conditions are suitable.  To keep things
simple, we assume that all populations have a temperature range outside
which they perish immediately.  We can incorporate this in our model by
including two new variables in the definition of the \population\ class,
{\tt Tmin} and {\tt Tmax}, adding a function to set these parameters, and
redefining the {\tt SetMass} procedure:

\begin{verbatim}
procedure Population.Niche(Low, High);  
begin
   Tmin := Low;
   Tmax := High;  
end;

procedure Population.SetMass(NewValue);  
begin
   if (Tmin < Temp) and (Temp < Tmax) then
      Biomass := NewValue;
   else
      Biomass := 0;  
end;
\end{verbatim}
\noindent
Since the {\tt SetMass} method is the only way we have to change 
\biomass\ (in a language which offered strict encapsulation this would be
guaranteed), this ensures that all populations vanish as soon as the
temperature goes outside their range of viability.  Of course we have
to use the {\tt Niche} procedure to initialize the temperature range
for all populations actually used in the model, but this is
straightforward.

We can introduce changes like this at any level in the chain of
inheritance -- we could for example override the definition of {\tt
Niche} and {\tt SetMass} for the class {\tt Plant} and all of its
descendants to include a minimum light level.


\section{Disadvantages of \oop}


A strong case can be made for \oop\ as a vehicle for ecosystem
modelling, but there are disadvantages as well as advantages to be
considered.  \OOP\ has not reached the level of optimization of
traditional languages, so the development of large \OOP\ models may not
yet be feasible.  There is much technical expertise and well-tested
code written in traditional languages that will need to be rewritten
and verified before it can be used for object-oriented modelling.


There are definite benefits to the use of classes for modelling
populations, but it is not yet clear whether the modelling of
interactions between populations is likely to be helped or hindered by
using object-oriented methods.  As Guthery (1989), one of the more
vociferous opponents of \oop, points out, ``Object-oriented programming
makes building code fragments easier, but it makes integration much
more difficult.''  In ecology, where the objects being modelled are
complex organisms with many hierarchical levels of internal processes,
the benefits of encapsulating this complexity within a class structure
is likely to outweigh the difficulty of modelling interactions, but
there is a tradeoff involved in object oriented modelling which must be
recognized (these tradeoffs are discussed in greater detail in Sydow 1982).

In the immediate future these disadvantages may outweigh the
advantages of using \oop\ to develop ecosystem models, especially
large ones where the inefficiency of currently available compilers may
be the critical deciding factor.  However these are likely to prove to
be only temporary concerns.

\section{Omissions}

There are many properties of \oop\ that I have not attempted to cover in
this brief introduction, including technical but useful features such
as constructors, destructors, and the distinction between early and
late binding (virtual methods).  It should also be noted that not all
languages offer a complete implementation of \OOP\ principles; for
example, neither Turbo Pascal nor QuickPascal have true {\bf
encapsulation}, since their definitions of {\bf object} are based
directly on the definition of a Pascal record.  This introduces a risk
of inadvertently changing some of the hidden variables associated with
the class.  In more fully implemented \oop\ languages like C++ the only
variables and methods which can be accessed outside the class itself
are those explicitly declared {\bf public}.

Another feature of \oop\ that is not implemented in either of the
object-oriented Pascals mentioned above is the concept of {\bf operator
overloading}.  This lets a single function operate in different ways,
depending on its arguments -- a common example is the {$+$} operator,
which does addition when applied to numbers and concatenation when
applied to strings.  This could potentially be of great value in
ecosystem modelling, since one might define a function such as
Eat(predator, prey) which would act differently on different classes of
predator and prey populations.  One could construct the function {\tt Eat} so
that the call {\tt Fish.Eat(Plankton)} would correctly simulate the grazing by
fish on plankton, the call {\tt Sharks.Eat(Fish)} would treat predation in a
different way, but the calls {\tt Sharks.Eat(Plankton)}
and {\tt Plankton.Eat(Fish)} would
not do anything.  This could probably be achieved in Turbo Pascal by
the use of the {\tt TypeOf} function, but it is far easier to implement in a
language like C++ which offers prototyping (specifying exactly what
kinds of arguments a function can expect) and overloading (meaning in
this context that you can define multiple versions of a function with
different argument lists, and the compiler selects the version of the
function that fits the given arguments at the time it is called).

\section{\oo\ Languages}

\oop\ has only recently received extensive popular notice even though it
has evolved over several decades.  It arose as a natural consequence of
the structured programming revolution of the 1960's (Yourdon 1979), but
it also addresses needs that have long been recognized in ecological
modelling.  For example, Muetzelfeldt (1979) describes an idea for an
ecological simulation language remarkably similar to what we now have,
and some of these features were already implemented in the SIMSCRIPT II
simulation language (Meyer 1979).


There are numerous languages that offer support for \oop\ to some degree,
such as Modula-2 and Ada, and there are languages that fully support
\OOP\ but which are not widely used for continuous simulation modelling,
such as SmallTalk and Eiffel.  The first \oop\ language was Simula67, and
a version of Simula is still available (Lund 1989), but most of these
complete \OOP\ implementations are designed primarily for discrete
simulation, so continuous simulation modelling of the type common in
ecology is at best difficult to carry out with these languages.


An object-oriented Fortran compiler has been announced for the NeXT
computer (Absoft 1989) and Fortran-90 includes object-oriented
features, but for users of other kinds of computers the most widely
available language is C++.  MS-DOS users also have a choice between two
object-oriented Pascal compilers (Borland 1988, 1990; Microsoft 1989;
for a review of QuickPascal, see Righter 1989).  Given the popularity
of object-oriented programming, it is likely that new compilers will
continue to appear and existing compilers improved.

\section{Additional Information}

In a rapidly developing field like \oop, most sources of information
have a limited useful lifetime.  In addition to the books mentioned in
this article, there has been a growing flood of magazine articles in
general computer publications like Byte magazine, in more technical
journals like Dr. Dobb's Journal, and in new specialty publications
like the Journal of Object-Oriented Programming.  Byte in particular
publishes frequent surveys of the field (e.g., August 1986, August
1988, March 1989), including a listing of resources such as compilers
and textbooks.


Most \oop\ compilers come with both tutorial information and sample
code.  Turbo Pascal by Borland International (1988, 1990), which was
used for the models described in this paper, is very well documented
and includes many examples, as is the Zortech (1989) C++ compiler.  For
some languages, such as C++, a standard reference work exists which
defines the standard language, e.g. Stroustrup (1987), as well as
guides like Berry (1988).  There are also books covering the use of
special compilers, such as Swan (1989) and Haiduk (1989).  One of the
few general books on \oop\ to address the use of objects in continuous
simulation is Meyer (1988).


\section{Long-Term Implications}


The short-term prospects for \oop\ in ecological modelling will probably 
depend more on whether powerful and efficient compilers can be
developed than on the underlying merits of \oo\ approaches.
There are certainly technical problems that need to be overcome, such
as limited standardization of existing languages and a lack of
comprehensive mathematics libraries and other basic tools of numerical
simulation.  This will almost certainly be overcome in the near future.

Other problems may take longer to resolve.  The modelling of complex
interactions is one type of difficulty that can be approached in
several different ways, and it may take time before a consensus
emerges on how best to deal with all aspects of ecosystem models in a
way that is clearcut and readily accepted.

Ironically, part of this difficulty arises from one of the most
appealing features of \oop, namely the resemblance of the structure of
\oo\ models to that of the systems being modelled.
Intuitively this is desirable, but it also means that we are bound to
start asking ourselves whether the resulting code is sufficiently
{\it biological}\ in structure.  Objects interact by passing messages
back and forth, which leads to the concept of a prey organism
advertising its presence to a predator by sending a message, and the
predator sending back the message, ``Thanks for the information,
I think I will eat you!''  It may take time before we are comfortable
with this sort of approach.

In the long-term it is very likely that \oop\ will become firmly
established at least as a strong candidate for ecological modelling,
and a small number of \oo\ languages will emerge as ones
which are widely known and used.  It is likely that this will lead in
turn to wide-spread distribution of libraries of standard objects that
can easily be integrated into models, just as today we use standard
libraries of mathematical subroutines in Fortran programs.  This is
already widely done in some applications of \oop, and it is
considerably easier than creating libraries of procedural subroutines
because of greater flexibility in the internal structure of
objects (it is generally not necessary to define complex blocks of
common storage or to pass lengthy argument lists in \oo\ models).

A probable scenario for future ecological modelling is that
standardized objects for at least some components of ecosystems will
be developed and widely distributed in a form that can be used in many
different models.  If anyone wants to modify one of these objects it
will not be necessary to edit the source code, since inheritance can
be used to define new objects having the desired structure.  This sort
of approach has long been pursued by computer scientists, and even
some procedural languages (such as Modula-2) encourage the use
of definition modules to provide functional definitions of program
components that are completely independent of the actual code.
\oop\ carries this a step further by letting the functional definition
describe both variables and procedures in a way that reflects
ecological reality; we may know what living organisms do and how they
behave, but we seldom know why!

In a sense the use of standard objects would bring theoretical
ecologists closer to experimentalists; when a laboratory scientist
needs a mouse or a population of {\it E. coli}\ for an experiment, he
doesn't develop his organisms from scratch.  Instead he gets standard
animals from a recognized supplier.  There is no basic reason why the
developer of ecosystem models should not eventually do the same.



\section{Summary}


\oop\ offers many advantages for developers of
ecosystem models.  There is a close connection
between objects and populations or other natural groupings, and the
concept of inheritance is directly borrowed from the biological
literature.  With \oop\ one can develop models that
are simpler and closer to natural ecosystem structure than with
procedural languages, it is also possible to modify and refine these
models far more efficiently.

There may be short-term difficulties in implementing \oop\ as a
methodology for ecosystem modelling, since there is only a limited
choice of languages to work with, and many of these are not complete
implementations.  Whether \oop\ languages have reached the point where
they offer the power and efficiency to support large-scale modelling
projects is not yet known.  However, it will be surprising if
\oop\ does not become an important ecosystem modelling approach within
the next few years.

\section{Acknowledgments}

The author is grateful to George White and Paul Keizer for numerous helpful
suggestions, as well as to S. R. Kerr for useful comments on style and
organization.

\begin{refs}

\item[]
Baretta, J., and P. Ruardij (Eds.).  1988.  Tidal Flat Estuaries.
Springer-Verlag.

\item[]
Berry, John.  1988.  The Waite Group's C++ Programming.  Howard W. Sams \& Co.

\item[]
Borland International.  1990.  Turbo Pascal 6.0.  Borland
International, Scotts Valley, CA.

\item[]
% Margin release, move back 0 characters
Carruthers, R., T. S. Larkin and R. Soper.  1988.  Simulation of insect
disease dynamics: an application of SERB to a rangeland ecosystem.
Simulation 51:101-109.


\item[]
% Margin release, move back 0 characters
Folse, L. J., J. M. Packard and W. E. Grant.  1989.  AI modelling of
animal movements in a heterogeneous habitat.  Ecol. Modelling
46:57-72.


\item[]
% Margin release, move back 0 characters
Goodall, D. W.  1974.  The Hierarchical Approach to Model Building.  In
Proceedings of the First International Congress of Ecology.  Centre for
Agricultural Publishing and Documentation, Wageningen.  P. 244-249.


\item[]
% Margin release, move back 0 characters
Guthery, Scott.  1989.  Are the Emperor's New Clothes Object Oriented?
Dr. Dobb's Journal, Dec. 1989, pp. 80-86.

\item[]
Haiduk, H. P.  1989.  Object-Oriented Turbo Pascal.  Mitchell Publishing.

\item[]
Holling, C. S. (Ed.).  1978.  Adaptive Environmental Assessment and
Management.  Wiley \& Sons.

\item[]
Lund Software House.  1989.  Lund Simula.  Lund Software House AB,
Lund, Sweden.

\item[]
Meyer, Bertrand.  1988.  Object-Oriented Software Construction.
Prentice Hall.


\item[]
% Margin release, move back 0 characters
Meyer, J. A.  1979.  The Utility of the SIMSCRIPT II Language for the
Simulation of Complex Predator-% Prey Relationships.  In
State-of-the-Art in Ecological Modelling, S. E. Jorgensen (Ed.), Int.
Soc.  Ecol. Modelling.  P. 800-828.

\item[]
Microsoft Corp.  1989.  QuickPascal.  Microsoft Corp., Richmond, WA.


\item[]
% Margin release, move back 0 characters
Muetzelfeldt, R. I.  1979.  Towards an Ecologically-Orientated
Simulation Language.  In State-of-the-Art in Ecological Modelling, S.
E. Jorgensen (Ed.), Int. Soc. Ecol. Modelling.  P. 711-800.


\item[]
% Margin release, move back 0 characters
Press, W. H., B. P. Flannery, S. A. Teukolsky and W. T. Vettering.
1986.  Numerical Recipes.  Cambridge.


\item[]
% Margin release, move back 0 characters
Press, W. H., B. P. Flannery, S. A. Teukolsky and W. T. Vettering.
1988.  Numerical Recipes in C.  Cambridge.


\item[]
% Margin release, move back 0 characters
Press, W. H., B. P. Flannery, S. A. Teukolsky and W. T. Vettering.
1989.  Numerical Recipes in Fortran.  Cambridge.


\item[]
% Margin release, move back 0 characters
Righter, D. A.  1989.  Microsoft QuickPascal 1.0: Review of the
Object-Oriented Extensions.  Journal of Object-Oriented Programming
2(3):80-82.


\item[]
% Margin release, move back 0 characters
Saarenma, H., N. D. Stone, L. J. Folse, J. M. Packard, W. E. Grant, M.
E. Makela and R. N. Coulson.  1988.  An artificial modelling approach
to simulating animal-habitat interactions.  Ecol.  Modelling
44:125-141.


\item[]
% Margin release, move back 0 characters
Sequeira, R. A., P. J. H. Sharpe, N. D. Stone, K. M. El-Zik and M. E.
Makela.  1991.  Object-oriented simulation: plant growth and discrete
organ to organ interactions.  Ecol. Modelling 58:55-89.


\item[]
% Margin release, move back 0 characters
Silvert, W.  199x.  The distributed derivative: an aid to modular
modelling.  Ecological Modelling (in press).

\item[]
Stroustrup, Bjarne.  1987.  The C++ Programming Language.  Addison-Wesley.

\item[]
Swan, Tom.  1989.  Mastering Turbo Pascal 5.5, Third Edition.  Hayden Books.


\item[]
% Margin release, move back 0 characters
Sydow,A.  1982.  Hierarchical Concepts in Modelling and Simulation.  In
Progress in Modelling and Simulation, F. E. Cellier (Ed.).  P.
103-118.

\item[]
Thomas, Dave.  1989.  What's in an Object?  Byte 14(3):231-240.

\item[]
Walters, Carl.  1986.  Adaptive Management of Renewable Resources.
MacMillan Publishing Co.


\item[]
% Margin release, move back 0 characters
Zeigler, B. P.  1990.  Object-oriented Simulation with Hierarchical,
Modular Models: Intelligent Agents and Endomorphic Systems.  Academic
Press.

\item[]
Zortech Incorporated.  1989.  C++ Compiler V2.0.  Zortech Inc., Arlington, MA.
\end{refs}

\appendix
\section{Appendix A: A Working Lotka-Volterra Model}

In developing the code on which this paper is based, several different
implementations of the Lotka-Volterra model were constructed.  The
focus was on determining how fully the grazing process could be
encapsulated in the methods of the component objects in a way that
could be easily generalized to more than two species.

The approach represented by the following code involves including in
the definition of the predator class a linked list of prey populations
along with a set of parameters describing how the prey are taken; this
involves some possibly unfamiliar concepts such as pointers, but the
use of linked lists is fully documented in Turbo Pascal.  The complete
code for the model is included, except for the copyrighted RK4 integration
procedure from Press {\it et al.} (1986).

This model corresponds to the standard Lotka-Volterra model that is
found throughout the biological literature, and its behaviour is
identical.  In other words, this is the same biology expressed in a
new programming formalism, namely old wine in a new bottle.

\small
\input{lv-model}
\end{document}
% That's all, folks.
