home
contents
background
models description
design
GUIs
events
calculations
publishing

Declarative Model Description

Setting up a calculation involves a range of distinct tasks which are often mixed together in a single script or program. They include specifying parameter values, describing equations to be solved, allocating memory to hold the working variables and output data, and setting initial values. For a one-off series of calculations, this is quick and efficient. If, however, the same or similar models are to be used in different contexts, by different people, or over a long time, there are often dramatic gains to be had from separating the problem into a purely descriptive part and a parameter-free execution part. The descriptive part includes the structure of the model, parameter values for its components, a description of how it is to be run, and perhaps a description of how the results should be displayed.

Purely Declarative

Declarations are essentially "name = value" pairs, where the "value" may be a primitive data type (boolean, integer, double, string), an array of primitive data, or a compound data type. In a purely declarative description, a compound data type just contains other "name = value" statements. These compound data types are the key to building efficient and intuitive descriptions of models. Two special structures - lists and references - complete what is needed for all the models developed so far in Catacomb.

Functions (not allowed)

In thinking about setting up a declarative description of a model, it often appears at first that some kind of non-declarative function mechanism, or at least computed assignment of parameters is essential in order to describe the model. For example, you might want to describe a cell in which the membrane capacitance per unit area is not constant, but depends on the radius of the segment so as to account for spines on some segments. This could be done by allowing a "name = function(other names)" in the description. But I think this is never necessary and that it takes away many of the advantages of a declarative description. Moreover, finding a purely declarative way round the problem leads to a description which is invariably clearer and easier to understand. To resolve the spine problem, for example, one might have included the parameters used in the spine function as new declarative statements, perhaps the minimum radius at which spines are present, the single spine surface area and the spine density. This is more restrictive than a general function facility but that is precicely why it is better. If a wider variety of functions was required, a new object could be created to contain descriptions of how spines influence the capacitance.If it seems that a function is necessary, then you are probably trying to make the description too concise or you are trying to postpone deciding how to describe something. The answer is to add parameters or create new description frameworks to cover what you had wanted to do in the function. Once created, they will certainly be more readable than the function and may well turn out to be useful in other contexts.

Compound Types

Building a framework for describing a class of models amounts to specifying the compound types that will be used. For example, a simple compound type to describe an ionic specie might have fields for its name, symbol, charge and mobility in water. More complex compound types require fields which themselves are compound types. A more complex specie framework might include a field specifying its nuclear properties (number of protons, neutrons, atomic mass excess etc), which could be grouped together in another compound type.

In the specie example, each specie has exactly one set of nuclear properties, so the specie type can contain a field which itself is a compound type. Very frequently, however, a compound type is required to hold a variable number of elements of some other type (eg the nodes in a graph), or it may be best to use an element without defining it because the element has already been defined elsewhere. These two cases, lists and selections, are the only special compound types built into Catacomb.

Lists

As far as Catacomb is concerned, a list is an ordered set of elements all of the same type. That is, when defining a compound type which contains a list, Catacomb requires that the type of objects to go in the list should be specified. This is not as restrictive as it sounds, because such a list can also contain any type derived from the one it is supposed to contain (so, if really necessary, you can tell it that a list just contains objects). But frequently there is only one type that can meaningfully be placed in a list in a particular context.

Selections

In defining a number of different cells, for example, one might wish to specify that each contains a particular type of channel. One could give each cell a list of channels, and duplicate the description of any channels that appear in multiple cells. A more robust and economical method, which is probably also closer to what the description is intended to say, is to keep a list of channel models elsewhere, and just refer to them by name in the individual cell models. A "Selection" in Catacomb is a field which holds the name of an object of a specified type. The object itself must be found elsewhere. The framework specification states what type of object can be referred to. A model built from the framework gives the actual name of the desired object.

Graphs

Many models can be expressed as graphs (in teh sense of collections of nodes and arcs). The simplest way to describe such a structure in Catacomb is for the graph framework to state that a graph model contains two lists: a list of nodes and a list of arcs. The node framework needn't do anything special, but the arc framework should have two selections to an element of type node. In a particular arc model these should be set to the source and target node. This is not the only way to describe graphs, but it is one of the most convenient in Catacomb.

Quantified sets

Another very common problem is to express quantified sets where a model can have a variable quantity of each element of a list. For example, to express a solution one might state the concentration of each specie. When it was first written, Catacomb had a special structure for such cases - a quantified selection which specified an integer or continuous amount of each element of a list. But it turned out to be too restrictive. Where do you put hte units that are used for example? And what if different elements require different units (eg some compounts in nM some in mM).

The current way of doing this is with an extra type of compound element. A solution becomes a list of SolutionElements. Each SolutionElement has a selection to specify which compound it refers to and variables for the concentration and units. It is not very intuitive when used through the default interface components, but the complexity can easily be concealed behind item specific interfaces.