CYCELL Logo
HOME >> LEARN>>RULE SYNTAX

Rule Syntax

Referring to a program written within a program can easily lead to ambiguities.

As used herein, the term "The Rules" or "Rules" refers to the program you will be writing to control your cells, while the term "Program" refers to the CYCELL operating system.

Variables Overview
^

Each Cell contains varying amounts of proteins and other substances that may affect the behavior of the Cell according to the Rules. For the CYCELL model, these proteins and other substances are treated as variables.

CYCELL uses four types of variables:

Some of these variables may be modified by the Rules. Others are read-only.

Prior to using the first three types of variables, they must be declared (i.e., given a name). The Internal variables are pre-named and ready for use, as described below.

All variable names must be unique. All names are case-sensitive.
User variables (U_VAR)
^

A User variable (referenced herein as U_VAR) may be declared anywhere in the Rules, on a single line, and with the following syntax:

U_VAR name

A U_VAR may contain 0 or any positive float number. As U_VARs correspond to levels of substances within the cell, they may not hold negative numbers.

Any attempt to assign a negative number to a U_VAR will result in a 0 being stored. Likewise, any attempt to assign a NaN to a U_VAR (such as from a division by zero) will result in a 0 being stored.

Upon MITOSIS, the values stored in a cell’s U_VAR variables will be split equally between the resulting mother and daughter cells.

Gradient variables (G_VAR)
^

A Gradient variable (referenced herein as G_VAR) may be declared anywhere in the Rules, on a single line, and with the following syntax:

G_VAR name

G_VARs represent substances that are emitted from a cell and diffuse throughout the environment.

The G_VARs reside, so to speak, within each Node of the Petri Dish. A cell has no direct control of a G_VAR, other than through the EMIT command. The EMIT command will set the value of a particular G_VAR variable to 1.0 in each of the cell's Nodes. From that point on, the value will diffuse from Node to Node throughout the Petri Dish. See EMIT for more information.

A cell may read only the G_VAR residing in the Node containing the cell's center.

Vector variables (V_VAR)

A Vector variable (referenced herein as V_VAR) may be declared anywhere in the Rules, on a single line, and with the following syntax:

V_VAR name

A V_VAR may be modified only by the SET_VEC command.

Internally, a V_VAR consists of a 2d vector. V_VARs are used exclusively by the MIGRATE and MITOSIS commands. For the former, the V_VAR indicates the direction of movement. For the latter, it indicates the cleavage line.

V_VARs are NOT persistent. They will always be cleared at the beginning of each evaluation cycle.
Internal variables
^

ACTUAL_AREA: This variable contains the total number of Nodes comprising the cell. It is read-only.

GOAL_AREA: This variable contains the number of Nodes the cell would 'like' to have. It may be read or written to.

RED, GREEN, and BLUE: These variables control the color of the cell. They may be read and written to. All values will be clipped to 0 through 255. Although they may be set directly, the RGB command is a useful way to deal with all of them at once.

TYPICAL_AREA: This variable is not used directly by the simulation; rather, it is a pre-named variable included for convenience.

Field-related variables

PP_SCALED_WIDTH: This variable contains the current scaled width component of the cell's Presumed Position. It may be read or written to. Values less than 0.001 will be increased to 0.001.

PP_SCALED_HEIGHT: This variable contains the current scaled height component of the cell's Presumed Position. It may be read or written to. Values less than 0.001 will be increased to 0.001.

PP_ORIENTATION: This variable contains the orientation component of the cell's Presumed Position. It may be read or written to. All values are in degree and will be mod'ed to 360.

States (STATE)
^

At any given time, a cell exists in a specific STATE. Each STATE is defined in the Rules, with various commands dictating the cell's behavior while in that STATE.

A STATE is defined by the conditions and commands (referred to as sentences) that follow the STATE's declaration. A STATE is declared (given a state_name) on a single line using the following syntax:

STATE state_name
sentences
sentences
sentences
. . .
Sentences
^

Immediately following the declaration of a STATE, the Program will have one or more sentences, each on a separate line.

A sentence is composed of conditions and commands. Alternatively, a sentence may have only commands.

Every sentence is formatted as follows:

STATE state_name
condition; condition; condition; ... :: command; command; command; ...
condition; condition; condition; ... :: command; command; command; ...
command; command; command;
. . .

Individual conditions and commands are separated by semicolons. The conditions, if any, are separated from the commands by a double colon (::).

At every cycle in the simulation, each cell will jump to that portion of the Rules that corresponds to its STATE.

Each sentence will then be evaluated in the order it is written. Specifically, going from left to right, the program will process each condition to determine if it evaluates true or false.

If any condition evaluates false, the program will abandon the sentence and move to the next one. (Or, return from the Rules if it has reached the last sentence.)

If all the conditions evaluate true, the commands will be processed from left to right. In short, each sentence can be considered as an IF statement:

IF ((condition_1)&&(condition_2)...&&(condition_n)){commands;}

Conditions
^

Many of the conditions described below use logical comparisons between values. Take for instance ADJ_CELLS[a,b]. This condition, as described in more detail below, counts the number of cells touching the evaluated cell. It will return true iff the count satisfies the logical comparison test comprised by the bracket portion.

The logical comparison syntax is a little funky. But, it's simple to learn and very concise.

The bracket portion in the example above can be written 5 different ways. The possibilities are listed below, along with their logical meaning:

In order to express a > b (or a >= b) the keyword INF may be used. INF represents the largest float the computer can handle. So, ADJ_CELLS(a,INF] means that the number of adjacent cells is larger than a.

In all the conditions below, unless otherwise noted, the bracketed portion may be swapped out for any of the above-listed possibilities.

All the conditions described below may be preceded by a !, which will cause a condition that would otherwise have evaluated true, to evaluate false, and vice versa.

Many of the conditions and commands take parameters.

In the description of the syntax for each, the following convention will be used:

ENTERING_STATE
^

A condition triggered upon entry into the state.

ENTERING_STATE takes no parameters.

It evaluates true only on the first occurrence of the cell entering the given STATE.

In the following example:

STATE Apple
ENTERING_STATE :: command_0
command_1

when the cell first enters the Apple state, command_0 will be processed, and then command_1. The next time the cell is evaluated, the program will skip command_0 and proceed directly to command_1.

If the cell leaves the Apple state (through the CHANGE_STATE command), and then subsequently returns, the ENTERING_STATE condition will once again evaluate true.

When a cell undergoes MITOSIS and creates a daughter cell that is the same state as the original (mother) cell, the daughter cell will NOT be considered to have entered the state for the first time.

POISSON
^

The condition is useful if you want something to occur every so often.

POISSON takes a literal_value as a parameter inside brackets. (This bracketed parameter is NOT a comparison.)

STATE Apple
POISSON[44] :: command_0
!POISSON[23] :: command_1

The first POISSON condition above will evaluate true, on average, every 44 times the condition is evaluated.

(Likewise, command_1 will occur every cycle except, on average, every 23 cycles or so when it will be skipped. This is due to the inclusion of the !.)

Variable comparisons
^

The value of any literal_value, u_var, or g_var, may be compared to any other literal_value, u_var, or g_var.

U_VAR Protein_a
U_VAR Protein_b


STATE Apple
Protein_a[2.34,982) :: command_0
Protein_a[Protein_b] :: command_1
46[Protein_a, Protein_b] :: command_2
. . .

In the example, Protein_a and Protein_b have been declared as U_VARs. (Let's assume that their values are modified somewhere else in the list of commands for the Apple state.)

command_0 will be processed iff the value of Protein_a is greater than or equal to 2.34 AND less than 982.

command_1 will be processed iff the value of Protein_a equals the value of Protein_b.

command_2 will be processed iff the value of Protein_a >= 46 <= the value of Protein_b.

Note that the last sentence could also be written as follows:

Protein_a[46, INF]; Protein_b[0,46] :: command_2
ADJ_CELLS
^

A condition that counts adjacent cells.

The syntax is as follows:

ADJ_CELLS[literal_value or u_var or g_var, literal_value or u_var or g_var]

- or -

ADJ_CELLS{state_name}[literal_value or u_var or g_var, literal_value or u_var or g_var]

Without the optional curly-bracket parameter, ADJ_CELLS will count all the distinct cells touching the evaluated cell. It will evaluate true if the number satisfies the comparison test, and false otherwise.

With the optional curly-bracket parameter, ADJ_CELLS will count only the cells of STATE state_name that are touching the evaluated cell. It will evaluate true if the number satisfies the comparison test, and false otherwise.

ADJ_MEMBRANES
^

A condition that counts adjacent membranes.

The syntax is as follows:

ADJ_MEMBRANES[literal_value or u_var or g_var, literal_value or u_var or g_var]

- or -

ADJ_MEMBRANES{state_name or MEDIUM}[literal_value or u_var or g_var, literal_value or u_var or g_var]

Without the optional curly-bracket parameter, ADJ_MEMBRANES will count the evaluated cell's membranes that touch any other cell. It will return true if the number satisfies the comparison test.

With the optional curly-bracket parameter, ADJ_MEMBRANES will count the evaluated cell's membranes that touch any cell in STATE state_name. Or, if MEDIUM is used as the curly-bracket parameter, it will count all such membranes that are touching the MEDIUM. It will evaluate true if the number satisfies the comparison test, and false otherwise.

The term MEMBRANE refers to the side of a Node. That is, a Node on the periphery of a cell may have from 1 to 3 MEMBRANEs touching the MEDIUM, other cells, or a combination of the two.

ADJ_MEMBRANES_PERCENT
^

A condition that evaluates adjacent membranes in terms of percents.

The syntax is as follows:

ADJ_MEMBRANES_PERCENT{state_name or MEDIUM}[literal_value or u_var or g_var, literal_value or u_var or g_var]

ADJ_MEMBRANES_PERCENT will count the evaluated cell's membranes, and then determine the percentage that touch cells in STATE state_name (or that touch the MEDIUM if that term is used as the parameter.) It will evaluate true if the number satisfies the comparison test, and false otherwise.

Note that ADJ_MEMBRANES_PERCENT evaluates percentages as numbers from 0 to 100. That is, 10% is "10" as opposed to 0.10.
FIELD
^

A condition based on where the cell thinks it is in the Field.

The syntax is as follows:

FIELD[field#, field#]

FIELD will read the field number of the cell's center Node, using the cell's Presumed Location Vector as the frame of reference. It will evaluate true if the number satisfies the comparison test, and false otherwise.

This condition will only be evaluated if FIELD_ACTIVE has been set to 1 and the Use Field checkbox is activated on the console. Unless these two condition are met, it will always evaluate false.
FIELD_EDGES
^

A condition based on where a cell thinks its edge Nodes are in the Field.

The syntax is as follows:

FIELD_EDGES{field#}[literal_value, literal_value]

FIELD_EDGES will count the evaluated cell's perimeter nodes that lie within the field# in the curly-bracket using the cell's Presumed Location Vector as the frame of reference. It will evaluate true if the number satisfies the comparison test, and false otherwise.

This condition will only be evaluated if FIELD_ACTIVE has been set to 1, and the Use Field checkbox is activated on the console. Unless these two condition are met, it will always evaluate false.
Commands
^
RGB
^

A command for setting the cell's color.

The syntax is as follows:

RGB(r, g, b)

Parameters r, g, and b may be lliteral_values or u_vars. They correspond to the Red, Green, and Blue values of the cell's color.

All parameters will be clipped to values from 0 to 255.

CHANGE_STATE
^

A command for changing the cell's state.

The syntax is as follows:

CHANGE_STATE{state_name}

This command sets the cell's STATE to state_name on the next cycle of the simulation. If state_name is equal to the cell's current state, nothing will happen.

The program will exit the Rules immediately after processing this command. When the cell re-enters the Rules on the next cycle of the simulation, it will do so in its new state.
EMIT
^

A command for setting a G_VAR variable for the purposes of diffusion.

The syntax is as follows:

EMIT{g_var}

This command will set the value of g_var in each of the cell's Nodes to 1.0.

After all the cells have run their Rules, the program diffuses the values of all the G_VAR variables throughout the Petri Dish. The speed of diffusion is constant for all G_VARs. Each G_VAR has a particular color. The Draw Diffusion checkbox on the console provides a visualization of the diffusion.

SET_VEC
^

A command for setting a V_VAR variable.

The syntax is as follows:

SET_VEC{v_var}[state_name or MEDIUM or u_var or g_var]
--- or ---
SET_VEC{v_var}[literal_value, literal_value]

This command will set the value of v_var.

V_VARs are two-dimensional vectors; they point in a particular direction. The direction depends on the parameters in the brackets.

If the bracket contains a state_name, v_var will be set as the normalized sum of all vectors extending from the cell's center to each of the cell's Nodes that touch a neighboring cell in STATE state_name. In other words, v_var will point towards the average position of all such Nodes. In the picture to the right, if the blue cells were in STATE state_name, the v_var vector would be somewhat in the direction of the black arrow.

Similarly, if the bracket contains MEDIUM as the parameter, v_var will point towards the average position of all the cell's Nodes touching the MEDIUM.

In the picture to the left, the black arrow represents v_var in such a scenario.

If the bracket contains u_var as the parameter, v_var will point towards the average position of all the cell's Nodes that touch adjacent cells containing u_var, with each such node weighted by the amount of u_var present.

The cell can read U_VAR values only from adjacent cells with which it can communicate. That is, there must be a GAP_JUNCTION between the cells. See GAP_JUNCTIONS for more information.

If the bracket contains g_var as the parameter, the cell will consider the amount of g_var in the four Nodes to the North, East, West, and South of its center node and set v_var to point towards the average concentration of g_var in these Nodes.

Finally, the second form of the command takes two litaral values which represent the x and y components of the vector. (This form is included primarily for debugging purposes and for use with the PP_MOD_SCALE command.)

The coordinate system used in CYCELL has a normal X-axis, with values increasing from left to right. But, the Y-axis is flipped; values increase from top to bottom. Thus, the vector (0.5, 0.5) points Southeast, the vector (0,1) points North, etc.

Regarding frames of reference, inputting (1,0) as a vector will result in a vector pointing East in the Petri Dish regardless of which way the cell thinks it is facing. And, if such a vector is used by MIGRATE, for instance, the program will rotate the vector internally, taking into account the cell's orientation, so that the cell will move due East.

While it might be more realistic to define vectors in terms of a cell's frame of reference, we feel its easier for the user to keep the vectors pegged to the Petri Dish and allow the program to do all the rotations and whatnot behind the scenes.

MIGRATE
^

A command for causing the cell to move.

The syntax is as follows:

MIGRATE[v_var, literal_value or u_var, literal_value or u_var]

The cell will move in the direction of v_var, the first bracket parameter.

The second bracket parameter indicates the 'strength' of migration. A negative number will induce movement in the direction of the vector (or rotated vector, as the case may be), while a positive number will induce movement in the opposite direction.

The third optional bracket parameter is an offset angle in degrees. If left blank, it will be 0. Otherwise, v_var will be rotated by the parameter's value.

There may be several MIGRATE commands. All of the resulting directional vectors and their magnitudes will be summed.

MITOSIS
^

A command for causing the cell to split.

The syntax is as follows:

MITOSIS
- or -
MITOSIS{state_name}
- or -
MITOSIS[v_var, literal_value or u_var]
- or -
MITOSIS{state_name}[v_var, literal_value or u_var, "CW" or "CCW"]

The first form will cause the mother cell to split along a random cleavage line. The daughter cell's state will be that of the mother.

The second form will cause the mother cell to split along a random cleavage line. The daughter cell's state will be state_name.

The third form will cause the mother cell to split along a cleavage line passing through the cell's center in the direction of v_var, offset by an angle given by the second parameter. The daughter cell's state will be that of the mother.

The final form will cause the mother cell to split along a cleavage line passing through the cell's center in the direction of v_var, offset by an angle given by the second parameter. The daughter cell's state will be state_name. The third parameter indicates which of the two resulting cells will be the daughter. Assuming the cleavage vector is pointing towards the top of the Petri Dish, "CW" would assign the portion to the right of the cleavage to the daughter, while "CCW" assigns the portion to the left to the daughter. (i.e. "clockwise" and "counter-clockwise.")

The program will exit the Rules immediately after processing this command.

All U_VAR variables are split equally beween mother and daughter.

Mitosis can be tricky... If the cell is in some squished position, the cleavage line might result in a divison that leaves non-contiguous sections. To avoid this, the cleavage line extends from the cell center in the direction of v_var and -v_var (adjusted by any offset angle) until an edge Node is reached.

For example, in the yellow cell above, perhaps the cleavage line passes through the cell's centroid (represented by the red dot.) If the line extended across the entire width of the cell, it would clip off the lower right portion, leaving a daughter cell with non-contiguous portions as shown here:

To avoid this, the division ends when an edge Node is reached; all contiguous Nodes on one side of the cleavage line will be the daughter, and the other set will be the second daughter.

If a daugther would contain less than 5 Nodes, mitosis will not occur; but, it will be attempted on the next simulation cycle.

If the cell center lies outside the cell (a frequent occurence if the cell is stretched out) mitosis will not occur but will be attempted on the next simulation cycle.

Math-like functions
^

Commands to directly modify U_VARs and other writeable variables.

The syntax is as follows:

a+=b
a-=b
a/=b
a*=b
a=b

Parameter a can be any writeable variable. Parameter b can be any readable variable (other than a G_VAR) or a literal_value.

The format is similar to many programming languages, wherein a+=b means a = a + b, and a-=b means a = a - b, etc.

Recall that no U_VAR can hold a negative; any attempt to do so will result in a 0 being stored. Likewise, the quotient from a division by 0 will be stored as 0.

V_VARs may also be modified with these commands, with the following restrictions.

SET_RAND
^

Command to set a random float to a variable.

The syntax is as follows:

SET_RAND{a}[b,c]

Parameter a can be any writeable variable. Parameters b and c can be any readable variable or a literal_value.

Parameter a will be set to a random float from the value of b up to c.

DIE
^

Command to kill the cell.

This command takes no parameters. Once processed, the program will exit the Rules.

END
^

Command to stop the Rules.

This command takes no parameters. Once processed, the program will exit the Rules.

There is an implicit END after every MITOSIS, CHANGE_STATE, and DIE command.

FIELD_ACTIVE
^

Command to make the cell sensitive to fields.

The syntax is as follows:

FIELD_ACTIVE["0" or "1"]

If the parameter is "1", the cell will sense fields. If "0", the cell will ignore fields.

MOD_PP_LOCATION
^

Command to modify the Location component of the cell's Presumed Position.

The syntax is as follows:

MOD_PP_LOCATION[v_var, a, b ]

a is a scaling factor and must be a literal_value.

b is a rotational offset value, measured in degrees, and may be a literal_value or u_var.

If left blank, a's default value is 1.0, and b's default value is 0.

The cell's current Presumed Position location will be modified by adding v_var, as modified by a and/or b, to it.

Simply put, if the v_var is a vector pointing due East, and a is equal to 1.0, the Cell's presumed location will move one unit to the East. Alternatively, one can think of the Field moving one unit to the West. The movement will be in the frame of reference of the Petri Dish and is irrespective of the Cell's presumed orientation; that is, in the preceding example, even if the cell's orientation was at 35 degree, the entire Field would nevertheless move 1 unit to the West.

ADJUST_PP_SCALE
^

Command to modify the Scale component of the cell's Presumed Position.

The syntax is as follows:

ADJUST_PP_SCALE[literal_value]

This command will create two sets of nodes.

The first consists of all the cell's edge nodes that are adjacent to MEDIUM and have a Field value of 0.

The second consists of all the cell's edge nodes that are adjacent to MEDIUM and have a Field value greater than 0.

The x and y scale components will then be adjusted to have the Field 'grow' in the direction of the first set, and 'shrink' in the direction of the second set. The literal_value represents the amount of the adjustment. The current PP_SCALED_WIDTH and PP_SCALED_HEIGHT will be multuplied by this variable, in proportion to the direction of growth or shrinkage.

As an example, consider the cell outlined in green.

Let us assume the cell perceives a Field zone in this area. Red represents a Field zone number greater than 0.

The command would adjust the cell's Presumed Position x- and y-scale components to make the Field (from the cell's point of view) grow and shrink in the directions indicated. The amount of growth (or shrinkage) is controlled by the literal_value parameter.

The literal_value parameter (we'll call it a) is related to the values of PP_SCALED_WIDTH and PP_SCALED_HEIGHT as follows:

PP_SCALED_WIDTHnew = PP_SCALED_WIDTHold × {1 + [a × (abs(Growx) - abs(Shrinkx))]}
PP_SCALED_HEIGHTnew = PP_SCALED_HEIGHTold × {1 + [a × (abs(Growy) - abs(Shrinky))]},

where Grow and Shrink are normalized vectors pointing in the direction (from the cell's point of view) of desired growth and shrinkage

Also keep in mind that the Program, at all times, will slowly adjust the x- and y-scale components of each cell's Presumed Position to have them gravitate towards the same value.

ADHESIONS
^

ADHESIONS control the degree cells stick to one another, themselves, and the MEDIUM.

ADHESIONS are declared as follows:

ADHESIONS
<state_name a, state_name a>(literal_value)
-- or --
<state_name a, state_name b>(literal_value)
-- or --
<state_name,SELF>(literal_value)
-- or --
<state_name,MEDIUM>(literal_value)
. . .

The first form dictates the degree to which cells of the same type adhere. The more negative the literal_value, the greater the adhesion.

The second form dictates the degree to which cells of the two different types adhere. The more negative the literal_value, the greater the adhesion.

The third form, using the keyword SELF, dictates the degree to which cells of the given type maintain their own self-adhesion. The more negative the literal_value, the greater the degree a particular cell will maintain a compact shape.

The fourth form, using the keyword MEDIUM, dictates the degree to which cells of the given type seek to avoid (or merge with) the surrounding MEDIUM. The more negative the literal_value, the greater the degree the cell type will seek to spread out into the MEDIUM. Typically, this value will be positive.

The following values are defaults:

(The adhesion values of Default_Blue and Default_Yellow may be set in real-time through the Blue/Yellow console.)

GAP_JUNCTIONS
^

GAP_JUNCTIONS control the rate at which U_VAR values are transferred between adjacent cells.

GAP_JUNCTIONS are declared as follows:

GAP_JUNCTIONS
<state_name a, state_name a, u_var>(literal_value)
-- or --
<state_name a, state_name b, u_var>(literal_value)
. . .

The first form dictates the rate u_var will flow between cells of the same type. The rate is set by literal_value.

The second form dictates the rate u_var will flow between cells of type a and b. The rate is set by literal_value.

In both forms, the literal_value is the fraction of the u_var per shared membrane that will be transferred from one cell to the other every cycle.

For the following example, <Apple, Bear, protein>(0.001)
A1 = A0 - (0.001 * MAB) + (0.001 * MAB × B0), where
A0 is the original level of protein in Apple,
A1 is the new level of protein in Apple after the iteration,
B0 is the original level of protein in Bear, and
MAB is the number of membranes shared between Apple and Bear.

The default rate for all junctions is 0. That is, unless set, no u_vars will be shared between cells.