type II chain", because such an annotation requires referencing the products of other genes such as gamma or delta. All the known proteins could be enumerated, but such an approach would almost surely lead to inaccuracies because biological knowledge continues to evolve. Instead, the annotation should refer to generic information such as Ensembl family ENSFM00250000000111 "CALCIUM/CALMODULIN DEPENDENT KINASE TYPE II CHAIN" or PIR superfamily PIRSF000594 "Calcium/calmodulin-dependent protein kinase type II".

The following two examples show how to use the qualifier `isVersionOf`. The first example is the relationship between a reaction and an EC code. An EC code describes an enzymatic activity and an enzymatic reaction involving a particular enzyme can be seen as an instance of this activity. For example, the following reaction represents the phosphorylation of a glutamate receptor by a complex calcium/calmodulin kinase II.

```xml
<reaction id="NMDAR_phosphorylation" metaid="thx1138"
          reversible="true">
  <annotation>
    <rdf:RDF
      xmlns:bqbiol="http://biomodels.net/biology-qualifiers/"
      xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    >
      <rdf:Description rdf:about="#thx1138">
        <bqbiol:isVersionOf>
          <rdf:Bag>
            <rdf:li rdf:resource="https://identifiers.org/ec-code/2.7.1.17"/>
          </rdf:Bag>
        </bqbiol:isVersionOf>
      </rdf:Description>
    </annotation>
  </annotation>
  <listOfReactants>
    <speciesReference species="NMDAR" stoichiometry="1"/>
  </listOfReactants>
  <listOfProducts>
    <speciesReference species="P-NMDAR" stoichiometry="1"/>
  </listOfProducts>
  <listOf Modifiers>
    <modifierSpeciesReference species="CaMKII"/>
  </listOf Modifiers>
  <kineticLaw>
    <math xmlns="http://www.w3.org/1998/Math/MathML">
      <apply>
        <times/>
        <ci>CaMKII</ci>
        <ci>kcat</ci>
      </apply>
      <divide/>
      <ci>NMDAR</ci>
      <apply></times> <ci>NMDAR</ci> <ci>Km</ci> </apply>
    </apply>
  </math>
  <listOfLocalParameters>
    <localParameter id="kcat" value="1"/>
    <localParameter id="Km" value="5e-10"/>
  </listOfLocalParameters>
  <kineticLaw>
  </kineticLaw>
</reaction>
```

The second example of the use of `isVersionOf` is the complex between Calcium/calmodulin-dependent protein kinase type II alpha chain and Calcium/calmodulin, that is only one of the "calcium- and calmodulin-dependent protein kinase complexes" described by the Gene Ontology term GO:0005954. (Note also how the GO identifier is written—we return to this point below.)

```xml
<species id="CaCaMKII" metaid="C8H10N4O2" compartment="C"
          hasOnlySubstanceUnits="false" boundaryCondition="false"
          constant="false">
  <annotation>
```
```xml
<rdf:RDF
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:bqbiol="http://biomodels.net/biology-qualifiers/"
>
  <rdf:Description rdf:about="#C8H10N4O2">
    <bqbiol:isVersionOf>
      <rdf:Bag>
        <rdf:li rdf:resource="https://identifiers.org/go/GO:0005954"/>
      </rdf:Bag>
    </bqbiol:isVersionOf>
  </rdf:Description>
</rdf:RDF>
</annotation>
</species>
```

In the example above, the URN for the GO term is written as `GO%3A0005954`, yet in reality, the actual GO identifier is `GO:0005954`. The reason for this rests in the definition of RDF/XML and URNs. The essential point is that the colon character (`:`) is a reserved character representing the component separator in URNs. Thus, when an identifier contains a colon character as part of it (as GO, ChEBI, and certain other identifiers do), the colon characters must be percent-encoded. The sequence `%3A` is the percent-encoded form of `:`. Applications must percent-encode `:` characters that appear in entity identifiers (whether from ECO, ChEBI, GO, or other) when writing them in MIRIAM URIs, and percent-decode the identifiers when reading the URIs. More examples of this appear throughout the rest of this section.

The previous case is different from the following one, although they could seem similar at first sight. The "Calcium/calmodulin-dependent protein kinase type II alpha chain" is a part of the above mentioned "calcium- and calmodulin-dependent protein kinase complex".

```xml
<species id="CaMKIIalpha" metaid="C10H14N2" compartment="C"
          hasOnlySubstanceUnits="false" boundaryCondition="false"
          constant="false">
  <annotation>
    <rdf:RDF
      xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
      xmlns:bqbiol="http://biomodels.net/biology-qualifiers/"
    >
      <rdf:Description rdf:about="#C10H14N2">
        <bqbiol:isPartOf>
          <rdf:Bag>
            <rdf:li rdf:resource="https://identifiers.org/go/GO:0005954"/>
          </rdf:Bag>
        </bqbiol:isPartOf>
      </rdf:Description>
    </annotation>
  </annotation>
</species>
```

It is possible to describe a component with several alternative sets of qualified annotations. For example, the following species represents a pool of GMP, GDP and GTP. We annotate it with the three corresponding KEGG compound identifiers but also with the three corresponding ChEBI identifiers. The two alternative annotations are encoded in separate `hasVersion` qualifier elements.

```xml
<species id="GXP" metaid="GXP" compartment="C"
          hasOnlySubstanceUnits="false" boundaryCondition="false"
          constant="false">
  <annotation>
    <rdf:RDF
      xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
      xmlns:bqbiol="http://biomodels.net/biology-qualifiers/"
    >
      <rdf:Description rdf:about="#GXP">
        <bqbiol:hasVersion>
          <rdf:Bag>
            <rdf:li rdf:resource="https://identifiers.org/chebi/CHEBI:17345"/>
            <rdf:li rdf:resource="https://identifiers.org/chebi/CHEBI:17552"/>
            <rdf:li rdf:resource="https://identifiers.org/chebi/CHEBI:17627"/>
          </rdf:Bag>
        </bqbiol:hasVersion>
      </rdf:Description>
    </annotation>
  </annotation>
</species>
```
```xml
)rdf:li rdf:resource="https://identifiers.org/kegg.compound/C00032"/>
</rdf:Bag>
</bqbiol:hasPart>
</rdf:Description>
</rdf:RDF>
</annotation>
</species>
```

As formally defined above it is possible to use different qualifiers in the same annotation element. The following phosphorylation is annotated by its exact KEGG counterpart and by the generic GO term "phosphorylation".

```xml
<reaction id="phosphorylation" metaid="phosphorylation"
          reversible="true"/>
<annotation>
  <rdf:RDF
    xmlns:bqbiol="http://biomodels.net/biology-qualifiers/"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  >
    <rdf:Description rdf:about="#phosphorylation">
      <bqbiol:is>
        <rdf:Bag>
          <rdf:li rdf:resource="https://identifiers.org/kegg.reaction/R03313"/>
        </rdf:Bag>
      </bqbiol:is>
      <bqbiol:isVersionOf>
        <rdf:Bag>
          <rdf:li rdf:resource="https://identifiers.org/go/GO:0016310"/>
        </rdf:Bag>
      </bqbiol:isVersionOf>
    </rdf:Description>
  </rdf:RDF>
</annotation>
</reaction>
```

The following example demonstrates the use of nested terms to describe both that a species is in a particular compartment, and the evidence that the species belongs there:

```xml
<species id="S1" metaid="_000004" compartment="lysosome"
          hasOnlySubstanceUnits="false" boundaryCondition="false"
          constant="false"/>
<annotation>
  <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:bqbiol="http://biomodels.net/biology-qualifiers/"
    xmlns:bqmodel="http://biomodels.net/model-qualifiers/">
    <rdf:Description rdf:about="#_000004">
      <bqbiol:occursIn>
        <rdf:Bag>
          <rdf:li rdf:resource="https://identifiers.org/go/GO:0005764"/>
          <bqbiol:isDescribedBy>
            <rdf:Bag>
              <rdf:li rdf:resource="https://identifiers.org/pubmed/111111"/>
            </rdf:Bag>
          </bqbiol:isDescribedBy>
          <bqbiol:isDescribedBy>
            <rdf:Bag>
              <rdf:li rdf:resource="https://identifiers.org/eco/ECO:0000004"/>
            </rdf:Bag>
          </bqbiol:isDescribedBy>
        </rdf:Bag>
      </bqbiol:occursIn>
    </rdf:Description>
  </rdf:RDF>
</annotation>
</species>
```

In descriptive terms, the SBML species "S1" (with metaid "_000004") occurs in "go/GO:0005764" (the lysosome). This is described by the publication "pubmed/1111111", and is believed to be true because of the evidence "eco/ECO:0000004" (cell fractionation evidence).
The following example demonstrates the use of nested terms to describe that the annotated species represents a phosphorylated form of a particular protein:

<species id="S1" metaid="_000004" compartment="cell"
  hasOnlySubstanceUnits="false" boundaryCondition="false"
  constant="false">
  <annotation>
    <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
      xmlns:bqbiol="http://biomodels.net/biology-qualifiers/"
      <rdf:Description rdf:about="#_000004" >
      <bqbiol:isVersionOf>
        <rdf:Bag>
          <rdf:li rdf:resource="https://identifiers.org/uniprot/P04551"/>
          <bqbiol:isVersionOf>
            <rdf:Bag>
              <rdf:li rdf:resource="https://identifiers.org/psimod/MOD:00047"/>
            </rdf:Bag>
          </bqbiol:isVersionOf>
        </rdf:Bag>
      </rdf:Description>
    </annotation>
  </annotation>
</species>
# 7 Example models expressed in XML using SBML

In this section, we present several examples of complete models encoded in XML using SBML Level 3.

## 7.1 A simple example application of SBML

Consider the following representation of an enzymatic reaction:

$$E + S \underset{k_{\text{off}}}{\overset{k_{\text{on}}}{\rightleftharpoons}} ES \underset{k_{\text{cat}}}{\overset{k_{\text{cat}}}{\rightleftharpoons}} E + P$$

In our model, we use the following initial species amounts:

$$E = 5 \cdot 10^{-21} \text{ mole}$$

$$S = 10^{-20} \text{ mole}$$

$$P = 0 \text{ mole}$$

$$ES = 0 \text{ mole}$$

Note that the species quantities are initialized in terms of substance amounts rather than concentrations. We also define the following values for the kinetic constants:

$$k_{\text{on}} = 1000000 \text{ litre mole}^{-1} \text{ second}^{-1}$$

$$k_{\text{off}} = 0.2 \text{ second}^{-1}$$

$$k_{\text{cat}} = 0.1 \text{ second}^{-1}$$

We place everything in a single compartment we call “comp” whose volume is $10^{-14}$ litres. The following is a minimal but complete SBML document encoding this model:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<sbml xmlns="http://www.sbml.org/sbml/level3/version2/core" level="3" version="2">
<model extentUnits="mole" timeUnits="second">
<listOfUnitDefinitions>
<unitDefinition id="per_second">
<listOfUnits>
<unit kind="second" exponent="-1" scale="0" multiplier="1"/>
</listOfUnits>
</unitDefinition>
<unitDefinition id="litre_per_mole_second">
<listOfUnits>
<unit kind="mole" exponent="-1" scale="0" multiplier="1"/>
<unit kind="litre" exponent="1" scale="0" multiplier="1"/>
<unit kind="second" exponent="-1" scale="0" multiplier="1"/>
</listOfUnits>
</unitDefinition>
</listOfUnitDefinitions>
<listOfCompartments>
<compartment id="comp" size="1e-14" spatialDimensions="3" units="litre" constant="true"/>
</listOfCompartments>
<listOfSpecies>
<species compartment="comp" id="E" initialAmount="5e-21" boundaryCondition="false" hasOnlySubstanceUnits="false" substanceUnits="mole" constant="false"/>
<species compartment="comp" id="S" initialAmount="1e-20" boundaryCondition="false" hasOnlySubstanceUnits="false" substanceUnits="mole" constant="false"/>
<species compartment="comp" id="P" initialAmount="0" boundaryCondition="false" hasOnlySubstanceUnits="false" substanceUnits="mole" constant="false"/>
<species compartment="comp" id="ES" initialAmount="0" boundaryCondition="false" hasOnlySubstanceUnits="false" substanceUnits="mole" constant="false"/>
</listOfSpecies>
<listOfReactions>
<reaction id="veq" reversible="true">
<listOfReactants>
<speciesReference species="E" stoichiometry="1" constant="true"/>
<speciesReference species="S" stoichiometry="1" constant="true"/>
</listOfReactants>
</reaction>
```
```xml
<listOfProducts>
    <speciesReference species="ES" stoichiometry="1" constant="true"/>
</listOfProducts>
<kineticLaw>
    <math xmlns="http://www.w3.org/1998/Math/MathML">
        <apply>
            <times/>
            <ci>comp</ci>
            <apply>
                <minus/>
                <apply>
                    <times/>
                    <ci>kon</ci>
                    <ci>E</ci>
                    <ci>S</ci>
                </apply>
            </apply>
            <apply>
                <times/>
                <ci>koff</ci>
                <ci>ES</ci>
            </apply>
        </apply>
    </math>
    <listOfLocalParameters>
        <localParameter id="kon" value="1000000" units="litre_per_mole_second"/>
        <localParameter id="koff" value="0.2" units="per_second"/>
    </listOfLocalParameters>
</kineticLaw>
</reaction>
<reaction id="vcat" reversible="false">
    <listOfReactants>
        <speciesReference species="ES" stoichiometry="1" constant="true"/>
    </listOfReactants>
    <listOfProducts>
        <speciesReference species="E" stoichiometry="1" constant="true"/>
        <speciesReference species="P" stoichiometry="1" constant="true"/>
    </listOfProducts>
    <kineticLaw>
        <math xmlns="http://www.w3.org/1998/Math/MathML">
            <apply>
                <times/>
                <ci>comp</ci>
                <ci>kcat</ci>
                <ci>ES</ci>
            </apply>
        </math>
        <listOfLocalParameters>
            <localParameter id="kcat" value="0.1" units="per_second"/>
        </listOfLocalParameters>
    </kineticLaw>
</reaction>
</listOfReactions>
</model>
</sbml>
```

The model features local parameter definitions in each reaction. In this case, the three parameters (kon, koff, kcat) all have unique identifiers and they could also have just as easily been declared global parameters. Local parameters frequently become more useful in larger models, where it may become tedious to assign unique identifiers for all the different parameters.

The example above also demonstrates the use of unit specifications throughout the model. The model components define the units of kinetic laws as being mole/second by virtue of the values of the attributes extentUnits and timeUnits. In the rest of the model, species, parameters and compartments are defined with appropriate units so that the mathematical formulas inside the kineticLaw elements work out to be mole/second.
## 7.2 A simple example using the conversionFactor attribute

This example involves the same enzymatic reaction as in the example of Section 7.1 on p. 113:

$$E + S \underset{k_{\text{off}}}{\overset{k_{\text{on}}}{\rightleftharpoons}} ES \quad \overset{k_{\text{cat}}}{\longrightarrow} \quad E + P$$

In this new version of the model, we deliberately define the species with different units from the unit of reaction extent in the model. This leads to two illustrative problems: (1) the reaction rate expressions must be changed in order to reconcile the differences between the species units and the unit of reaction extent in the model, and (2) the formulas constructed for species' rate-of-change equations must use conversion factors to reconcile the differences between the units of the reaction rate expressions and the units in which the species quantities are measured.

We begin with the following new **Species** object definitions:

$$E = 5 \cdot 10^{-18} \text{ millimole}$$

$$S = 10^{-17} \text{ millimole}$$

$$P = 0 \text{ gram}$$

$$ES = 0 \text{ millimole}$$

We keep the units of extent and time in the model the same as in the example of Section 7.1 on p. 113; that is, the overall unit of extent in the model is mole and the unit of time is second, set by assigning appropriate values to the attributes **extentUnits** and **timeUnits**, respectively, on the **Model** object definition. The differences between these and the units of the species means that we have to adjust the reaction rate expressions from their original versions in the model. In what follows, we illustrate one approach to doing so, and in Section 7.3 on p. 118 we illustrate a second approach. The method in the present section involves changing the values of the kinetic rate constants in the reaction rate formulas, while the example of Section 7.3 does not change the kinetic constants but does require the introduction of additional parameters.

The reaction rate formulas (i.e., the formulas in the **math** elements of **KineticLaw** objects) were previously

$$v_{\text{veq}} = V_{\text{comp}} \cdot (k_{\text{on}} \cdot [E] \cdot [S] - k_{\text{off}} \cdot [ES]) \quad (5)$$

$$v_{\text{vcat}} = V_{\text{comp}} \cdot k_{\text{cat}} \cdot [ES] \quad (6)$$

where $V_{\text{comp}}$ stands for the size of compartment “comp” in the SBML model. Recalling the values of the parameters $k_{\text{on}}$, $k_{\text{off}}$, and $k_{\text{cat}}$,

$$k_{\text{on}} = 1000\,000 \text{ litre mole}^{-1} \text{ second}^{-1}$$

$$k_{\text{off}} = 0.2 \text{ second}^{-1}$$

$$k_{\text{cat}} = 0.1 \text{ second}^{-1}$$

it becomes clear that, with the values of E, S and ES all in millimoles, Equations 5 and 6 no longer lead to units of mole/second for the reaction rates. To compensate, we change the values of the constants $k_{\text{on}}$, $k_{\text{off}}$, and $k_{\text{cat}}$ using the following simple transformations:

$$k_{\text{on}}^{*} = k_{\text{on}} \cdot \left( \frac{1 \text{ mole}}{1000 \text{ millimoles}} \right)^{2} = 1 \text{ litre mole millimole}^{-2} \text{ second}^{-1}$$

$$k_{\text{off}}^{*} = k_{\text{off}} \cdot \frac{1 \text{ mole}}{1000 \text{ millimoles}} = 0.0002 \text{ mole millimole}^{-1} \text{ second}^{-1}$$

$$k_{\text{cat}}^{*} = k_{\text{cat}} \cdot \frac{1 \text{ mole}}{1000 \text{ millimoles}} = 0.0001 \text{ mole millimole}^{-1} \text{ second}^{-1}$$

The “mole/millimole” portion of the units are admittedly unconventional for mass-action kinetic rate constants. They are unlikely to correspond to values found in textbooks or databases. The logic of this approach is that in an actual experimental situation, with the units of the species as given in the model (presumably
representing how the species are being measured), the kinetic rate constants are likely to be measured in terms of the units above. However, if that is not the case, then the approach of Section 7.3 on p. 118 may be more appropriate.

Taking these new $k_{on}^*$, $k_{off}^*$ and $k_{cat}^*$ parameters and replacing the original parameters in the reaction rate equations finally leads to the following:

$$v_{veq} = V_{comp} \cdot (k_{on}^* \cdot [E] \cdot [S] - k_{off}^* \cdot [ES]) \quad (7)$$

$$v_{vcat} = V_{comp} \cdot k_{cat}^* \cdot [ES] \quad (8)$$

Next, we turn to the rates-of-change equations for the species. There are two cases: species S, whose unit of substance is millimole, and species P, whose unit of substance is gram. We use SBML Level 3's conversion factor mechanism to effectuate the necessary transformations, following the guidelines described in Section 4.11.7 on p. 77. In the model text below, we define a default conversion factor by setting the value of the **Model** object's **conversionFactor** attribute to a parameter whose values is

$$\frac{1000 \text{ millimole}}{1 \text{ mole}}$$

Let $c_{model}$ stand for the **Model** object's **conversionFactor** attribute with the value above. The rate-of-change equation for S is the following:

$$\frac{dn_S}{dt} = -c_{model} \cdot V_{comp} \cdot (k_{on}^* \cdot [E] \cdot [S] - k_{off}^* \cdot [ES]) \quad (9)$$

The portion inside the gray box in Equation 9 is simply Equation 7, and its value will have the unit mole/second. Multiplying this by $c_{model}$ will produce a result in millimole/second. The stoichiometry of species S in the reaction is “1”, but it is a reactant, thus the need for the negative sign.

For species P, we need a different conversion factor, to convert between the units of gram and mole. We accomplish this by setting a value for the **Species** object's **conversionFactor** attribute. By virtue of being defined on the **Species** object for P, this conversion factor value overrides the global value defined on the **Model** object. Let $c_P$ represent this conversion factor. The equation for the rate-of-change of P is the following:

$$\frac{dn_P}{dt} = c_P \cdot V_{comp} \cdot k_{cat}^* \cdot [ES] \quad (10)$$

The portion inside the gray box in Equation 10 is simply Equation 8, with a value in mole/second. Multiplying by the conversion factor “convertToGram” defined in the model below will yield gram/second. The species P is a product, and its stoichiometry is “1”; thus, the right-hand side has a positive sign.

The following is the SBML encoding of this model:

```xml
<?xml version="1.0" encoding="UTF-8" ?>
<sbml xmlns="http://www.sbml.org/sbml/level3/version2/core" level="3" version="2">
<model extentUnits="mole" timeUnits="second" conversionFactor="convertToMilliMole">
<listOfUnits>
<unitDefinition id="mole_per_millimole_second">
<listOfUnits>
<unit kind="mole" exponent="1" scale="0" multiplier="1" />
<unit kind="mole" exponent="-1" scale="-3" multiplier="1" />
<unit kind="second" exponent="-1" scale="0" multiplier="1" />
</listOfUnits>
</unitDefinition>
<unitDefinition id="mole_litre_per_millimole_sq_second">
<listOfUnits>
<unit kind="mole" exponent="1" scale="0" multiplier="1" />
<unit kind="litre" exponent="1" scale="0" multiplier="1" />
<unit kind="mole" exponent="-2" scale="-3" multiplier="1" />
<unit kind="second" exponent="-1" scale="0" multiplier="1" />
</listOfUnits>
</unitDefinition>
<unitDefinition id="millimole">
<listOfUnits>
```
```xml
<kineticLaw>
  <math xmlns="http://www.w3.org/1998/Math/MathML">
    <apply>
      <times /> <ci> comp </ci> <ci> kcat </ci> <ci> ES </ci>
    </apply>
  </math>
  <listOfLocalParameters>
    <localParameter id="kcat" value="0.0001" units="mole_per_millimole_second" />
  </listOfLocalParameters>
</kineticLaw>
</reaction>
</listOfReactions>
</model>
</sbml>
```

## 7.3 An alternative formulation of the conversionFactor example

Here we present an alternative formulation of the model from the previous section. Once again, it involves the same enzymatic reaction as in the example of Section 7.1 on p. 113:

$$E + S \underset{k_{\text{off}}}{\overset{k_{\text{on}}}{\rightleftharpoons}} ES \xrightarrow{k_{\text{cat}}} E + P$$

As in Section 7.2 on p. 115, we define the overall unit of extent on the model to be mole and the unit of time to be second; this means the unit of reaction rates is mole/second as before. We also set the initial amounts and units as in the previous section:

$$E = 5 \cdot 10^{-18} \text{ millimole}$$

$$S = 10^{-17} \text{ millimole}$$

$$P = 0 \text{ gram}$$

$$ES = 0 \text{ millimole}$$

Unlike in the previous section's model, however, here we retain the values of the kinetic constants as they were originally in the model of Section 7.1 on p. 113:

$$k_{\text{on}} = 1000000 \text{ litre mole}^{-1} \text{ second}^{-1}$$

$$k_{\text{off}} = 0.2 \text{ second}^{-1}$$

$$k_{\text{cat}} = 0.1 \text{ second}^{-1}$$

We take a different approach to adjusting the reaction rate expressions to account for the fact that the concentrations of the species as they appear in the KineticLaw elements are in units of millimole/litre, while the unit of reaction extent is mole and reaction rates are in mole/second. Our approach here is to introduce constants into the reaction rate expressions to convert the substance units to mole and multiply each occurrence of a concentration by that constant. A separate constant is necessary for each Species object appearing in a KineticLaw object, although it turns out that in the particular situation under consideration here, the constants are all identical:

$$c_E = c_S = c_{ES} = 10^{-3} \text{ mole millimole}^{-1}$$

Applying this approach, the reaction rate equations become the following:

$$v_{\text{veq}} = V_{\text{comp}} \cdot (k_{\text{on}} \cdot [E] \cdot c_{E} \cdot [S] \cdot c_{S} - k_{\text{off}} \cdot [ES] \cdot c_{ES})$$

$$v_{\text{vcat}} = V_{\text{comp}} \cdot k_{\text{cat}} \cdot [ES] \cdot c_{ES}$$

where again $V_{\text{comp}}$ stands for the size of compartment called "comp" in the SBML model. We construct the rate-of-change equations for the each species using the guidelines described in Section 4.11.7 on p. 77, and in this case, the equations for species S and P are

$$\frac{dn_S}{dt} = -c_{\text{model}} \cdot V_{\text{comp}} \cdot (k_{\text{on}} \cdot [E] \cdot c_E \cdot [S] \cdot c_S - k_{\text{off}} \cdot [ES] \cdot c_{ES})$$

$$\frac{dn_P}{dt} = c_P \cdot V_{\text{comp}} \cdot k_{\text{cat}} \cdot [ES] \cdot c_{ES}$$
where again $c_{model}$ stands for the value of the **Model** object's **conversionFactor** attribute and $c_P$ is the value of the **conversionFactor** attribute of the **Species** object definition for P.

The SBML encoding of this model is given below:

```xml
<?xml version="1.0" encoding="UTF-8" ?>
<sbml xmlns="http://www.sbml.org/sbml/level3/version2/core" level="3" version="2">
<model extentUnits="mole" timeUnits="second" conversionFactor="convertToMilliMole">
<listOfUnitDefinitions>
<unitDefinition id="per_second">
<listOfUnits>
<unit kind="second" exponent="-1" scale="0" multiplier="1" />
</listOfUnits>
</unitDefinition>
<unitDefinition id="litre_per_mole_second">
<listOfUnits>
<unit kind="mole" exponent="-1" scale="0" multiplier="1" />
<unit kind="litre" exponent="1" scale="0" multiplier="1" />
<unit kind="second" exponent="-1" scale="0" multiplier="1" />
</listOfUnits>
</unitDefinition>
<unitDefinition id="millimole">
<listOfUnits>
<unit kind="mole" exponent="1" scale="-3" multiplier="1" />
</listOfUnits>
</unitDefinition>
<unitDefinition id="gram_per_mole">
<listOfUnits>
<unit kind="gram" exponent="1" scale="0" multiplier="1" />
<unit kind="mole" exponent="-1" scale="0" multiplier="1" />
</listOfUnits>
</unitDefinition>
<unitDefinition id="mole_per_millimole">
<listOfUnits>
<unit kind="mole" exponent="1" scale="0" multiplier="1" />
<unit kind="mole" exponent="-1" scale="-3" multiplier="1" />
</listOfUnits>
</unitDefinition>
<unitDefinition id="millimole_per_mole">
<listOfUnits>
<unit kind="mole" exponent="1" scale="-3" multiplier="1" />
<unit kind="mole" exponent="-1" scale="0" multiplier="1" />
</listOfUnits>
</unitDefinition>
</listOfUnitDefinitions>
<listOfCompartments>
<compartment id="comp" size="1e-14" spatialDimensions="3" units="litre" constant="true" />
</listOfCompartments>
<listOfSpecies>
<species compartment="comp" id="ES" initialAmount="0" boundaryCondition="false" hasOnlySubstanceUnits="false" substanceUnits="millimole" constant="false" />
<species compartment="comp" id="P" initialAmount="0" boundaryCondition="false" hasOnlySubstanceUnits="false" substanceUnits="gram" constant="false" conversionFactor="convertToGram" />
<species compartment="comp" id="S" initialAmount="1e-17" boundaryCondition="false" hasOnlySubstanceUnits="false" substanceUnits="millimole" constant="false" />
<species compartment="comp" id="E" initialAmount="5e-18" boundaryCondition="false" hasOnlySubstanceUnits="false" substanceUnits="millimole" constant="false" />
</listOfSpecies>
<listOfParameters>
<parameter id="convertToMilliMole" value="1000" units="millimole_per_mole" constant="true" />
<parameter id="convertToGram" value="180" units="gram_per_mole" constant="true" />
<parameter id="c_e" value="1e-3" units="mole_per_millimole" constant="true" />
<parameter id="c_s" value="1e-3" units="mole_per_millimole" constant="true" />
<parameter id="c_es" value="1e-3" units="mole_per_millimole" constant="true" />
</listOfParameters>
<listOfReactions>
<reaction id="veq" reversible="true">
<listOfReactants>
```
```xml
<speciesReference species="E" stoichiometry="1" constant="true" />>
<speciesReference species="S" stoichiometry="1" constant="true" />>
</listOfReactants>
<listOfProducts>
<speciesReference species="ES" stoichiometry="1" constant="true" />>
</listOfProducts>
<kineticLaw>
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply>
<times /> 
<ci>comp</ci>
<apply>
<minus /> 
<apply>
<times /> 
<ci>kon</ci>
<ci>E</ci>
<ci>c_e</ci>
<ci>S</ci>
<ci>c_s</ci>
</apply>
<apply>
<times /> 
<ci>koff</ci>
<ci>ES</ci>
<ci>c_es</ci>
</apply>
</apply>
</math>
<listOfLocalParameters>
<localParameter id="kon" value="1000000" units="litre_per_mole_second" /> 
<localParameter id="koff" value="0.2" units="per_second" /> 
</listOfLocalParameters>
</kineticLaw>
</reaction>
<reaction id="vcat" reversible="false">
<listOfReactants>
<speciesReference species="ES" stoichiometry="1" constant="true" />>
</listOfReactants>
<listOfProducts>
<speciesReference species="E" stoichiometry="1" constant="true" />>
<speciesReference species="P" stoichiometry="1" constant="true" />>
</listOfProducts>
<kineticLaw>
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply>
<times /> 
<ci>comp</ci>
<ci>kcat</ci>
<ci>ES</ci>
<ci>c_es</ci>
</apply>
</math>
<listOfLocalParameters>
<localParameter id="kcat" value="0.1" units="per_second" /> 
</listOfLocalParameters>
</kineticLaw>
</reaction>
</listOfReactions>
</model> </sbml>
```

## 7.4 Example of a discrete version of a simple dimerization reaction

*(SBO annotations for this model contributed by Lukas Endler, EMBL-EBI, Cambridge, UK.)*

This example illustrates subtle differences between models formulated for use in a continuous simulation framework (e.g., using differential equations) and those intended for a discrete simulation framework. The
model shown here is suitable for use with a discrete stochastic simulation algorithm of the sort developed by Gillespie (1977). In such an approach, species are described in terms of molecular counts and simulation proceeds by computing the probability of the time and identity of the next reaction, then updating the species amounts appropriately.

The model involves a simple dimerization reaction for a protein named P:

$$2P \leftrightarrow P_2$$

The SBML representation is shown below. There are several notable points. First, species *P* and *P*<sub>2</sub> (represented by “P” and “P<sub>2</sub>”, respectively) are declared to be always in terms of discrete amounts by using the flag hasOnlySubstanceUnits=“true” on the Species object definitions. This indicates that when the species identifiers appear in mathematical formulas, their values have units of substance amount, not {substance amount}/size. A second point is that, as a result, the corresponding KineticLaw formulas do not need volume corrections. In Gillespie’s approach, the constants in the rate expressions (here, *c*<sub>1</sub> and *c*<sub>2</sub>, represented in the SBML model by c<sub>1</sub> and c<sub>2</sub>, respectively) contain a contribution from the kinetic constants of the reaction and the size of the compartment in which the reactions take place. This is a convention commonly adopted by stochastic modelers, but is in no way essential—it is perfectly reasonable to factor volume out of the rate constants, and in certain situations it may be desirable to do so (e.g., for models having time-varying compartment volume), but due to the use of substance units, it must be done differently compared to the deterministic case. Third, although the reaction is reversible, it is encoded as two separate irreversible reactions, one each for the forward and reverse directions, as averaging over the reactions will affect the stochasticity. Finally, note that the rate expression for the forward reaction is a second-order mass-action reaction, but it is the discrete formulation of such a reaction rate (Gillespie, 1977).

```xml
<?xml version="1.0" encoding="UTF-8"?>
<sbml xmlns="http://www.sbml.org/sbml/level3/version2/core" level="3" version="2">
  <model id="dimerization" substanceUnits="item" timeUnits="second"
         volumeUnits="litre" extentUnits="item">
    <listOfUnitDefinitions>
      <unitDefinition id="per_second">
        <listOfUnits>
          <unit kind="second" exponent="-1" scale="0" multiplier="1"/>
        </listOfUnits>
      </unitDefinition>
      <unitDefinition id="per_item_per_second">
        <listOfUnits>
          <unit kind="item" exponent="-1" scale="0" multiplier="1"/>
          <unit kind="second" exponent="-1" scale="0" multiplier="1"/>
        </listOfUnits>
      </unitDefinition>
    </listOfUnitDefinitions>
    <listOfCompartments>
      <compartment id="Cell" size="1e-15" spatialDimensions="3"
                  constant="true" sboTerm="SBO:0000290"/>
    </listOfCompartments>
    <listOfSpecies>
      <species id="P" compartment="Cell" initialAmount="301"
               hasOnlySubstanceUnits="true" boundaryCondition="false"
               constant="false" sboTerm="SBO:0000252"/>
      <species id="P2" compartment="Cell" initialAmount="0"
               hasOnlySubstanceUnits="true" boundaryCondition="false"
               constant="false" sboTerm="SBO:0000420"/>
    </listOfSpecies>
    <reaction id="Dimerization" reversible="false" sboTerm="SBO:0000177">
      <listOfReactants>
        <speciesReference species="P" stoichiometry="2" constant="true"
                          sboTerm="SBO:0000010"/>
      </listOfReactants>
      <listOfProducts>
        <speciesReference species="P2" stoichiometry="1" constant="true"
                          sboTerm="SBO:0000011"/>
      </listOfProducts>
    </reaction>
  </model>
</sbml>
```
```xml
<kineticLaw sboTerm="SBO:0000142">
  <math xmlns="http://www.w3.org/1998/Math/MathML">
    xmlns:sbml="http://www.sbml.org/sbml/level3/version2/core">
    <apply>
      <divide/>
      <apply>
        <times/>
        <ci> c1 </ci>
        <ci> P </ci>
        <apply>
          <minus/>
          <ci> P </ci>
          <cn type="integer" sbml:units="item"> 1 </cn>
        </apply>
      </apply>
      <cn type="integer" sbml:units="dimensionless"> 2 </cn>
    </apply>
  </math>
  <listOfLocalParameters>
    <localParameter id="c1" value="0.00166" units="per_item_per_second"
                  sboTerm="SBO:0000067"/>
  </listOfLocalParameters>
  <kineticLaw>
    <reaction id="Dissociation" reversible="false" sboTerm="SBO:0000180">
      <listOfReactants>
        <speciesReference species="P2" stoichiometry="1" constant="true"
                          sboTerm="SBO:0000010"/>
      </listOfReactants>
      <listOfProducts>
        <speciesReference species="P" stoichiometry="2" constant="true"
                          sboTerm="SBO:0000011"/>
      </listOfProducts>
      <kineticLaw sboTerm="SBO:0000141">
        <math xmlns="http://www.w3.org/1998/Math/MathML">
          <apply>
            <times/>
            <ci> c2 </ci>
            <ci> P </ci>
            <apply>
              <math>
                <listOfLocalParameters>
                  <localParameter id="c2" value="0.2" units="per_second"
                                  sboTerm="SBO:0000066"/>
                </listOfLocalParameters>
              </math>
            </apply>
          </apply>
        </math>
      </kineticLaw>
    </reaction>
    <listOfReactions>
      <model>
        <sbml>
```

This example also illustrates the need to provide additional information in a model so that software tools using different mathematical frameworks can properly interpret it. In this case, a simulation tool designed for continuous ODE-based simulation would likely misinterpret the model (in particular the reaction rate formulas), unless it deduced that a discrete stochastic simulation was intended. One of the purposes of SBO annotations (Section 5 on p. 91) is to enable such interpretation without the need for deduction. However, the interpretation of the model is essentially the same irrespective of whether the model is to be simulated in a deterministic or stochastic manner, and a properly SBML-compliant deterministic simulator will in most cases correctly simulate the continuous deterministic approximation of the stochastic model even if it has no stochastic simulation capability.
The interpretation of rate laws for stochastic models is similar to, yet different from, that of deterministic models. Taking the first reaction as an example, the rate law is $c_1P(P-1)/2$ reaction events per second. In the continuous deterministic case, the interpretation of this is that the extent of the reaction in time $dt$ is $[c_1P(P-1)/2]dt$ (and this leads naturally to the usual ODE formulation of the model). In the stochastic case, the interpretation is that the *propensity* (or *rate*, or *hazard*) of the reaction is $c_1P(P-1)/2$. That is, the *probability* of a single reaction event occurring in time $dt$ is $[c_1P(P-1)/2]dt$ (and note that the *expected* extent of the reaction will be $[c_1P(P-1)/2]dt$. This interpretation leads to a Markov jump process for the system dynamics, where the inter-event times are exponentially distributed. Such dynamics can be simulated using a discrete event simulation algorithm such as the *Gillespie algorithm*. In this case, the algorithm for simulating the model can be described as follows:

1. Initialize $t := 0$, $c_1 := 0.00166$, $c_2 := 0.2$, $P := 301$, $P_2 := 0$

2. Compute $h_1 := c_1P(P-1)/2$, $h_2 := c_2P_2$

3. Compute $h_0 = h_1 + h_2$

4. Simulate $t' \sim \text{Exp}(h_0)$ and set $t := t + t'$

5. With probability $h_1/h_0$ set $P := P-2$, $P_2 := P_2+1$, otherwise set $P := P+2$, $P_2 := P_2-1$.

6. Output $t$, $P$, $P_2$

7. If $t < T_{\text{max}}$, return to step 2, otherwise stop.

Although this is a simulation algorithm is a very practical way of describing how to construct exact realizations of the Markov jump process corresponding to the discrete stochastic kinetic model, it is not a concise mathematical description. Such a description can be provided by writing the model as a time change of a pair of independent unit Poisson processes. Let $N_1(t)$ and $N_2(t)$ be the counting functions of these processes, so that for each $i = 1, 2, t > 0$, $N_i(t) \sim \text{Poisson}(t)$. Then, writing $P(t)$ and $P_2(t)$ for the numbers of molecules of $P$ and $P_2$ at time $t$, respectively, we have that the stochastic process $\{P(t), P_2(t) | t > 0\}$ satisfies the stochastic integral equation

$$P_2(t) = N_1 \left( \int_0^t c_1 \frac{P(\tau)[P(\tau) - 1]}{2} d\tau \right) - N_2 \left( \int_0^t c_2 P_2(\tau) d\tau \right) \\ P(t) = 301 - 2P_2(t).$$

The above representation is arguably the most useful for mathematical analysis of the stochastic model; see Ball et al. (2006) for details. Another popular representation is the so-called chemical Master equation (CME) for the probability distribution of the possible states at all times (Gillespie, 1992). In this case, since there are 151 possible states of the system (corresponding to the 151 possible values of $P_2$), the CME consists of 151 coupled ODEs,

$$\frac{d}{dt} p(P, P_2, t) = \begin{cases} -\frac{c_1}{2} \times 301 \times 299p(301, 0, t) + c_2p(299, 1, t), & P = 301, P_2 = 0, \\ \frac{c_1}{2}(P+2)(P+1)p(P+2, P_2-1, t) - \frac{c_1}{2}P(P-1)p(P, P_2, t) + c_2(P_2+1)p(P-2, P_2+1, t) - c_2P_2p(P, P_2, t), & P = 301-x, P_2 = x, \\ \frac{c_1}{2} \times 2 \times 3p(3, 149, t) - c_2 \times 150p(1, 150, t), & P = 1, P_2 = 150, \end{cases}$$

where $p(P, P_2, t)$ denotes the probability that there are $P$ molecules of $P$ and $P_2$ molecules of $P_2$ at time $t$, and the ODEs are subject to the initial conditions

$$p(301, 0, 0) = 1, p(301 - 2x, x, 0) = 0, x = 1, 2, \dots, 150.$$

See Evans et al. (2008) for further examples of discrete stochastic kinetic models encoded in SBML and Wilkinson (2006) for an introduction to discrete stochastic modeling using SBML.
```xml
<ci> T </ci>
<apply>
    <plus/>
    <cn sbml:units="dimensionless"> 1 </cn>
    <ci> Keq </ci>
</apply>
</math>
</assignmentRule>
<assignmentRule variable="S2">
    <math xmlns="http://www.w3.org/1998/Math/MathML">
        <apply>
            <times/>
            <ci> Keq </ci>
            <ci> S1 </ci>
        </apply>
    </math>
</assignmentRule>
</listOfRules>
<listOfReactions>
    <reaction id="in" reversible="false">
        <listOfReactants>
            <speciesReference species="X0" stoichiometry="1" constant="true"/>
        </listOfReactants>
        <listOfProducts>
            <speciesReference species="T" stoichiometry="1" constant="true"/>
        </listOfProducts>
        <kineticLaw>
            <math xmlns="http://www.w3.org/1998/Math/MathML">
                <apply>
                    <times/>
                    <ci> k1 </ci>
                    <ci> X0 </ci>
                    <ci> cell </ci>
                </apply>
            </math>
        </kineticLaw>
    </reaction>
    <reaction id="out" reversible="false">
        <listOfReactants>
            <speciesReference species="T" stoichiometry="1" constant="true"/>
        </listOfReactants>
        <listOfProducts>
            <speciesReference species="X1" stoichiometry="1" constant="true"/>
        </listOfProducts>
        <listOfModifiers>
            <modifierSpeciesReference species="S2"/>
        </listOfModifier>
        <kineticLaw>
            <math xmlns="http://www.w3.org/1998/Math/MathML">
                <apply>
                    <times/>
                    <ci> k2 </ci>
                    <ci> S2 </ci>
                    <ci> cell </ci>
                </apply>
            </math>
        </kineticLaw>
    </reaction>
    <listOfReactions>
        <math>
            <listOfLocalParameters>
                <localParameter id="k2" value="0.15" units="per_second"/>
            </listOfLocalParameters>
        </math>
    </listOfReactions>
</model>
</sbml>
```
## 7.6 Example involving algebraic rules

This section contains an example model that contains two **AlgebraicRule** objects that are necessary to determine the values of two variables within the model. In this particular case, the rules cannot be rewritten in terms of **AssignmentRule**. This example illustrates a more rigorous analysis of the enzymatic reaction given in the example of Section 7.1 on p. 113.

$$E + S \underset{k1_{off}}{\overset{k1_{on}}{\rightleftharpoons}} ES \xrightarrow{k2} E + P$$

In this example, we describe a quasi-steady-state approximation of the enzymatic reaction equation shown above. It is based on two assumptions. First, the rate at which the concentration of the substrate bound enzyme ([ES]) changes is assumed to be slow compared to the rate of change of concentration of both the substrate ([S]) and product ([P]). Second, the total concentration of the enzyme is assumed to stay constant over time. This means we can assume the concentration of [ES] and [E] are not governed by the reactions, and so some other equations must be used to determine the values of these concentrations in order to be able to simulate the model.

Applying the first assumption means that the rate of change of [ES] should be set to zero:

$$\frac{d[ES]}{dt} = k1_{on} \cdot [E] \cdot [S] - (k1_{off} + k2) \cdot [ES] = 0$$

The second assumption can be written as

$$[E_{total}] = [E] + [ES]$$

which, after rearranging, becomes

$$[E_{total}] - ([E] + [ES]) = 0$$

Thus, we have two algebraic rules that must be applied to determine the values of [E] and [ES]. The SBML encoding of this model is given below. Note that the species E and ES have their **boundaryCondition** attribute set to “true”. This means that a simulation tool should not construct equations for them based on the reactions in the system. Their values are instead set using the rules in the model. Also, the model uses a dummy species E<sub>total</sub> with its **constant** attribute set to “true”; its role is to assign the total concentration of the enzyme in the model. This could just as easily have been done using a parameter instead of a constant dummy species, but we use the latter approach as an illustration.

```xml
<?xml version="1.0" encoding="UTF-8" ?>
<sbml xmlns="http://www.sbml.org/sbml/level3/version2/core" level="3" version="2">
<model substanceUnits="mole" volumeUnits="litre" timeUnits="second" extentUnits="mole">
<listOfUnitDefinitions>
<unitDefinition id="per_second">
<listOfUnits>
<unit kind="second" exponent="-1" scale="0" multiplier="1"/>
</listOfUnits>
</unitDefinition>
<unitDefinition id="mole_per_litre">
<listOfUnits>
<unit kind="mole" exponent="1" scale="0" multiplier="1"/>
<unit kind="litre" exponent="-1" scale="0" multiplier="1"/>
</listOfUnits>
</unitDefinition>
<unitDefinition id="litre_per_mole_per_second">
<listOfUnits>
<unit kind="litre" exponent="1" scale="0" multiplier="1"/>
<unit kind="mole" exponent="-1" scale="0" multiplier="1"/>
<unit kind="second" exponent="-1" scale="0" multiplier="1"/>
</listOfUnits>
</unitDefinition>
</listOfUnitDefinitions>
<listOfCompartments>
<compartment id="cell" size="1" spatialDimensions="3" constant="true"/>
```
```xml
<speciesReference species="ES" stoichiometry="1" constant="true"/>
</listOfReactants>
<listOfProducts>
<speciesReference species="E" stoichiometry="1" constant="true"/>
<speciesReference species="P" stoichiometry="1" constant="true"/>
</listOfProducts>
<kineticLaw>
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply> <times/> <ci> cell </ci> <ci> k2 </ci> <ci> ES </ci> </apply>
</math>
</kineticLaw>
</reaction>
</listOfReactions>
</model>
</sbml>
```

## 7.7 Example with combinations of `boundaryCondition` and `constant` values on Species with RateRule objects

In this section, we discuss a model that includes four species, each with a different combination of values for their `boundaryCondition` and `constant` attributes. The model represents a hypothetical system containing one reaction,

$$S_1 + S_2 \xrightarrow{k_1[S_1][S_2][S_3]} S_4$$

where $S_3$ is a species that catalyzes the conversion of species $S_1$ and $S_2$ into $S_4$. Species $S_1$ and $S_2$ are on the boundary of the system (i.e., $S_1$ and $S_2$ are reactants but their values are not determined by kinetic laws). The value of $S_1$ in the system is determined over time by the rate rule:

$$\frac{d[S_1]}{dt} = k_2$$

The species $S_2$ and $S_3$ are not affected by the either the reaction or the rate rule, and have the following initial concentration values:

$$[S_2] = 1, \quad [S_3] = 2$$

The values of constant parameters in the system are:

$$k_1 = 0.5, \quad k_2 = 0.1$$

and the initial values of varying species are:

$$[S_1] = 0, \quad [S_4] = 0$$

The value of $[S_1]$ varies over time and it is on the boundary, so in the SBML representation, $S_1$ has a `constant` attribute with a value of `false` and a `boundaryCondition` attribute with a value of `true`. The value of $[S_2]$ is fixed and it is also on the boundary, so $S_2$ has a `constant` attribute value of `false` and a `boundaryCondition` attribute value of `true`. $[S_3]$ is fixed but not on the boundary, so the `constant` attribute is `true` and the `boundaryCondition` attribute is `false`. Finally, $[S_4]$ is a product whose value is determined by a kinetic law and therefore in the SBML representation has `false` for both its `boundaryCondition` and `constant` attributes.

The following is the SBML rendition of the model shown above:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<sbml xmlns="http://www.sbml.org/sbml/level3/version2/core" level="3" version="2">
<model id="BoundaryCondExampleModel"
      volumeUnits="litre" substanceUnits="mole" timeUnits="second" extentUnits="mole">
  <listOfUnitDefinitions>
    <unitDefinition id="mole_per_litre_per_second">
      <listOfUnits>
        <unit kind="mole" exponent="1" scale="0" multiplier="1"/>
      </listOfUnits>
    </unitDefinition>
  </listOfUnitDefinitions>
</model>
```
```xml
<unit kind="litre" exponent="-1" scale="0" multiplier="1"/>
<unit kind="second" exponent="-1" scale="0" multiplier="1"/>
</listOfUnits>
</unitDefinition>
<unitDefinition id="litre_sq_per_mole_sq_per_second">
  <listOfUnits>
    <unit kind="mole" exponent="-2" scale="0" multiplier="1"/>
    <unit kind="litre" exponent="2" scale="0" multiplier="1"/>
    <unit kind="second" exponent="-1" scale="0" multiplier="1"/>
  </listOfUnits>
</unitDefinition>
</listOfUnitDefinitions>
</listOfCompartments>
<compartment id="compartmentOne" size="1" spatialDimensions="3" constant="true"/>
</listOfCompartments>
<listOfSpecies>
  <species id="S1" initialConcentration="0" compartment="compartmentOne" constant="false" hasOnlySubstanceUnits="false" boundaryCondition="true"/>
  <species id="S2" initialConcentration="1" compartment="compartmentOne" constant="false" hasOnlySubstanceUnits="false" boundaryCondition="true"/>
  <species id="S3" initialConcentration="3" compartment="compartmentOne" constant="false" hasOnlySubstanceUnits="false" boundaryCondition="false"/>
  <species id="S4" initialConcentration="0" compartment="compartmentOne" constant="false" hasOnlySubstanceUnits="false" boundaryCondition="false"/>
</listOfSpecies>
<listOfParameters>
  <parameter id="k1" value="0.5" units="litre_sq_per_mole_sq_per_second" constant="true"/>
  <parameter id="k2" value="0.1" units="mole_per_litre_per_second" constant="true"/>
</listOfParameters>
<listOfRules>
  <rateRule variable="S1">
    <math xmlns="http://www.w3.org/1998/Math/MathML">
      <ci> k2 </ci>
    </math>
  </rateRule>
</listOfRules>
<listOfReactions>
  <reaction id="reaction_1" reversible="false">
    <listOfReactants>
      <speciesReference species="S1" stoichiometry="1" constant="true"/>
      <speciesReference species="S2" stoichiometry="1" constant="true"/>
    </listOfReactants>
  </reaction>
  <listOfProducts>
    <speciesReference species="S4" stoichiometry="1" constant="true"/>
  </listOfProducts>
  <listOfModifiers>
    <modifierSpeciesReference species="S3"/>
  </listOfModifierS>
  <kineticLaw>
    <math xmlns="http://www.w3.org/1998/Math/MathML">
      <apply>
        <times/>
        <ci> k1 </ci>
        <ci> S1 </ci>
        <ci> S2 </ci>
        <ci> S3 </ci>
        <ci> compartmentOne </ci>
      </apply>
    </math>
  </kineticLaw>
</listOfReactions>
</model>
</sbml>
```
## 7.8 Example of translation from a multi-compartmental model to ODEs

This section contains a model with two compartments and four reactions. The model is derived from Lotka-Volterra, with the addition of a reversible transport step. When observed in a time-course simulation, three of this model's species display damped oscillations.

<figure><img src="image_38.png" /><figcaption>Figure 29: An example multi-compartmental model.</figcaption></figure>

Figure 29 illustrates the arrangement of compartments and reactions in the model LotkaVolterra_transport. The reaction between the compartments called cytosol and nucleus is a transport reaction whose mechanisms are not modeled here; in particular, the reaction does not take place on the membrane between the compartments, and is modeled here simply as a process that spans the two three-dimensional compartments.

The text of the SBML representation of the model is shown below, and it is followed by its complete translation into ordinary differential equations. As usual, in this SBML model, the reaction rate equations in the kinetic laws are in substance per time units. The reactions have also been simplified to reduce common stoichiometric factors in the original system depicted in Figure 29. The species variables in this SBML representation are in concentration units; their initial quantities are declared using the attribute `initialAmount` on the species definitions, but since the attribute `hasOnlySubstanceUnits` is not set to true, the identifiers of the species represent their concentrations when those identifiers appear in mathematical expressions elsewhere in the model. Note that the species whose identifier is “X” is a boundary condition, as indicated by the attribute `boundaryCondition="true"` in its definition.

```xml
<?xml version="1.0" encoding="UTF-8"?>
<sbml xmlns="http://www.sbml.org/sbml/level3/version2/core" level="3" version="2">
<model name="LotkaVolterra_transport" substanceUnits="mole" volumeUnits="litre"
        extentUnits="mole" timeUnits="second">
<listOfUnitDefinitions>
<unitDefinition id="per_second">
<listOfUnits>
<unit kind="second" exponent="-1" scale="0" multiplier="1"/>
</listOfUnits>
</unitDefinition>
<unitDefinition id="litre_per_mole_per_second">
<listOfUnits>
<unit kind="mole" exponent="-1" scale="0" multiplier="1"/>
<unit kind="litre" exponent="1" scale="0" multiplier="1"/>
<unit kind="second" exponent="-1" scale="0" multiplier="1"/>
</listOfUnits>
</unitDefinition>
</listOfUnitDefinitions>
<listOfCompartments>
<compartment id="cytoplasm" size="5" constant="true" spatialDimensions="3"/>
<compartment id="nucleus" size="1" constant="true" spatialDimensions="3"/>
</listOfCompartments>
<listOfSpecies>
<species id="X" compartment="nucleus" initialAmount="1" constant="false"
        boundaryCondition="true" hasOnlySubstanceUnits="false"/>
<species id="Y1n" compartment="nucleus" initialAmount="1" constant="false"
        boundaryCondition="false" hasOnlySubstanceUnits="false"/>
<species id="Y1c" compartment="cytoplasm" initialAmount="0" constant="false"
        boundaryCondition="false" hasOnlySubstanceUnits="false"/>
<species id="Y2" compartment="cytoplasm" initialAmount="1" constant="false"
        boundaryCondition="false" hasOnlySubstanceUnits="false"/>
</listOfSpecies>
<listOfParameters>
<parameter id="k1" value="2500" units="litre_per_mole_per_second" constant="true"/>
</listOfParameters>
```
```xml
<parameter id="k2" value="2500" units="litre_per_mole_per_second" constant="true"/>
<parameter id="KT" value="25000" units="per_second" constant="true"/>
<parameter id="k3" value="2500" units="per_second" constant="true"/>
</listOfParameters>
<listOfReactions>
    <reaction id="production" reversible="false">
        <listOfReactants>
            <speciesReference species="X" stoichiometry="1" constant="true"/>
            <speciesReference species="Y1n" stoichiometry="1" constant="true"/>
        </listOfReactants>
        <listOfProducts>
            <speciesReference species="Y1n" stoichiometry="1" constant="true"/>
            <speciesReference species="Y1n" stoichiometry="1" constant="true"/>
        </listOfProducts>
        <kineticLaw>
            <math xmlns="http://www.w3.org/1998/Math/MathML">
                <apply>
                    <times/>
                    <ci>nucleus</ci>
                    <ci>k1</ci>
                    <ci>X</ci>
                    <ci>Y1n</ci>
                </apply>
            </math>
        </kineticLaw>
    </reaction>
    <reaction id="transport" reversible="true">
        <listOfReactants>
            <speciesReference species="Y1n" stoichiometry="1" constant="true"/>
        </listOfReactants>
        <listOfProducts>
            <speciesReference species="Y1c" stoichiometry="1" constant="true"/>
        </listOfProducts>
        <kineticLaw>
            <math xmlns="http://www.w3.org/1998/Math/MathML">
                <apply>
                    <times/>
                    <ci>cytoplasm</ci>
                    <ci>KT</ci>
                    <apply>
                        <minus/>
                        <ci>Y1n</ci>
                        <ci>Y1c</ci>
                    </apply>
                </apply>
            </math>
        </kineticLaw>
    </reaction>
    <reaction id="transformation" reversible="false">
        <listOfReactants>
            <speciesReference species="Y1c" stoichiometry="1" constant="true"/>
            <speciesReference species="Y2" stoichiometry="1" constant="true"/>
        </listOfReactants>
        <listOfProducts>
            <speciesReference species="Y2" stoichiometry="2" constant="true"/>
        </listOfProducts>
        <kineticLaw>
            <math xmlns="http://www.w3.org/1998/Math/MathML">
                <apply>
                    <times/>
                    <ci>cytoplasm</ci>
                    <ci>k2</ci>
                    <ci>Y1c</ci>
                    <ci>Y2</ci>
                </apply>
            </math>
        </kineticLaw>
    </reaction>
    <reaction id="degradation" reversible="false">
```
```xml
<listOfReactants>
    <speciesReference species="Y2" stoichiometry="1" constant="true"/>
</listOfReactants>
<kineticLaw>
    <math xmlns="http://www.w3.org/1998/Math/MathML">
        <apply>
            <times/>
            <ci>cytoplasm</ci>
            <ci>k3</ci>
            <ci>Y2</ci>
        </apply>
    </math>
</kineticLaw>
<reaction>
    <listOfReactions>
        <model>
            <sbml>
```

The ODE translation of this model is as follows. First, we give the values of the constant parameters:

$$k_1 = 2500 \text{ litre mole}^{-1} \text{ second}^{-1}$$

$$k_2 = 2500 \text{ litre mole}^{-1} \text{ second}^{-1}$$

$$K_3 = 25000 \text{ second}^{-1}$$

$$K_T = 25000 \text{ second}^{-1}$$

Now on to the initial conditions of the variables. In the following, the terms $[X]$, $[Y_{1n}]$, $[Y_{1c}]$, and $[Y_2]$ refer to the species' concentrations. Note that the corresponding species identifiers **X**, **Y_1n**, **Y_1c** and **Y_2** in the model are in concentration units, even though all the values in the model are initialized in terms of amounts. (The reason the species identifiers in the model are still in concentration units goes back to the meaning of the `hasOnlySubstanceUnits` attribute on a **Species**; if the attribute is set to a value of `false`, a species' symbol in a model is interpreted as a concentration or density regardless of whether its initial value is set using `initialAmount` or `initialConcentration`.) We use $V_n$ to represent the size of compartment "nucleus" and $V_c$ the size of compartment "cytoplasm":

$$V_n = 1 \text{ litre}$$

$$V_c = 5 \text{ litre}$$

$$X = 1 \text{ mole}$$

$$Y_{1n} = 1 \text{ mole}$$

$$Y_{1c} = 0 \text{ mole}$$

$$Y_2 = 1/5 \text{ mole}$$

And finally, here are the differential equations:

$$\frac{d[X]}{dt} = 0$$

$$V_n \frac{d[Y_{1n}]}{dt} = k_1[X][Y_{1n}]V_n - K_T([Y_{1n}] - [Y_{1c}])V_c \quad \text{reactions production and transport}$$

$$V_c \frac{d[Y_{1c}]}{dt} = K_T([Y_{1n}] - [Y_{1c}])V_c - k_2[Y_{1c}][Y_2]V_c \quad \text{reactions transport and transformation}$$

$$V_c \frac{d[Y_2]}{dt} = k_2[Y_{1c}][Y_2]V_c - k_3[Y_2]V_c \quad \text{reactions transformation and degradation}$$

As formulated here, this example assumes constant volumes. If the sizes of the compartments "cytoplasm" or "nucleus" could change during simulation, then it would be preferable to use a different approach to constructing the differential equations. In this alternative approach, the ODEs would compute substance change rather than concentration change, and the concentration values would be computed using separate equations. This approach is used in Section 4.11.7 on p. 77.
## 7.9 Example involving function definitions

This section contains a model that uses the function definition feature of SBML. Consider the following hypothetical system:

$$S_1 \xrightarrow{f([S_1])} S_2$$

where

$$f(x) = 2x$$

The following is the XML document that encodes the model shown above:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<sbml xmlns="http://www.sbml.org/sbml/level3/version2/core" level="3" version="2">
<model id="Example" substanceUnits="mole" volumeUnits="litre"
        timeUnits="second" extentUnits="mole">
<listOfUnitDefinitions>
<unitDefinition id="conc">
<listOfUnits>
<unit kind="mole" multiplier="1" scale="0" exponent="1"/>
<unit kind="litre" multiplier="1" scale="0" exponent="-1"/>
</listOfUnits>
</unitDefinition>
</listOfUnitDefinitions>
<listOfFunctionDefinitions>
<functionDefinition id="f">
<math xmlns="http://www.w3.org/1998/Math/MathML"
       xmlns:sbml="http://www.sbml.org/sbml/level3/version2/core">
<lambda>
<bvar>
<ci> x </ci>
</bvar>
<apply>
<times/>
<ci> x </ci>
<cn sbml:units="dimensionless"> 2 </cn>
</apply>
</lambda>
</math>
</functionDefinition>
</listOfFunctionDefinitions>
<listOfCompartments>
<compartment id="compartmentOne" size="1" spatialDimensions="3" constant="true"/>
</listOfCompartments>
<listOfSpecies>
<species id="S1" initialConcentration="1" compartment="compartmentOne"
          hasOnlySubstanceUnits="false" boundaryCondition="false"
          constant="false"/>
<species id="S2" initialConcentration="0" compartment="compartmentOne"
          hasOnlySubstanceUnits="false" boundaryCondition="false"
          constant="false"/>
</listOfSpecies>
<listOfParameters>
<parameter id="t" value = "1" constant="true"/>
</listOfParameters>
<listOfReactions>
<reaction id="reaction_1" reversible="false">
<listOfReactants>
<speciesReference species="S1" stoichiometry="1" constant="true"/>
</listOfReactants>
<listOfProducts>
<speciesReference species="S2" stoichiometry="1" constant="true"/>
</listOfProducts>
<kineticLaw>
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply>
<divide/>
<apply>
```
<times/> <apply> <ci> f </ci> <ci> S1 </ci> </apply> <ci> compartmentOne </ci> </apply> <ci> t </ci> </apply> </math> </kineticLaw> </reaction> </listOfReactions> </model> </sbml>

7.10 Example involving delay functions

The following is a simple model illustrating the use of delay to represent a gene that suppresses its own expression. The model can be expressed in a single rule:

$$
\frac{d[P]}{dt} = \frac{\frac{1}{1 + m[P_{\text{delayed}}]^q} - [P]}{\tau}
$$

where

[P<sub>delayed</sub>] is delay([P], Δ<sub>t</sub>) or [P] at t − Δ<sub>t</sub>

[P] is protein concentration

τ is the response time

m is a multiplier or equilibrium constant

q is the Hill coefficient

and the species quantities are in concentration units. The text of an SBML encoding of this model is given below:

<?xml version="1.0" encoding="UTF-8"?> <sbml xmlns="http://www.sbml.org/sbml/level3/version2/core" level="3" version="2"> <model substanceUnits="mole" volumeUnits="litre" extentUnits="mole" timeUnits="second"> <listOfUnitDefinitions> <unitDefinition id="conc"> <listOfUnits> <unit kind="mole" multiplier="1" scale="0" exponent="1"/> <unit kind="litre" multiplier="1" scale="0" exponent="-1"/> </listOfUnits> </unitDefinition> <unitDefinition id="conc_sq"> <listOfUnits> <unit kind="mole" multiplier="1" scale="0" exponent="2"/> <unit kind="litre" multiplier="1" scale="0" exponent="-2"/> </listOfUnits> </unitDefinition> </listOfUnitDefinitions> <listOfCompartments> <compartment id="cell" size="1" spatialDimensions="3" constant="true"/> </listOfCompartments> <listOfSpecies> <species id="P" compartment="cell" initialConcentration="0" hasOnlySubstanceUnits="false" boundaryCondition="false" constant="false"/> </listOfSpecies> <listOfParameters> <parameter id="tau" value="1" units="second" constant="true"/> <parameter id="m" value="0.5" units="dimensionless" constant="true"/> <parameter id="q" value="1" units="dimensionless" constant="true"/> <parameter id="delta_t" value="1" units="second" constant="true"/> </listOfParameters>
```xml
</listOfParameters>
<listOfRules>
<rateRule variable="P">
<math xmlns="http://www.w3.org/1998/Math/MathML"
      xmlns:sbml="http://www.sbml.org/sbml/level3/version2/core">
<apply>
  <divide/>
  <apply>
    <minus/>
    <apply>
      <divide/>
      <cn sbml:units="conc_sq">1</cn>
    </apply>
    <plus/>
    <cn sbml:units="conc">1</cn>
  </apply>
  <times/>
  <ci> m </ci>
  <apply>
    <power/>
    <apply>
      <csymbol
        encoding="text"
        definitionURL="http://www.sbml.org/sbml/symbols/delay">
        delay
        <csymbol>
          <ci> P </ci>
          <ci> delta_t </ci>
        </csymbol>
      </apply>
      <ci> q </ci>
    </apply>
  </apply>
</apply>
</apply>
</apply>
</apply>
</apply>
</listOfRules>
</model>
</sbml>
```

## 7.11 Example involving events

This section presents a simple model system that demonstrates the use of events in SBML. Consider a system with two genes, $G_1$ and $G_2$. $G_1$ is initially on and $G_2$ is initially off. When turned on, the two genes lead to the production of two products, $P_1$ and $P_2$, respectively, at a fixed rate. When $P_1$ reaches a given concentration, $G_2$ switches on. This system can be represented mathematically as follows:

$$ \frac{d[P_1]}{dt} = k_1([G_1] - [P_1]) $$

$$ \frac{d[P_2]}{dt} = k_2([G_2] - [P_2]) $$

$$ [G_2] = \begin{cases} 0 & \text{when } [P_1] \le \tau, \\ 1 & \text{when } [P_1] > \tau. \end{cases} $$

The initial values are:

$$ [G_1] = 1, \quad [G_2] = 0, \quad \tau = 0.25, \quad P_1 = 0, \quad P_2 = 0, \quad k_1 = k_2 = 1. $$

The SBML Level 3 representation of this is as follows:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<sbml xmlns="http://www.sbml.org/sbml/level3/version2/core" level="3" version="2">
    xmlns:math="http://www.w3.org/1998/Math/MathML"
    xmlns:sbml="http://www.sbml.org/sbml/level3/version2/core">
    <model substanceUnits="mole" volumeUnits="litre" timeUnits="second"
        extentUnits="mole">
        <listOfUnitDefinitions>
            <unitDefinition id="per_second">
                <listOfUnits>
                    <unit kind="second" exponent="-1" scale="0" multiplier="1"/>
                </listOfUnits>
            </unitDefinition>
            <unitDefinition id="concentration">
                <listOfUnits>
                    <unit kind="mole" exponent="1" scale="0" multiplier="1"/>
                    <unit kind="litre" exponent="-1" scale="0" multiplier="1"/>
                </listOfUnits>
            </unitDefinition>
        </listOfUnitDefinitions>
        <listOfCompartments>
            <compartment id="cell" size="1" spatialDimensions="3" constant="true"/>
        </listOfCompartments>
        <listOfSpecies>
            <species id="P1" compartment="cell" initialConcentration="0"
                hasOnlySubstanceUnits="false" boundaryCondition="false"
                constant="false"/>
            <species id="P2" compartment="cell" initialConcentration="0"
                hasOnlySubstanceUnits="false" boundaryCondition="false"
                constant="false"/>
        </listOfSpecies>
        <listOfParameters>
            <parameter id="k1" value="1" units="per_second" constant="true"/>
            <parameter id="k2" value="1" units="per_second" constant="true"/>
            <parameter id="tau" value="0.25" units="concentration" constant="true"/>
            <parameter id="G1" value="1" units="concentration" constant="false"/>
            <parameter id="G2" value="0" units="concentration" constant="false"/>
        </listOfParameters>
        <listOfRules>
            <rateRule variable="P1">
                <math:math>
                    <math:apply>
                        <math:times/>
                        <math:ci> k1 </math:ci>
                        <math:apply>
                            <math:minus/>
                            <math:ci> G1 </math:ci>
                            <math:ci> P1 </math:ci>
                        </math:apply>
                    </math:apply>
                </math:math>
            </rateRule>
            <rateRule variable="P2">
                <math:math>
                    <math:apply>
                        <math:times/>
                        <math:ci> k2 </math:ci>
                        <math:apply>
                            <math:minus/>
                            <math:ci> G2 </math:ci>
                            <math:ci> P2 </math:ci>
                        </math:apply>
                    </math:apply>
                </math:math>
            </rateRule>
        </listOfRules>
        <listOfEvents>
            <event useValuesFromTriggerTime="true">
                <trigger persistent="false" initialValue="true"/>
            </trigger>
        </listOfEvents>
    </model>
</sbml>
```
```xml
<math:math>
  <math:apply>
    <math:gt/>
    <math:ci> P1 </math:ci>
    <math:ci> tau </math:ci>
  </math:apply>
</math:math>
</trigger>
<listOfEventAssignments>
  <eventAssignment variable="G2">
    <math:math>
      <math:cn sbml:units="concentration"> 1 </math:cn>
    </math:math>
  </eventAssignment>
</listOfEventAssignments>
</event>
<event useValuesFromTriggerTime="true">
  <trigger persistent="false" InitialValue="true">
    <math:math>
      <math:apply>
        <math:leq/>
        <math:ci> P1 </math:ci>
        <math:ci> tau </math:ci>
      </math:apply>
    </math:math>
  </trigger>
</eventAssignment>
</listOfEventAssignments>
</event>
<event useValuesFromTriggerTime="true">
  <trigger persistent="false" InitialValue="true">
    <math:math>
      <math:apply>
        <math:leq/>
        <math:ci> P1 </math:ci>
        <math:ci> tau </math:ci>
      </math:apply>
    </math:math>
  </trigger>
</eventAssignment>
</listOfEventAssignments>
</event>
</model>
</sbml>
```

## 7.12 Example involving two-dimensional compartments

The following example is a model that uses a two-dimensional compartment. It is a fragment of a larger model of calcium regulation across the plasma membrane of a cell. The model includes a calcium influx channel, “Ca_channel”, and a calcium-extruding PMCA pump, “Ca_Pump”. It also includes two cytosolic proteins that buffer calcium via the “CalciumCalbindin_gt_BoundCytosol” and “CalciumBuffer_gt_BoundCytosol” reactions. Finally, the rate expressions in this model do not include explicit factors of the compartment volumes; instead, the various rate constants are assumed to include any necessary corrections for volume.

```xml
<?xml version="1.0" encoding="UTF-8"?>
<sbml xmlns="http://www.sbml.org/sbml/level3/version2/core" level="3" version="2">
  <model id="facilitated_ca_diffusion" substanceUnits="substance"
    areaUnits="area" volumeUnits="litre" timeUnits="second" extentUnits="substance">
    <listOfUnitDefinitions>
      <unitDefinition id="substance">
        <listOfUnits>
          <unit kind="mole" exponent="1" scale="-6" multiplier="1"/>
        </listOfUnits>
      </unitDefinition>
      <unitDefinition id="area">
        <listOfUnits>
          <unit kind="metre" exponent="2" scale="-6" multiplier="1"/>
        </listOfUnits>
      </unitDefinition>
      <unitDefinition id="per_second">
        <listOfUnits>
          <unit kind="second" exponent="-1" scale="0" multiplier="1"/>
        </listOfUnits>
      </unitDefinition>
      <unitDefinition id="litre_per_mole_per_second">
```
```xml
<listOfUnits>
  <unit kind="mole" exponent="-1" scale="-6" multiplier="1"/>
  <unit kind="litre" exponent="1" scale="0" multiplier="1"/>
  <unit kind="second" exponent="-1" scale="0" multiplier="1"/>
</listOfUnits>
</unitDefinition>
<unitDefinition id="subs_per_vol">
  <listOfUnits>
    <unit kind="mole" exponent="1" scale="-6" multiplier="1"/>
    <unit kind="litre" exponent="-1" scale="0" multiplier="1"/>
  </listOfUnits>
</unitDefinition>
</listOfUnitDefinitions>
<listOfCompartments>
  <compartment id="Extracellular" spatialDimensions="3" size="1" constant="true"/>
  <compartment id="PlasmaMembrane" spatialDimensions="2" size="1" constant="true"/>
  <compartment id="Cytosol" spatialDimensions="3" size="1" constant="true"/>
</listOfCompartments>
<listOfSpecies>
  <species id="CaBPB_C" compartment="Cytosol" initialConcentration="47.17" hasOnlySubstanceUnits="false" boundaryCondition="false" constant="false"/>
  <species id="B_C" compartment="Cytosol" initialConcentration="396.04" hasOnlySubstanceUnits="false" boundaryCondition="false" constant="false"/>
  <species id="CaB_C" compartment="Cytosol" initialConcentration="3.96" hasOnlySubstanceUnits="false" boundaryCondition="false" constant="false"/>
  <species id="Ca_C" name="Ca" compartment="Cytosol" initialConcentration="0.1" hasOnlySubstanceUnits="false" boundaryCondition="false" constant="false"/>
  <species id="Ca_EC" name="Ca" compartment="Extracellular" initialConcentration="1000" hasOnlySubstanceUnits="false" boundaryCondition="false" constant="false"/>
  <species id="CaCh_PM" compartment="PlasmaMembrane" initialConcentration="1" hasOnlySubstanceUnits="false" boundaryCondition="false" constant="false"/>
  <species id="CaPump_PM" compartment="PlasmaMembrane" initialConcentration="1" hasOnlySubstanceUnits="false" boundaryCondition="false" constant="false"/>
  <species id="CaBP_C" compartment="Cytosol" initialConcentration="202.83" hasOnlySubstanceUnits="false" boundaryCondition="false" constant="false"/>
</listOfSpecies>
<listOfReactions>
  <reaction id="CalciumCalbindin_gt_BoundCytosol" reversible="true">
    <listOfReactants>
      <speciesReference species="CaBP_C" stoichiometry="1" constant="true"/>
      <speciesReference species="Ca_C" stoichiometry="1" constant="true"/>
    </listOfReactants>
    <listOfProducts>
      <speciesReference species="CaBPB_C" stoichiometry="1" constant="true"/>
    </listOfProducts>
    <kineticLaw>
      <notes>
        <p xmlns="http://www.w3.org/1999/xhtml">
          (((Kf_CalciumCalbindin_BoundCytosol * CaBP_C) * Ca_C) -
          (Kr_CalciumCalbindin_BoundCytosol * CaBPB_C))
        </p>
      </notes>
      <math xmlns="http://www.w3.org/1998/Math/MathML">
        <apply>
          <times/>
        </apply>
      </math>
    </kineticLaw>
  </reaction>
</listOfReactions>
```
1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69
(J0 * Kc * (Ca_EC - Ca_C) / (Kc + Ca_C) * CaCh_PM)
</p>
</notes>
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply>
  <times/>
  <ci>PlasmaMembrane</ci>
</apply>
<divide/>
<apply>
  <times/>
  <ci>CaCh_PM</ci>
  <ci>J0</ci>
  <ci>Kc</ci>
</apply>
<minus/>
<ci>Ca_EC</ci>
<ci>Ca_C</ci>
</apply>
</apply>
<apply>
  <plus/>
  <ci>Kc</ci>
  <ci>Ca_C</ci>
</apply>
</apply>
</apply>
</math>
<listOfLocalParameters>
  <localParameter id="J0" value="0.014" units="litre_per_mole_per_second"/>
  <localParameter id="Kc" value="0.5" units="subs_per_vol"/>
</listOfLocalParameters>
</kineticLaw>
</reaction>
<listOfReactions>
</model>
</sbml>

7.13 Example of a reaction located at a membrane

This section describes a model containing one single enzymatic reaction where substrate and product are
located in the same compartment but the enzyme is localized at the membrane surrounding the compartment.

$$
R: S \xrightarrow{[E]} P
$$

The model contains two compartments, a three-dimensional one called “cytosol” and a two-dimensional one called “membrane” that is assumed to be the boundary of the cell. The reaction *R* has a substrate *S* and a product *P* that are both located in the cytosol. The enzyme *E* that catalyzes the reactions is located at the membrane. The kinetic law of reaction *R* is

$$
v = A \cdot \frac{k_{\text{cat}} \cdot [E] \cdot [S]}{K_{\text{M}} + [S]}
$$

where *A* is the area of the membrane (measured in µm²), [*E*] is the density of the enzyme on the membrane (in µmol µm⁻²), [*S*] is the concentration of the substrate (in µmol l⁻¹), *K*<sub>M</sub> the Michaelis-Menten constant (also in µmol l⁻¹), and *k*<sub>cat</sub> the rate constant (in min⁻¹). The units of the result of the kinetic law are in µmol min⁻¹. Since the units for the amounts of all species (*S*, *P*, and *E*) and for the reaction extent are the same (µmol) the model does not require unit conversion factors.

The kinetic law as it is given here scales correctly for changes in cytosol volume, membrane area, or enzyme
density. This means that if one of these values is changed (even if it varies during a simulation) the rate
expression remains valid.

The following is the text of the model’s SBML representation.
```xml
<?xml version="1.0" encoding="UTF-8"?>
<sbml xmlns="http://www.sbml.org/sbml/level3/version2/core" level="3" version="2">
<model id="Model_1" name="Reaction on membrane" substanceUnits="micromole"
        timeUnits="minute" extentUnits="micromole">
<listOfFunctionDefinitions>
<functionDefinition id="MM_enzyme" name="MM_enzyme">
<math xmlns="http://www.w3.org/1998/Math/MathML">
<lambda>
<bvar> <ci> size </ci> </bvar>
<bvar> <ci> k </ci> </bvar>
<bvar> <ci> enz </ci> </bvar>
<bvar> <ci> subs </ci> </bvar>
<bvar> <ci> Km </ci> </bvar>
<apply>
<divide/>
<apply>
<times/>
<ci> size </ci>
<ci> k </ci>
<ci> enz </ci>
<ci> subs </ci>
</apply>
<apply>
<plus/>
<ci> Km </ci>
<ci> subs </ci>
</apply>
</apply>
</lambda>
</math>
</functionDefinition>
<listOfFunctionDefinitions>
<listOfUnitDefinitions>
<unitDefinition id="minute">
<listOfUnits>
<unit kind="second" exponent="1" scale="0" multiplier="60"/>
</listOfUnits>
</unitDefinition>
<unitDefinition id="per_minute">
<listOfUnits>
<unit kind="second" exponent="-1" scale="0" multiplier="60"/>
</listOfUnits>
</unitDefinition>
<unitDefinition id="micromole">
<listOfUnits>
<unit kind="mole" exponent="1" scale="-6" multiplier="1"/>
</listOfUnits>
</unitDefinition>
<unitDefinition id="micromole_per_1">
<listOfUnits>
<unit kind="mole" exponent="1" scale="-6" multiplier="1"/>
<unit kind="litre" exponent="-1" scale="0" multiplier="1"/>
</listOfUnits>
</unitDefinition>
<unitDefinition id="sqrmicrometre">
<listOfUnits>
<unit kind="metre" exponent="2" scale="-6" multiplier="1"/>
</listOfUnits>
</unitDefinition>
<listOfUnitDefinitions>
<listOfCompartments>
<compartment id="cyt" name="Cytosol"
             spatialDimensions="3" units="litre"
             size="1e-15" constant="true"/>
<compartment id="mem" name="Membrane"
             spatialDimensions="2" units="sqrmicrometre"
             size="1" constant="true"/>
</listOfCompartments>
```
```xml
<listOfSpecies>
  <species id="species_1" name="substrate" compartment="cyt"
    hasOnlySubstanceUnits="false" boundaryCondition="false"
    initialConcentration="1" constant="false"/>
  <species id="species_2" name="product" compartment="cyt"
    hasOnlySubstanceUnits="false" boundaryCondition="false"
    initialConcentration="1" constant="false"/>
  <species id="species_3" name="enzyme" compartment="mem"
    hasOnlySubstanceUnits="false" boundaryCondition="false"
    initialConcentration="1" constant="false"/>
</listOfSpecies>
<listOfReactions>
  <reaction id="reaction_1" name="Reaction" reversible="false"
    compartment="mem">
    <listOfReactants>
      <speciesReference species="species_1" stoichiometry="1" constant="true"/>
    </listOfReactants>
    <listOfProducts>
      <speciesReference species="species_2" stoichiometry="1" constant="true"/>
    </listOfProducts>
    <listOf modifiers>
      <modifierSpeciesReference species="species_3"/>
    </listOf Modifiers>
    <kineticLaw>
      <math xmlns="http://www.w3.org/1998/Math/MathML">
        <apply>
          <ci>MM_enzyme</ci>
          <ci>mem</ci>
          <ci>k</ci>
          <ci>species_3</ci>
          <ci>species_1</ci>
          <ci>Km</ci>
        </apply>
      </math>
    </kineticLaw>
  </reaction>
</listOfReactions>
</model>
</sbml>
```

### 7.14 Example using an event with a non-persistent trigger and a delay

This example illustrates the syntax and use of the **Trigger** object on **Event**, particularly the **persistent** attribute, as well as the optional **Delay** object on **Event**. In the model below, the event has a trigger expression that tests the value of species "a" in the model, and if the value comes within the range $0.999 \le a \le 1.001$, the event triggers and reassigns the value of "c" after a delay of 3 seconds.

```xml
<?xml version="1.0" encoding="UTF-8"?>
<sbml xmlns="http://www.sbml.org/sbml/level3/version2/core" level="3" version="2">
  <model id="PersistentEvent" timeUnits="second">
    <listOfUnitDefinitions>
      <unitDefinition id="mol_per_l">
        <listOfUnits>
          <unit kind="mole" exponent="1" scale="0" multiplier="1"/>
          <unit kind="litre" exponent="-1" scale="0" multiplier="1"/>
        </listOfUnits>
      </unitDefinition>
      <unitDefinition id="l_per_s">
        <listOfUnits>
          <unit kind="litre" exponent="1" scale="0" multiplier="1"/>
          <unit kind="second" exponent="-1" scale="0" multiplier="1"/>
        </listOfUnits>
      </unitDefinition>
    </listOfUnitDefinitions>
  </model>
</sbml>
```
```xml
<listOfCompartments>
    <compartment id="compartment" size="1" units="litre"
        spatialDimensions="3" constant="true"/>
</listOfCompartments>
<listOfSpecies>
    <species id="d" initialConcentration="0" boundaryCondition="true"
        compartment="compartment" substanceUnits="mole"
        hasOnlySubstanceUnits="false" constant="false"/>
    <species id="a" initialConcentration="2" boundaryCondition="false"
        compartment="compartment" substanceUnits="mole"
        hasOnlySubstanceUnits="false" constant="false"/>
    <species id="b" initialConcentration="0" boundaryCondition="false"
        compartment="compartment" substanceUnits="mole"
        hasOnlySubstanceUnits="false" constant="false"/>
    <species id="c" initialConcentration="0" boundaryCondition="false"
        compartment="compartment" substanceUnits="mole"
        hasOnlySubstanceUnits="false" constant="false"/>
    <species id="e" initialConcentration="0" boundaryCondition="false"
        compartment="compartment" substanceUnits="mole"
        hasOnlySubstanceUnits="false" constant="false"/>
</listOfSpecies>
<listOfParameters>
    <parameter id="k1" value="0.2" constant="true" units="l_per_s"/>
</listOfParameters>
<listOfRules>
    <assignmentRule variable="e">
        <math xmlns="http://www.w3.org/1998/Math/MathML">
            <cn type="integer" sbml:units="mol_per_l"> 1 </cn>
        </math>
    </assignmentRule>
</listOfRules>
<listOfReactions>
    <reaction id="_J0" reversible="false">
        <listOfReactants>
            <speciesReference species="a" constant="true" stoichiometry="1"/>
        </listOfReactants>
    </reaction>
    <listOfProducts>
        <speciesReference species="d" constant="true" stoichiometry="1"/>
    </listOfProducts>
    <kineticLaw>
        <math xmlns="http://www.w3.org/1998/Math/MathML">
            <apply>
                <times/>
                <ci> k1 </ci>
                <ci> a </ci>
            </apply>
        </math>
    </kineticLaw>
</reaction>
</listOfReactions>
<listOfEvents>
    <event useValuesFromTriggerTime="true">
        <!-- If persistent is 'false', c won't be set to '6', but if it's 'true', it will. -->
        <trigger persistent="false" initialValue="true">
            <math xmlns="http://www.w3.org/1998/Math/MathML">
                <apply>
                    <and/>
                    <apply>
                        <leq/>
                        <ci> a </ci>
                        <cn> 1.001 </cn>
                    </apply>
                </apply>
            </math>
        </trigger>
        <apply>
            <geq/>
            <ci> a </ci>
            <cn> 0.999 </cn>
        </apply>
    </event>
</listOfEvents>
</math>
```
```xml
</trigger>
```

```xml
<delay>
```

```xml
<math xmlns="http://www.w3.org/1998/Math/MathML">
```

```xml
<cn type="integer" sbml:units="second"> 3 </cn>
```

```xml
</math>
```

```xml
</delay>
```

```xml
<listOfEventAssignments>
```

```xml
<eventAssignment variable="c">
```

```xml
<math xmlns="http://www.w3.org/1998/Math/MathML">
```

```xml
<cn type="integer" sbml:units="mol_per_1"> 6 </cn>
```

```xml
</math>
```

```xml
</eventAssignment>
```

```xml
</listOfEventAssignments>
```

```xml
</event>
```

```xml
</listOfEvents>
```

```xml
</model>
```

```xml
</sbml>
```
# 8 Recommended practices

In this section, we recommend a number of practices for using and interpreting various SBML constructs. These recommendations are non-normative, but we advocate them strongly; ignoring them will not render a model invalid, but may hinder interoperability between different software systems exchanging SBML content.

## 8.1 Recommended practices concerning common SBML attributes and objects

Many SBML components share some or all of the following attributes and objects. We describe recommendations concerning them here, separately from discussing the specific SBML components. In Section 8.2 on p. 148, we turn to the specific SBML components, but the recommendations described here also apply to them.

### 8.1.1 Identifiers and names

The `id` attribute is available on most (but not all) objects in SBML, and all objects that have `id` attributes also have an optional `name` attribute. How should models treat identifiers and names?

The following is the recommended practice for handling `name`. If a software tool has the capability to display the content of `name` attributes, it should display this content to the user as a component's label instead of the component's `id`. If the user interface does not have this capability (e.g., because it cannot display or use special characters in symbol names), or if the `name` attribute is missing on a given component, then the user interface should display the value of the `id` attribute instead.

As a consequence of the above, authors of software systems that automatically generate values for `id` attributes should be aware some other systems may display the `id`'s to the user. (Script language interpreters are especially likely to display `id` instead of `name`.) Authors therefore may wish to take some care to have their software create `id` values that are: (a) reasonably easy for humans to type and read, and (b) likely to be meaningful (e.g., by making the `id` attribute is an abbreviated form of the `name` attribute value).

### 8.1.2 Initial Values

SBML allows for the creation of `Compartment`, `Species`, `Parameter`, `LocalParameter` and `SpeciesReference` objects without declaring their initial values directly on the object instances. That is, a `Compartment` object can be created without defining a value for its `size` attribute; a `Species` object can be created without defining a value for either its `initialConcentration` or `initialAmount` attribute; `Parameter` and `LocalParameter` objects can be created without giving a value to their `value` attributes; and a `SpeciesReference` object can be created without assigning a value to its `stoichiometry` attribute. A missing value in the case of `Compartment`, `Species`, `Parameter`, and `SpeciesReference` objects implies that the value is either set via an `InitialAssignment` object elsewhere in the model, or is meant to be obtained from an external source (e.g., by querying the user of a software system), or is unknown. In the case of `LocalParameter` objects, a missing value implies that the value is either unknown or meant to be obtained from an external source.

Where initial values are available and are decimal numbers that can be set using the appropriate attribute on an object, the best practice recommendation is to do that in preference to using an `InitialAssignment` construct if there is no particular reason to use `InitialAssignment`. Setting the relevant attribute directly on the `Compartment`, `Species`, and `Parameter` and `SpeciesReference` object is simpler and may be more interoperable with different software systems. This is especially true of `stoichiometry` on `SpeciesReference`, which in the vast majority of models, is never more than a constant floating-point value anyway.

An additional point is worth noting in passing. Although the value attributes of various SBML components are of type `double` (e.g., `Parameter`'s attribute `value`), this does not mean that component values are limited only to decimal numbers. As noted above, other constructs such as `InitialAssignment` can be used to set the value of an object, and since those constructs offer the power of MathML, the results may be rational numbers such as fractions. Software developers should be aware of this possibility when planning the type of storage variables used to hold SBML objects' values.
### 8.1.3 The constant flag

There is a mandatory **boolean** attribute called **constant** on the **Compartment**, **Species**, **SpeciesReference** and **Parameter** components. A value of **true** means that the SBML object in question will not be changed by other constructs in SBML except possibly an **InitialAssignment**. A value of **false** indicates an intention to change the element's value by an **AssignmentRule**, **RateRule**, **AlgebraicRule**, **Reaction** or **Event** in the model.

A **constant** attribute value of **false** does not require that the object in question is changed; strictly speaking, an SBML model is valid even if it sets all **constant** attributes to **false** but never actually modify any of the values. However, the best practice recommendation is to communicate intentions by setting **constant** to **true** unless an entity in a model really is intended to be changed. The exception to this is **Species**, which are usually part of the reaction system and thus usually need to have **constant**="false".

### 8.1.4 Annotations

#### Use of Identifiers.org

All of the examples of annotations in this specification use URIs from the service hosted at Identifiers.org (Juty et al., 2012). The use of Identifiers.org URIs is not required by SBML, but it is considered a current best practice for SBML annotations. Regardless of whether Identifiers.org URIs are used, a general best practice for URIs used in annotations is that they should be chosen to be as persistent as possible, so future consumers of SBML documents can continue to dereference and understand the annotations.

#### Appropriate uses of annotations

In the description of the **Annotation** object available on every component derived from **SBase** (Section 3.2.6 on p. 16), we already made the point that it is critical not to put data essential to understanding a model into annotations. This raises a question: what kind of data may be appropriately put into annotations? Here are some examples:

* Identification information for cross-referencing components in a model with items in a data resource such as a database. This is the purpose of the annotation scheme described in Section 6 on p. 100.

* Application-specific processing instructions that do not change the essential meaning of a model, but help a particular application with tasks such as managing the model, maintaining state data across editing sessions, etc.

* Evidence codes for annotating a model with controlled vocabulary terms that indicate (e.g.) the quality of biological evidence supporting the inclusion of each component in the model. The annotation scheme of Section 6 on p. 100 can be used in this capacity.

* Information about the model that cannot be readily encoded in existing SBML elements, but that does not alter the mathematical meaning of the model.

#### Specificity of annotations

The annotation data (Section 3.2.6 on p. 16) attached to a specific SBML object in a model is assumed by other applications to be directly associated with that particular object. Therefore, it is important to decompose and locate annotation data appropriately in an SBML document. Applications are advised to avoid encoding all their annotations in a single top-level attribute on (e.g.) the **Model** object. The data associated with, for example, an individual **Species** object in a model should be encoded in the `<annotation>` element enclosed within the SBML `<species>` element representing that species in the SBML file.

#### Syntax of annotations

The annotation scheme described in Section 6 on p. 100 is useful for many, but not all, situations. It is tempting to develop new annotation syntaxes for situations that fall outside the scope of the SBML MIRIAM annotation scheme. However, a proliferation of proprietary annotation schemes will hinder software interoperability in the long run.
We recommend the following approach when faced with a need to use alternate annotation syntaxes:

1. The modular nature of SBML Level 3 Version 2 Core means that data that in SBML Level 2 could only be stored in annotations may now be supported using a full SBML Level 3 package. Therefore, software developers and modelers should first check if there already exists a package that may serve their needs. A list of SBML Level 3 packages is always maintained at the SBML website, http://sbml.org.

2. If no package exists, developers and modelers may wish to check if someone else has already developed a similar annotation syntax for use with another software system. A list of known SBML annotation schemes is maintained online at http://sbml.org/Community/Wiki/Known_SBML_annotations.

3. If none of the above alternatives provide a satisfactory result, developers and modelers should query the SBML discussion list (sbml-discuss@caltech.edu) to see if anyone else has been faced with similar problems. Other SBML users may have insights or even partial solutions already available.

## 8.2 Recommended practices concerning specific SBML components

In this section, we describe expectations and recommendations concerning specific SBML components. We do not reiterate the recommendations presented in Section 8.1 on p. 146, but they apply to many of the SBML components discussed here and should be kept in mind. The order of the components discussed here follows the order of their presentation in Section 4 on p. 34, but we only include here those components for which we have specific recommendations.

### 8.2.1 Unit definitions

We advise modelers and software tools to declare the units of all quantities in a model, insofar as this is possible, using the various mechanisms provided for this in SBML. Fully declared units can allow software tools to perform dimensional analysis on the units of mathematical expressions, and such analysis can be valuable in helping modelers produce correct models. In addition, it can allow model-wide operations such as conversion or rescaling of units.

#### Recommendations for choices of units

Table 9 on the next page lists the units recommended for different SBML components. While a single unit will typically be used in each situation, combinations of the recommended types may also be used, such as mmol/g for substance elements that are calculated in terms of milimoles per gram dry weight.

#### Handling units requiring the use of offsets

As already mentioned, unit definitions and conversions that require offsets cannot be done directly using the simple UnitDefinition and Unit system in SBML. In fact, SBML does not predefine a unit for Celsius precisely because it would require the use of an offset, and so its inclusion would result in an inconsistent system. Definitions involving Celsius, Fahrenheit or other units with offsets require a different approach.

We discuss approaches to handling units with offsets, starting with the case of degrees Celsius:

* Handling Celsius. A model in which certain quantities are temperatures measured in degrees Celsius can be converted straightforwardly to a model in which those temperatures are in kelvin. A software tool could do this by performing a substitution using the following relationship:

$$T_{\text{kelvin}} = T_{\text{Celsius}} + 273.15$$

In every mathematical formula of the model where a quantity (call it $x$) in degrees Celsius appears, replace $x$ with $x_k + 273.15$ where $x_k$ is now in kelvin. An alternative approach would be to use a FunctionDefinition to define a function encapsulating this relationship above and then using that in the rest of the model as needed. Since Celsius is a commonly-used unit, software tools could help users by providing users with the ability to express temperatures in Celsius in the tools' interfaces, and making substitutions automatically when writing out SBML.
<table><caption>**Table 9:** Units recommended for use on different SBML model components. Note that avogadro is considered to be derived from dimensionless as a consequence of its definition; see Section 4.4.2 on p. 43.</caption><thead><tr><th>Component attribute</th><th>Unit recommendations</th></tr></thead><tbody><tr><td>Model substanceUnits</td><td>mole, item, dimensionless, kilogram, gram, or units derived from these</td></tr><tr><td>Model timeUnits</td><td>second, dimensionless, or units derived from these</td></tr><tr><td>Model volumeUnits</td><td>litre, metre<sup>3</sup>, dimensionless, or units derived from these</td></tr><tr><td>Model areaUnits</td><td>metre<sup>2</sup>, dimensionless, or units derived from these</td></tr><tr><td>Model lengthUnits</td><td>metre, dimensionless, or units derived from these</td></tr><tr><td>Model extentUnits</td><td>mole, item, dimensionless, kilogram, gram, or units derived from these</td></tr><tr><td>Compartment units</td><td><table><thead><tr><th>Value of attribute<br>spatialDimensions</th><th>Recommended units</th></tr></thead><tbody><tr><td>"3"</td><td>litre, metre<sup>3</sup>, dimensionless, or units derived from these</td></tr><tr><td>"2"</td><td>metre<sup>2</sup>, dimensionless, or units derived from these</td></tr><tr><td>"1"</td><td>metre, dimensionless, or units derived from these</td></tr><tr><td>other</td><td>no specific recommendations</td></tr></tbody></table></td></tr><tr><td>Species substanceUnits</td><td>mole, item, dimensionless, kilogram, gram, or units derived from these</td></tr><tr><td>Parameter units</td><td>no specific recommendations</td></tr></tbody></table>

* Handling other units requiring offsets. The only other units requiring offsets in SBML's domain of common applications are other temperature units such as Fahrenheit. Few modern scientists employ Fahrenheit degrees; therefore, this is an unusual situation. The complication inherent in converting between degrees Fahrenheit and kelvin is that both a multiplier and an offset are required:

$$T_{\text{kelvin}} = \frac{T_{\text{F}} + 459.67}{1.8}$$

One approach to handling this is to use a **FunctionDefinition** to define a function encapsulating the relationship above, then to substitute a call to this function wherever the original temperature in Fahrenheit appears in the model's mathematical formulas. We provide a candidate definition in Figure 30 on the following page.

An alternative approach not requiring the use of function definitions is to use an **AssignmentRule** for each variable in Fahrenheit units. The **AssignmentRule** could compute the conversion from Fahrenheit to (say) kelvin, assign its value to a variable (with units declared to be "kelvin"), and then that variable could be used elsewhere in the model. Still another approach is to rewrite the mathematical formulas of a model to directly incorporate the conversion above wherever the quantity appears.

All of these approaches provide general solutions to the problem of supporting any units requiring offsets in the unit system of SBML Level 3. It can be used for other temperature units requiring an offset (e.g., degrees Rankine or degrees Réaumur), although the likelihood of a real-life model requiring such other temperature units seems exceedingly small.

In summary, the fact that SBML units do not support specifying an offset does not impede the creation of models using alternative units. If conversions are needed, then converting between temperature in degrees Celsius and thermodynamic temperature can be handled rather easily by the simple substitution described above. For the rare case of Fahrenheit and other units requiring combinations of multipliers and offsets, users are encouraged to employ the power of **FunctionDefinition**, **AssignmentRule**, or other constructs in SBML.
<figure><img src="image_39.png" /><figcaption>**Figure 30:** SBML fragment showing a candidate definition of a function to convert Fahrenheit temperature to kelvin, along with necessary unit definitions to make the definition complete.</figcaption></figure>

## 8.2.2 Compartments

### Setting the size attribute on a compartment

As mentioned in Section 4.5.3 on p. 47, we highly recommend that every **Compartment** object in a model has its **size** set. There are three major technical reasons for this. First, if the model contains any species whose initial amounts are given in terms of concentrations, and there is at least one reaction in the model referencing such a species, then the model will be numerically incomplete if it lacks a value for the size of the compartment in which the species is located. The reason is that SBML reactions are expected to be in terms of intensive properties such as *amount/time* (or more generally, *extent units/time units*; see Section 4.11.7 on p. 78), and converting from concentration to amount requires knowing the compartment size. Second, models ideally should be capable of being instantiated in a variety of simulation frameworks. A commonly-used one is the discrete stochastic framework (Gillespie, 1977; Wilkinson, 2006) in which species are represented as item counts (e.g., molecule counts). If species' initial quantities are given in terms of concentrations or densities, it is impossible to convert the values to item counts without knowing compartment sizes. Third, if a model contains multiple compartments whose sizes are not all identical to each other, it is impossible to quantify the reaction rate expressions without knowing the compartment volumes. The reason for the latter is again that reaction rates in SBML are defined in terms *extent/time*, and when species quantities are given in terms of concentrations or densities, the compartment sizes usually become factors in the reaction rate expressions.
Indicating a default compartment

Some types of models do not use compartments, for example because they factor out volumes completely. Since SBML requires at least one compartment to be defined if any species exists in a model, the representation of models where no compartments are needed sometimes leaves model creators wishing they could indicate that a compartment is only a “default” in some sense. The recommended approach to handling this situation is to annotate the **Compartment** object by setting its **sboTerm** attribute to an appropriate SBO term, specifically “SBO:0000410”.

8.2.3 Rules

Section 4.9.5 on p. 64 establishes the fact that when **AlgebraicRule** objects are used, it is possible to produce a model that is overdetermined. When a model includes both **Event** and **Reaction** objects, it is necessary to analyze the set of equations produced from the rules and reactions and the set of equations produced from rules and the event assignments of each event. Each set of equations must not be overdetermined. In addition, each set of equations must be fully determined if accurate simulation is to be performed.

The following example illustrates a case where the set of equations is fully determined. First, we present the SBML expression of the model:
```xml
<speciesReference species="S2" stoichiometry="1" constant="true"/>
</listOfProducts>
<kineticLaw>
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply> <times/> <ci> C </ci> <ci> k1 </ci> <ci> S1 </ci>
</apply>
</math>
<listOfLocalParameters>
<localParameter id="k1" value="0.1" units="per_second"/>
</listOfLocalParameters>
</kineticLaw>
</reaction>
</listOfReactions>
<listOfEvents>
<event useValuesFromTriggerTime="true">
<trigger persistent="false" InitialValue="true">
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply> <gt/> <ci> S2 </ci> <ci> p1 </ci> </apply>
</math>
</trigger>
<listOfEventAssignments>
<eventAssignment variable="S1">
<math xmlns="http://www.w3.org/1998/Math/MathML">
<ci> p1 </ci>
</math>
</eventAssignment>
<eventAssignment variable="S2">
<math xmlns="http://www.w3.org/1998/Math/MathML">
<ci> p2 </ci>
</math>
</eventAssignment>
</listOfEventAssignments>
</event>
</listOfEvents>
</model>
</sbml>
```

There are three species in the model above whose values may vary. The first set of equations to consider is the set produced by the **Reaction** and the **AlgebraicRule** objects:

$$ 
\begin{aligned}
\frac{d[S_1]}{dt} &= -C \cdot k_1 \cdot [S_1] \\
\frac{d[S_2]}{dt} &= C \cdot k_1 \cdot [S_1] \\
[S_1] - [S_2] &= 0
\end{aligned}
$$

This set of equations is fully determined, i.e., each of the three variables $S_1$, $S_2$ and $S_3$ are derived from one equation. The second set of equations to consider is produced by the **Event** and the **AlgebraicRule** objects:

$$ 
\begin{aligned}
[S_1] &= 1 \\
[S_2] &= 1.5 \\
[S_1] - [S_2] &= 0
\end{aligned}
$$

Again the set of equations is fully determined, but had the event assignment for species $S_1$ been absent, the algebraic rule would produce an ambiguity regarding which variable should be adjusted.

In this example, as is often the case when an **AlgebraicRule** has been used, the **AlgebraicRule** could be replaced by an **AssignmentRule**:

```xml
<assignmentRule variable="S3">
<math xmlns="http://www.w3.org/1998/Math/MathML">
<ci> S1 </ci>
</math>
</assignmentRule>
```
Replacing **AlgebraicRule** objects with **AssignmentRule** objects, particularly in models that use events, reduces the possibilities for creating either overdetermined or ambiguous models and produces models that can be exchanged with greater ease.

### 8.2.4 Reactions

Consider a very simple model consisting of a single enzymatic reaction *R* that converts *S*₁ to *S*₂ for which a traditional kinetic law *v*<sub>R</sub> is given:

$$S_1 \xrightarrow{v_R} S_2$$

where

$$v_R = \frac{v_{\max} \cdot [S_1]}{K_M + [S_1]}$$

with *v*<sub>R</sub> and *v*<sub>max</sub> given in units of concentration per time.

As mentioned above, when a rate law is presented in the traditional way, it usually embodies (implicitly or explicitly) several assumptions: that all species are located in the same compartment, that the compartment size does not change, and that the reaction takes place uniformly throughout the volume of the compartment, i.e. the enzyme is not localized in any special way. Under these circumstances it is possible to construct rate equations for the concentration of the species:

$$\frac{d[S_2]}{dt} = -\frac{d[S_1]}{dt} = v_R$$

In SBML, however, the rate equations are constructed for the rate of change of the *amount* of the species:

$$\frac{dn_{S_2}}{dt} = -\frac{dn_{S_1}}{dt} = \hat{v}_R = V \cdot v_R$$

where $\hat{v}_R$ is the modified SBML kinetic law and *V* is the volume of the compartment. Since the traditional kinetic law *v*<sub>R</sub> describes how fast the amount of the species changes *per volume*, the SBML kinetic law $\hat{v}_R$ simply equals the product of *v*<sub>R</sub> and the compartment volume *V*. This means that the actual rate of change of the amounts of the species is proportional to the compartment size, which will only be true if the reaction takes place uniformly throughout the compartment. (See Section 7.13 on p. 141 for an example of a reaction that is located at the boundary of a compartment.) The concentrations of the species (that are needed in the definition of *v*<sub>R</sub>) can easily be recovered through the relation [*S*<sub>i</sub>] = *n*<sub>S<sub>i</sub></sub>/*V*.

An important property of the amount rate equation is that it is still valid if the volume *V* changes during a simulation. This is not true for the concentration rate equations.

### 8.2.5 Events

The following recommendations concern **Event** objects and their subcomponents.

#### Undefined ordering

Section 4.12 on p. 79 describes how to interpret SBML events; however, the explanation explicitly leaves *undefined* how events should be ordered in the absence of priorities attached to the events. This curious omission in the specification reflects the state of agreement in biological modeling software today, but at the same time, it does not help software developers with the goal of implementing support for SBML events.

In practice, a variety of simple approaches can satisfy the “undefined ordering” requirement. For example, a software system could assign an arbitrary priority value to all events with undefined priorities. Another approach is for a simulator to execute the events in whatever order they happen to be stored in the implementation of the software. This part of SBML event behavior is left up to developers.

Regardless of the above, developers should keep in mind that the ordering requirements for events with **Priority** subobjects *are* defined, including for the case where such events in the model are mixed with events having
undefined priorities. For example, if a model contains three simultaneously-firing events, one with priority 10, one with priority 4, and one with an undefined priority (call it $X$), there are three valid results for an implementation following the combined priority and “undefined ordering” requirements in SBML: 10-4-X, 10-X-4, and X-10-4. The implementation could always pick the same option among those three (as would happen if it assigned events with undefined priorities an artificial priority value, as mentioned above), or it could pick randomly between the three alternatives on different simulation runs, as it would if it were trying to be robustly stochastic. But the simulator should never execute the events in the order 4-10-X, nor should it quit unexpectedly. By defining the events in the model in this way, the creator of the model has clearly stated that the event with priority 10 should be executed before the event with priority 4, and that the event with $X$ must also be executed at some point. Beyond that, nothing more can be said or assumed about the modeler’s intention.

## Simultaneous event execution

Another concern with SBML events is how to implement true “simultaneous” execution of events. A model defines the conditions mathematically, but software realizations generally need to use numerical methods; the limited precision inherent with numerical methods can result in the system not executing precisely at the same time events that are meant to be simultaneous, or conversely, executing simultaneously some events that are *not* meant to be exactly simultaneous. Calculating the time of event execution depends on finding the trigger time, because an event’s execution time is the sum (counting from the simulation start time) of the trigger time plus any delay in the event. If two events have the same delay but different triggers, they should trigger simultaneously if the moment that their trigger expressions transition to “true” is the same.

In part, the ultimate behavior may depend on how the modeler has written the model, and careful modelers will write models that are robust against slight numerical imprecision. For their part, software developers can take steps to increase the likelihood that the times at which trigger expressions transition in value are all detected equally, by doing such things as caching the calculated times at which embedded Boolean subexpressions in **Trigger** formulas switch their truth states. (For example, given two events, one with trigger expression [$(s1 > 5) \ \& \ (s2 > 7)$] and the other with trigger expression [$(s1 > 5) \ \& \ (s3 > 10)$], the time at which $s1$ transitions from less than 5 to greater than 5 can be calculated just once, cached, and reused thereafter, thereby helping to mitigate against small timing differences that might occur if the expression is reevaluated at different times.) If the trigger times are thus numerically identical, and if they have the same delay equation (which should also be cached if need be, for the same reason), they will then execute simultaneously, as they were intended to do in the model.

When creating models containing (e.g.) two events $A$ and $B$ that have different delays, model authors should not expect to achieve simultaneous execution simply by arranging for the sum of $A$'s trigger time plus $A$'s delay to be equal to the sum of $B$'s trigger time plus $B$'s delay. It is unlikely that different software implementations will resolve the execution times precisely in the same way, so it is unlikely the model will behave as the author expected in this scenario.
# A Validation and consistency rules for SBML

This section summarizes all the conditions that must (or in some cases, at least *should*) be true of a model encoded in SBML Level 3 Core format. We use the following conventions in the list of rules that follow:

* There are different degrees of rule strictness. Formally, the differences are expressed in the statement of a rule: either a rule states that a condition *must* be true, or a rule states that it *should* be true. Rules of the former kind are strict SBML validation rules—a model encoded in SBML must conform to all of them in order to be considered valid. Rules of the latter kind are consistency rules. To help highlight these differences, we use the following three symbols next to the rule numbers:

* [x] A checked box indicates a *requirement* for SBML conformance. If a model does not follow this rule, it does not conform to the SBML specification. (Mnemonic intention behind the choice of symbol: "This must be checked.")

* [x] A triangle indicates a *recommendation* for model consistency. If a model does not follow this rule, it is not considered strictly invalid as far as the SBML specification is concerned; however, it indicates that the model contains a physical or conceptual inconsistency. (Mnemonic intention behind the choice of symbol: "This is a cause for warning.")

* [x] A star indicates a strong recommendation for good modeling practice. This rule is not strictly a matter of SBML encoding, but the recommendation comes from logical reasoning. As in the previous case, if a model does not follow this rule, it is not strictly considered an invalid SBML encoding. (Mnemonic intention behind the choice of symbol: "You're a star if you heed this.")

* Most rules have existed in previous Levels/Versions of SBML. Note that, because each SBML specification is independent, the precise details of a given rule in *this* specification may differ slightly from its formulation in other Levels/Versions, to reflect changes in SBML Level 3; however, the essential purpose of the rule will be the same.

* Rules that may have been introduced in lower Levels/Versions of SBML sometimes are removed in higher Levels/Versions. (This can happen, for example, if they become irrelevant due to changes in the language in a higher Level or Version of SBML.) Rule numbers, however, remain unique and are never reused for a different purpose. Consequently, there exist gaps in the sequence numbers of the rules.

* New rules introduced by this SBML Level 3 specification are indicated by an underlined rule number (e.g., 10104 instead of 10104).

* XML element attributes mentioned in the following validation and consistency rules have no XML namespace prefix, and must appear in SBML documents without any explicit XML namespace, even if the declared namespace is otherwise correct for SBML Level 3.

## General rules concerning basic XML requirements

10101. [x] An SBML XML file must use UTF-8 as the character encoding. More precisely, the *encoding* attribute of the XML declaration at the beginning of the XML data stream cannot have a value other than "UTF-8". An example valid declaration is `<?xml version="1.0" encoding="UTF-8"?>`. (References: SBML L3V1 Section 4.1; SBML L3V2 Section 4.1.)

10102. [x] An SBML XML document must not contain undefined elements or attributes in the SBML Level 3 Core namespace or in a SBML Level 3 package namespace. Documents containing unknown elements or attributes placed in an SBML namespace do not conform to the SBML specification. (References: SBML L3V1 Section 4.1; SBML L3V2 Section 4.1.)

10104. [x] An SBML document must conform to the rules of XML well-formedness defined in the XML 1.0 specification. These rules define the basic structural and syntactic constraints with which all XML documents must comply. (References: SBML L3V1 Section 4.1; SBML L3V2 Section 4.1.)
General rules for MathML content in SBML

10201. ✓ Wherever MathML content appears in an SBML document, the MathML content must be placed within a **math** element, and that **math** element must be either explicitly or implicitly declared to be in the XML namespace "http://www.w3.org/1998/Math/MathML". (References: SBML L3V1 Section 3.4; SBML L3V2 Section 3.4.)

10202. ✓ The following is a list of the only MathML 2.0 elements permitted in SBML Level 3: **abs**, **and**, **annotation**, **annotation-xml**, **apply**, **arccosh**, **arccos**, **arccoth**, **arccot**, **arccsch**, **arccsc**, **arcsech**, **arcsec**, **arcsinh**, **arcsin**, **arctanh**, **arctan**, **bvar**, **ceiling**, **ci**, **cn**, **cosh**, **cos**, **coth**, **cot**, **csch**, **csc**, **csymbol**, **degree**, **divide**, **eq**, **exponentiale**, **exp**, **factorial**, **false**, **floor**, **geq**, **gt**, **implies**, **infinity**, **lambda**, **leq**, **ln**, **logbase**, **log**, **lt**, **max**, **min**, **minus**, **neq**, **notanumber**, **not**, **or**, **otherwise**, **piecewise**, **piece**, **pi**, **plus**, **power**, **quotient**, **rem**, **root**, **sech**, **sec**, **semantics**, **sep**, **sinh**, **sin**, **tanh**, **tan**, **times**, **true**, and **xor**. An SBML package may allow new MathML elements to be added to this list, and if so, the package must define **required**="true" on the SBML container element <sbml>. (References: SBML L3V1 Section 3.4.1; SBML L3V2 Section 3.4.1.)

10203. ✓ In the SBML subset of MathML 2.0, the MathML attribute **encoding** is only permitted on **csymbol**, **annotation** and **annotation-xml**. No other MathML elements may have an **encoding** attribute. An SBML package may allow the **encoding** attribute on other elements, and if so, the package must define **required**="true" on the SBML container element <sbml>. (References: SBML L3V1 Section 3.4.1; SBML L3V2 Section 3.4.1.)

10204. ✓ In the SBML subset of MathML 2.0, the MathML attribute **definitionURL** is only permitted on **ci**, **csymbol** and **semantics**. No other MathML elements may have a **definitionURL** attribute. An SBML package may allow the **definitionURL** attribute on other elements, and if so, the package must define **required**="true" on the SBML container element <sbml>. (References: SBML L3V1 Section 3.4.1; SBML L3V2 Section 3.4.1.)

10205. ✓ In SBML Level 3, the only values permitted for the attribute **definitionURL** on a **csymbol** are "http://www.sbml.org/sbml/symbols/time", "http://www.sbml.org/sbml/symbols/delay", "http://www.sbml.org/sbml/symbols/avogadro", and "http://www.sbml.org/sbml/symbols/rateOf". An SBML package may allow new values for the **definitionURL** attribute of a **csymbol**, and if so, the package must define **required**="true" on the SBML container element <sbml>. (References: SBML L3V1 Section 3.4.6; SBML L3V2 Section 3.4.6.)

10206. ✓ In the SBML subset of MathML 2.0, the MathML attribute **type** is only permitted on the **cn** construct. No other MathML elements may have a **type** attribute. An SBML package may allow the **type** attribute on other elements, and if so, the package must define **required**="true" on the SBML container element <sbml>. (References: SBML L3V1 Section 3.4.1; SBML L3V2 Section 3.4.1.)

10207. ✓ The only permitted values for the attribute **type** on MathML **cn** elements are "e-notation", "real", "integer", and "rational". An SBML package may allow new values for the **type** attribute, and if so, the package must define **required**="true" on the SBML container element <sbml>. (References: SBML L3V1 Section 3.4.2; SBML L3V2 Section 3.4.2.)

10208. ✓ MathML **lambda** elements are only permitted as either the first element inside the **math** element of a **FunctionDefinition** object, or as the first element of a **semantics** element immediately inside the **math** element of a **FunctionDefinition** object. MathML **lambda** elements may not be used elsewhere in an SBML model. An SBML package may allow **lambda** elements on other elements, and if so, the package must define **required**="true" on the SBML container element <sbml>. (References: SBML L3V1 Section 3.4.1 and 4.3.2; SBML L3V2 Section 3.4.1 and Section 4.3.2.)

10209. ✓ (This validation rule does not apply in SBML Level 3 Version 2 Core.) <fnref n="1" />

<footnote n="1">¹Original rule: "The arguments of the MathML logical operators **and**, **not**, **or**, and **xor** must evaluate to Boolean values."</footnote>
10210. ☑ (This validation rule does not apply in SBML Level 3 Version 2 Core.) <fnref n="2" />

10211. ☑ (This validation rule does not apply in SBML Level 3 Version 2 Core.) <fnref n="3" />

10212. ▲ (This validation rule does not apply in SBML Level 3 Version 2 Core.) <fnref n="4" />

10213. ☑ (This validation rule does not apply in SBML Level 3 Version 2 Core.) <fnref n="5" />

10214. ☑ Outside of a **FunctionDefinition** object, if a MathML **ci** element is the first element within a MathML **apply** element, then the **ci** element's value can only be chosen from the set of identifiers of **FunctionDefinition** objects defined in the enclosing SBML **Model** object. (References: SBML L3V1 Section 4.3.2; SBML L3V2 Section 4.3.2.)

10215. ☑ Outside of a **FunctionDefinition** object, if a MathML **ci** element is not the first element within a MathML **apply**, then the **ci** element's value may only be chosen from the following set of identifiers: the identifiers of **Species**, **Compartment**, **Parameter**, **SpeciesReference** and **Reaction** objects defined in the enclosing **Model** object; the identifiers of **LocalParameter** objects that are children of the **Reaction** in which the **FunctionDefinition** appears (if it appears inside the **Math** object of a **KineticLaw**); and any identifiers (in the **SId** namespace of the model) belonging to an object class defined by an SBML Level 3 package as having mathematical meaning. (References: SBML L3V1 Section 3.4.3; SBML L3V2 Section 3.4.3.)

10216. ☑ The **id** attribute value of a **LocalParameter** object defined within a **KineticLaw** object may only be used, in core, in MathML **ci** elements within the **math** element of that same **KineticLaw**; in other words, the identifier of the **LocalParameter** object is not visible to other parts of the model outside of that **Reaction** instance. In package constructs, the **id** attribute value of a **LocalParameter** object may only be used in MathML **ci** elements or as the target of an **SIdRef** attribute if that package construct is a child of the parent **Reaction**. (References: SBML L3V1 Section 3.3.1, 3.4.3, and 4.11.5; SBML L3V2 Section 3.3.1, Section 3.4.3, and Section 4.11.5.)

10217. ☑ (This validation rule does not apply in SBML Level 3 Version 2 Core.) <fnref n="6" />

10218. ☑ A MathML operator must be supplied the number of arguments appropriate for that operator. (References: SBML L3V1 Section 3.4.1; SBML L3V2 Section 3.4.1.)

10219. ☑ The number of arguments used in a call to a function defined by a **FunctionDefinition** object must equal the number of arguments accepted by that function, if defined. In other words, it must equal the number of MathML **bvar** elements inside the **lambda** element of the function definition, if present. (References: SBML L3V1 Section 4.3.4; SBML L3V2 Section 4.3.4.)

10220. ☑ The SBML attribute **units** may only be added to MathML **cn** elements; no other MathML elements are permitted to have the **units** attribute. An SBML package may allow the **units** attribute on other elements, and if so, the package must define **required**="true" on the SBML container element `<sbml>`. (References: SBML L3V1 Section 3.4.2; SBML L3V2 Section 3.4.2.)

10221. ☑ The value of the SBML attribute **units** on a MathML **cn** element must be chosen from either the set of identifiers of **UnitDefinition** objects in the model, or the set of base units defined by SBML. (References: SBML L3V1 Section 3.4.2; SBML L3V2 Section 3.4.2.)

<footnote n="2">²Original rule: “The arguments to the following MathML constructs must evaluate to numeric values (more specifically, they must evaluate to MathML real, integer, rational, or “e-notation” numbers, or the *time*, *delay*, *avogadro*, *csymbol* elements): *abs*, *arccosh*, *arccos*, *arccoth*, *arccot*, *arccsch*, *arccsc*, *arcsech*, *arcsec*, *arcsinh*, *arcsin*, *arctanh*, *arctan*, *ceiling*, *cosh*, *cos*, *coth*, *cot*, *csch*, *csc*, *divide*, *exp*, *factorial*, *floor*, *ln*, *log*, *minus*, *plus*, *power*, *root*, *sech*, *sec*, *sinh*, *sin*, *tanh*, *tan*, and *times*.”</footnote>

<footnote n="3">³Original rule: “The values of all arguments to MathML **eq** and **neq** operators must evaluate to the same type, either all Boolean or all numeric.”</footnote>

<footnote n="4">⁴Original rule: “The types of the values within MathML **piecewise** operators should all be consistent; i.e., the set of expressions that make up the first arguments of the **piece** and **otherwise** operators within the same **piecewise** operator should all return values of the same type.”</footnote>

<footnote n="5">⁵Original rule: “The second argument of a MathML **piece** operator must evaluate to a Boolean value.”</footnote>

<footnote n="6">⁶Original rule: “The MathML formulas in the following elements must yield numeric values (that is, MathML real, integer or “e-notation” numbers, or the *time*, *delay*, *avogadro*, or *rateOf* *csymbol*): *math* in **KineticLaw**, *math* in **InitialAssignment**, *math* in **AssignmentRule**, *math* in **RateRule**, *math* in **AlgebraicRule**, *math* in **EventDelay**, and *math* in **EventAssignment**.”</footnote>
10223. [x] The single argument for the *rateOf csymbol* function must be a *ci* element. (Reference: SBML L3V2 Section 3.4.6)

10224. [x] The target of a *rateOf csymbol* function must not appear as the *variable* of an **AssignmentRule**, nor may its value be determined by an **AlgebraicRule**. (Reference: SBML L3V2 Section 3.4.6)

10225. [x] If the target of a *rateOf csymbol* function is a **Species** with a *hasOnlySubstanceUnits* value of "false", the *compartment* of that **Species** must not appear as the *variable* of an **AssignmentRule**, nor may its *size* be determined by an **AlgebraicRule**. (Reference: SBML L3V2 Section 3.4.6)

General rules for identifiers

10301. [x] The value of the attribute *id* on every instance of the following classes of objects must be unique across the set of all *id* attribute values of all such objects in a model: **AlgebraicRule**, **AssignmentRule**, **Compartment**, **Constraint**, **Delay**, **Event**, **EventAssignment**, **FunctionDefinition**, **InitialAssignment**, **KineticLaw**, **ListOfCompartments**, **ListOfConstraints**, **ListOfEventAssignments**, **ListOfEvents**, **ListOfFunctionDefinitions**, **ListOfInitialAssignments**, **ListOfLocalParameters**, **ListOfModifierSpeciesReferences**, **ListOfParameters**, **ListOfReactions**, **ListOfRules**, **ListOfSpecies**, **ListOfSpeciesReferences**, **ListOfUnitDefinitions**, **ListOfUnits**, **Model**, **ModifierSpeciesReference**, **Parameter**, **Priority**, **RateRule**, **Reaction**, **Species**, **SpeciesReference**, **Trigger**, and **Unit**, plus the *id* attribute values of any SBML Level 3 package element defined to be in the *SId* namespace of the model. (References: SBML L3V1 Section 3.3; SBML L3V2 Section 3.3.)

10302. [x] The value of the attribute *id* of every **UnitDefinition** object must be unique across the set of all the **UnitDefinition** objects in the entire model. (References: SBML L3V1 Section 3.3 and 4.4; SBML L3V2 Section 3.3 and Section 4.4.)

10303. [x] The value of the attribute *id* of every **LocalParameter** object defined within a **KineticLaw** object must be unique across the set of all such parameter definitions within that particular **KineticLaw** instance. (References: SBML L3V1 Section 3.3.1 and 4.11.5; SBML L3V2 Section 3.3.1 and Section 4.11.5.)

10304. [x] The value of the attribute *variable* of every **AssignmentRule** and **RateRule** objects must be unique across the set of all **AssignmentRule** and **RateRule** objects in a model. In other words, a given model component cannot be the subject of both an assignment rule and a rate rule simultaneously. (References: SBML L3V1 Section 4.9.3; SBML L3V2 Section 4.9.3.)

10305. [x] In every **Event** object, the value of the attribute *variable* within each **EventAssignment** subobject must be unique across the set of all such **EventAssignment** subobjects within that particular **Event** object. In other words, a single **Event** cannot make more than one assignment to the same model component. (References: SBML L3V1 Section 4.12.5; SBML L3V2 Section 4.12.5.)

10306. [x] An identifier used as the value of the attribute *variable* of an **EventAssignment** object cannot also appear as the value of the *variable* attribute in an **AssignmentRule** object. In other words, a given model component cannot be the subject of both an assignment rule and an assignment by an event. (References: SBML L3V1 Section 4.12.5; SBML L3V2 Section 4.12.5.)

10307. [x] Every **metaid** attribute value must be unique across the set of all **metaid** values in a model. (References: SBML L3V1 Section 3.2.1 and 3.1.6; SBML L3V2 Section 3.2.3 and Section 3.1.6.)

10308. [x] The value of the attribute **sboTerm** must always conform to the syntax of the SBML data type **SBOTerm**, which is a string consisting of the characters 'S', 'B', 'O', ':', followed by exactly seven digits. (References: SBML L3V1 Section 3.1.11; SBML L3V2 Section 3.1.12.)

10309. [x] The value of a **metaid** attribute must always conform to the syntax of the XML data type **ID**. (References: SBML L3V1 Section 3.2.1 and 3.1.6; SBML L3V2 Section 3.2.3 and Section 3.1.6.)

10310. [x] The value of an *id* attribute must always conform to the syntax of the SBML data type *SId*. (References: SBML L3V1 Section 3.1.7; SBML L3V2 Section 3.1.7.)
10311. ☑ Unit identifiers (that is, the values of the `id` attribute on `UnitDefinition`, the `units` attribute on `Compartment`, the `units` attribute on `Parameter`, the `units` attribute on `LocalParameter`, the `substanceUnits` attribute on `Species`, the SBML `units` attribute on MathML `cn` elements, and the `substanceUnits`, `volumeUnits`, `areaUnits`, `lengthUnits`, `timeUnits` and `extentUnits` on `Model`) must always conform to the syntax of the SBML data type `UnitId`. (References: SBML L3V1 Section 3.1.9; SBML L3V2 Section 3.1.9.)

10312. ☑ The value of a `name` attribute must always conform to the syntax of type `string`. (References: SBML L3V1 Section 3.1.1; SBML L3V2 Section 3.1.1.)

10313. ☑ Unit identifier references (that is, the `units` attribute on `Compartment`, the `units` attribute on `Parameter`, the `units` attribute on `LocalParameter`, the `substanceUnits` attribute on `Species`, the SBML `units` attribute on MathML `ci` elements, and the `substanceUnits`, `volumeUnits`, `areaUnits`, `lengthUnits`, `timeUnits` and `extentUnits` on `Model`) must be the identifier of a `UnitDefinition` in the `Model`, or the identifier of a predefined unit in SBML, that is, any of the following base units: "ampere", "avogadro", "becquerel", "candela", "coulomb", "dimensionless", "farad", "gram", "gray", "henry", "hertz", "item", "joule", "katal", "kelvin", "kilogram", "litre", "lumen", "lux", "metre", "mole", "newton", "ohm", "pascal", "radian", "second", "siemens", "sievert", "steradian", "tesla", "volt", "watt", or "weber". (References: SBML L3V1 Section 4.4.2; SBML L3V2 Section 4.4.2.)

## General rules for annotation elements

10401. ☑ Every top-level XML element within an **Annotation** object must have an XML namespace declared. (References: SBML L3V1 Section 3.2.4; SBML L3V2 Section 3.2.6.)

10402. ☑ A given XML namespace cannot be the namespace of more than one top-level element within a given **Annotation** object. (References: SBML L3V1 Section 3.2.4; SBML L3V2 Section 3.2.6.)

10404. ☑ A given SBML element may contain at most one **Annotation** subobject. (References: SBML L3V1 Section 3.2; SBML L3V2 Section 3.2.)

## General rules for units

10501. ▲ The units of the expressions used as arguments to a function call should match the units expected for the arguments of that function. (References: SBML L3V1 Section 3.4; SBML L3V2 Section 3.4.)

10503. ▲ The unit of measurement associated with the mathematical formula in the MathML `math` element of every **KineticLaw** object in a model should be identical to all **KineticLaw** objects in the model. (References: SBML L3V1 Section 3.4; SBML L3V2 Section 3.4.)

10511. ▲ When the value of the attribute `variable` in an **AssignmentRule** object refers to a **Compartment** object, the unit of measurement associated with the mathematical expression in the rule's MathML `math` element should be consistent with the unit of that compartment's size. (References: SBML L3V1 Section 4.9.3; SBML L3V2 Section 4.9.3.)

10512. ▲ When the value of the attribute `variable` in an **AssignmentRule** object refers to a **Species** object, the unit of measurement associated with the mathematical expression in the rule's MathML `math` element should be consistent with the unit of that species' quantity. (References: SBML L3V1 Section 4.9.3; SBML L3V2 Section 4.9.3.)

10513. ▲ When the value of the attribute `variable` in an **AssignmentRule** object refers to a **Parameter** object, the unit of measurement associated with the mathematical expression in the rule's MathML `math` element should be consistent with the unit declared for that parameter's value. (References: SBML L3V1 Section 4.9.3; SBML L3V2 Section 4.9.3.)

10514. ▲ When the value of the attribute `variable` in an **AssignmentRule** object refers to a **SpeciesReference** object, the unit of measurement associated with the rule's right-hand side should be consistent
with the unit of stoichiometry, that is, **dimensionless**. (References: SBML L3V1 Section 4.9.3; SBML L3V2 Section 4.9.3.)

10521. ▲ When the value of the attribute **variable** in an **InitialAssignment** object refers to a **Compartment** object, the unit of measurement associated with the **InitialAssignment's math** expression should be consistent with the unit of that compartment's size. (References: SBML L3V1 Section 4.8; SBML L3V2 Section 4.8.)

10522. ▲ When the value of the attribute **variable** in an **InitialAssignment** object refers to a **Species** object, the unit of measurement associated with the **InitialAssignment's math** expression should be consistent with the unit of that species' quantity. (References: SBML L3V1 Section 4.8; SBML L3V2 Section 4.8.)

10523. ▲ When the value of the attribute **variable** in an **InitialAssignment** object refers to a **Parameter** object, the unit of measurement associated with the **InitialAssignment's math** expression should be consistent with the unit declared for that parameter's value. (References: SBML L3V1 Section 4.8; SBML L3V2 Section 4.8.)

10524. ▲ When the value of the attribute **variable** in an **InitialAssignment** object refers to a **SpeciesReference** object, the unit of measurement associated with the **InitialAssignment's math** expression should be consistent with the unit of stoichiometry, that is, **dimensionless**. (References: SBML L3V1 Section 4.8; SBML L3V2 Section 4.8.)

10531. ▲ When the value of the attribute **variable** in a **RateRule** object refers to a **Compartment** object, the unit of measurement associated with the **RateRule's math** expression should be consistent with {unit of compartment size}/{unit of time}. (References: SBML L3V1 Section 4.5.4, 4.2.4, and 4.9.4; SBML L3V2 Section 4.5.4, Section 4.2.3, and Section 4.9.4.)

10532. ▲ When the value of the attribute **variable** in a **RateRule** object refers to a **Species** object, the unit of measurement associated with the **RateRule's math** expression should be consistent with {unit of species quantity}/{unit of time}. (References: SBML L3V1 Section 4.6.5, 4.2.4, and 4.9.4; SBML L3V2 Section 4.6.5, Section 4.2.3, and Section 4.9.4.)

10533. ▲ When the value of the attribute **variable** in a **RateRule** object refers to a **Parameter** object, the unit of measurement associated with the **RateRule's math** expression should be consistent with {parameter's units}/{unit of time}. (References: SBML L3V1 Section 4.7.3, 4.2.4, and 4.9.4; SBML L3V2 Section 4.7.3, Section 4.2.3, and Section 4.9.4.)

10534. ▲ When the value of the attribute **variable** in a **RateRule** object refers to a **SpeciesReference** object, the unit of measurement associated with the **RateRule's math** expression should be consistent with {unit derived from **dimensionless**}/{unit of time}. (References: SBML L3V1 Section 4.11.3, 4.2.4, and 4.9.4; SBML L3V2 Section 4.11.3, Section 4.2.3, and Section 4.9.4.)

10541. ▲ In a **KineticLaw** object, the unit of measurement associated with the formula in the **KineticLaw's math** expression should be equal to {unit of reaction extent}/{unit of time}. (References: SBML L3V1 Section 4.11.7, 4.2.4, and 4.9.4; SBML L3V2 Section 4.11.7, Section 4.2.3, and Section 4.9.4.)

10542. ▲ For every **Species** object produced or consumed in a reaction (that is, referenced by a **SpeciesReference** object), the unit of measurement of the species' substance should be consistent with the unit of **extent** for the model times the unit of the conversion factor for that species. More precisely, the product of the units indicated by the **Model** object's **extentUnits** and the **conversionFactor** attribute for that particular **Species** (whether the attribute is set directly on the **Species** object or inherited from the enclosing **Model** object) should be consistent with the unit specified by that **Species** object's **substanceUnits** attribute value. (References: SBML L3V1 Section 4.2.6; SBML L3V2 Section 4.2.5.)

10551. ▲ In an **Event** object, the unit of measurement associated with a **Delay** object's **math** expression object should be identical to the unit indicated by the **Model** object's **timeUnits** attribute. (References: SBML L3V1 Section 4.12.4; SBML L3V2 Section 4.12.4.)
10561. ▲ When the value of the attribute **variable** of an **EventAssignment** object is the identifier of a **Compartment** object, the unit of measurement associated with the **EventAssignment**'s **math** expression should be consistent with the unit of that compartment's size. (References: SBML L3V1 Section 4.12.5; SBML L3V2 Section 4.12.5.)

10562. ▲ When the value of the attribute **variable** of an **EventAssignment** object is the identifier of a **Species** object, the unit of measurement associated with the **EventAssignment**'s **math** expression should be consistent with the unit of that species' size. (References: SBML L3V1 Section 4.12.5; SBML L3V2 Section 4.12.5.)

10563. ▲ When the value of the attribute **variable** of an **EventAssignment** object is the identifier of a **Parameter** object, the unit of measurement associated with the **EventAssignment**'s **math** expression should be consistent with the unit declared for that parameter's value. (References: SBML L3V1 Section 4.12.5; SBML L3V2 Section 4.12.5.)

10564. ▲ When the value of the attribute **variable** of an **EventAssignment** object is the identifier of a **SpeciesReference** object, the unit of measurement associated with the **EventAssignment**'s **math** expression should be consistent with the unit of stoichiometry, i.e., **dimensionless**. (References: SBML L3V1 Section 4.12.5; SBML L3V2 Section 4.12.5.)

10565. ▲ In an **Event** object, the unit of measurement associated with a **Priority** object's **math** expression object should be **dimensionless**. (References: SBML L3V1 Section 4.12.3; SBML L3V2 Section 4.12.3.)

## General rules for model definitions

10601. ☑ A system of equations created from an SBML model must not be overdetermined. (References: SBML L3V1 Section 4.9.5; SBML L3V2 Section 4.9.5.)

## General rules for SBO usage

10701. ▲ The value of the attribute **sboTerm** on a **Model** object should be an SBO identifier referring to an interaction or modeling framework defined in SBO. That is, the value should be a term derived from **SBO:0000231**, "occurring entity representation", or **SBO:0000004**, "modeling framework". (References: SBML L3V1 Section 5; SBML L3V2 Section 5.)

10702. ▲ The value of the attribute **sboTerm** on a **FunctionDefinition** object should be an SBO identifier referring to a mathematical expression. That is, the value should be a term derived from **SBO:0000064**, "mathematical expression". (References: SBML L3V1 Section 5; SBML L3V2 Section 5.)

10703. ▲ The value of the attribute **sboTerm** on a **Parameter** object should be an SBO identifier referring to a quantitative parameter. That is, the value should be a term derived from **SBO:0000545**, "systems description parameter". (References: SBML L3V1 Section 5; SBML L3V2 Section 5.)

10704. ▲ The value of the attribute **sboTerm** on an **InitialAssignment** object should be an SBO identifier referring to a mathematical expression. That is, the value should be a term derived from **SBO:0000064**, "mathematical expression". (References: SBML L3V1 Section 5; SBML L3V2 Section 5.)

10705. ▲ The value of the attribute **sboTerm** on a **AlgebraicRule**, **RateRule** or **AssignmentRule** object should be an SBO identifier referring to a mathematical expression. That is, the value should be a term derived from **SBO:0000064**, "mathematical expression". (References: SBML L3V1 Section 5; SBML L3V2 Section 5.)

10706. ▲ The value of the attribute **sboTerm** on a **Constraint** object should be an SBO identifier referring to a mathematical expression. That is, the value should be a term derived from **SBO:0000064**, "mathematical expression". (References: SBML L3V1 Section 5; SBML L3V2 Section 5.)

10707. ▲ The value of the attribute **sboTerm** on a **Reaction** object should be an SBO identifier referring to an interaction framework. That is, the value should be a term derived from **SBO:0000231**, "occurring entity representation". (References: SBML L3V1 Section 5; SBML L3V2 Section 5.)
10708. ▲ The value of the attribute `sboTerm` on a **SpeciesReference** or a **ModifierSpeciesReference** object should be an SBO identifier referring to a participant role. That is, the value should be a term derived from `SBO:0000003`, "participant role". The appropriate term depends on whether the entity is a reactant, product or modifier. (References: SBML L3V1 Section 5; SBML L3V2 Section 5.)

10709. ▲ The value of the attribute `sboTerm` on a **KineticLaw** object should be an SBO identifier referring to a rate law. That is, the value should be a term derived from `SBO:0000001`, "rate law". (References: SBML L3V1 Section 5; SBML L3V2 Section 5.)

10710. ▲ The value of the attribute `sboTerm` on an **Event** object should be an SBO identifier referring to a mathematical expression. That is, the value should be a term derived from `SBO:0000231`, "occurring entity representation". (References: SBML L3V1 Section 5; SBML L3V2 Section 5.)

10711. ▲ The value of the attribute `sboTerm` on an **EventAssignment** object should be an SBO identifier referring to a mathematical expression. That is, the value should be a term derived from `SBO:0000064`, "mathematical expression". (References: SBML L3V1 Section 5; SBML L3V2 Section 5.)

10712. ▲ The value of the attribute `sboTerm` on a **Compartment** object should be an SBO identifier referring to a material entity. That is, the value should be a term derived from `SBO:0000236`, "physical entity representation". (References: SBML L3V1 Section 5; SBML L3V2 Section 5.)

10713. ▲ The value of the attribute `sboTerm` on a **Species** object should be an SBO identifier referring to a material entity. That is, the value should be a term derived from `SBO:0000236`, "physical entity representation". (References: SBML L3V1 Section 5; SBML L3V2 Section 5.)

10716. ▲ The value of the attribute `sboTerm` on a **Trigger** object should be an SBO identifier referring to a mathematical expression. That is, the value should be a term derived from `SBO:0000064`, "mathematical expression". (References: SBML L3V1 Section 5; SBML L3V2 Section 5.)

10717. ▲ The value of the attribute `sboTerm` on a **Delay** object should be an SBO identifier referring to a mathematical expression. That is, the value should be a term derived from `SBO:0000064`, "mathematical expression". (References: SBML L3V1 Section 5; SBML L3V2 Section 5.)

10718. ▲ The value of the attribute `sboTerm` on a **LocalParameter** object should be an SBO identifier referring to a quantitative parameter. That is, the value should be a term derived from `SBO:0000545`, "systems description parameter". (References: SBML L3V1 Section 5; SBML L3V2 Section 5.)

10719. ▲ The value of the attribute `sboTerm` on the **SBML** object should be an SBO identifier referring to a modeling framework. That is, the value should be a term derived from `SBO:0000004`, "modeling framework". (References: SBML L3V2 Section 5.)

## General rules for notes elements

10801. ☑ The contents of a **Notes** object must be explicitly placed in the XHTML XML namespace. (References: SBML L3V1 Section 3.2.3; SBML L3V2 Section 3.2.5.)

10802. ☑ The contents of a **Notes** object must not contain an XML declaration, i.e., a string of the form `"<?xml version="1.0" encoding="UTF-8"?>"` or similar. (References: SBML L3V1 Section 3.2.3; SBML L3V2 Section 3.2.5.)

10803. ☑ The content of a **Notes** object must not contain an XML DOCTYPE declaration, i.e., a string beginning with the characters `"<!DOCTYPE"`. (References: SBML L3V1 Section 3.2.3; SBML L3V2 Section 3.2.5.)

10805. ☑ A given SBML object may contain at most one **Notes** subobject. (References: SBML L3V1 Section 3.2; SBML L3V2 Section 3.2.)
## Rules for the `<sbml>` container element

2010. The **sbml** container element must declare the XML Namespace for SBML, and this declaration must be consistent with the values of the **level** and **version** attributes on the **sbml** element. (References: SBML L3V1 Section 4.1; SBML L3V2 Section 4.1.)

2010. The **sbml** container element must declare the SBML Level using the attribute **level**, and this declaration must be consistent with the XML Namespace declared for the **sbml** element. (References: SBML L3V1 Section 4.1; SBML L3V2 Section 4.1.)

2010. The **sbml** container element must declare the SBML Version using the attribute **version**, and this declaration must be consistent with the XML Namespace declared for the **sbml** element. (References: SBML L3V1 Section 4.1; SBML L3V2 Section 4.1.)

2010. The **sbml** container element must declare the XML Namespace for any SBML Level 3 packages used within the SBML document. This declaration must be consistent with the values of the **level** and **version** attributes on the **sbml** element. (References: SBML L3V1 Section 4.1.2; SBML L3V2 Section 4.1.3.)

2010. The attribute **level** on the **sbml** container element must have a value of type **positiveInteger**. (References: SBML L3V1 Section 3.1.4; SBML L3V2 Section 3.1.4.)

2010. The attribute **version** on the **sbml** container element must have a value of type **positiveInteger**. (References: SBML L3V1 Section 3.1.4; SBML L3V2 Section 3.1.4.)

2010. The attribute **xmlns** on the **sbml** container element must have a value of type **string**. (References: SBML L3V1 Section 3.1.1; SBML L3V2 Section 3.1.1.)

2010. The **sbml** object may have the optional attributes **id**, **name**, **metaid** and **sboTerm**. (References: SBML L3V1 Section 4.2.8; SBML L3V2 Section 4.2.7.)

## Rules for Model components

2020. An SBML document may contain at most one **Model** object. (References: SBML L3V1 Section 4.1; SBML L3V2 Section 4.1).

2020. (This validation rule does not apply in SBML Level 3 Version 2 Core.) <fnref n="7" />

2020. If a model defines any **Species** object, then the model must also define at least one **Compartment** object. This is an implication of the fact that the **compartment** attribute on **Species** is not optional. (References: SBML L3V1 Section 4.6.3; SBML L3V2 Section 4.6.3.)

2020. There may be at most one instance of each of the following kind of object in a **Model** object: **ListOfFunctionDefinitions**, **ListOfUnitDefinitions**, **ListOfCompartments**, **ListOfSpecies**, **ListOfParameters**, **ListOfInitialAssignments**, **ListOfRules**, **ListOfConstraints**, **ListOfReactions** and **ListOfEvents**. (References: SBML L3V1 Section 4.2; SBML L3V2 Section 4.2.)

2020. Apart from the general notes and annotation subobjects permitted on all SBML components, a **ListOfFunctionDefinitions** container object may only contain **FunctionDefinition** objects. (References: SBML L3V1 Section 4.2.8; SBML L3V2 Section 4.2.7.)

2020. Apart from the general notes and annotation subobjects permitted on all SBML components, a **ListOfUnitDefinitions** container object may only contain **UnitDefinition** objects. (References: SBML L3V1 Section 4.2.8; SBML L3V2 Section 4.2.7.)

<footnote n="7">⁷Original rule: "The various `listOf` container objects in a **Model** instance are optional, but if present, such container elements must not be empty. Specifically, if any of the following is present in a **Model**, it must not be empty: **ListOfFunctionDefinitions**, **ListOfUnitDefinitions**, **ListOfCompartments**, **ListOfSpecies**, **ListOfParameters**, **ListOfInitialAssignments**, **ListOfRules**, **ListOfConstraints**, **ListOfReactions** and **ListOfEvents**."</footnote>
20208. ✅ Apart from the general notes and annotation subobjects permitted on all SBML components, a **ListOfCompartments** container object may only contain **Compartment** objects. (References: SBML L3V1 Section 4.2.8; SBML L3V2 Section 4.2.7.)

20209. ✅ Apart from the general notes and annotation subobjects permitted on all SBML components, a **ListOfSpecies** container object may only contain **Species** objects. (References: SBML L3V1 Section 4.2.8; SBML L3V2 Section 4.2.7.)

20210. ✅ Apart from the general notes and annotation subobjects permitted on all SBML components, a **ListOfParameters** container object may only contain **Parameter** objects. (References: SBML L3V1 Section 4.2.8; SBML L3V2 Section 4.2.7.)

20211. ✅ Apart from the general notes and annotation subobjects permitted on all SBML components, a **ListOfInitialAssignments** container object may only contain **InitialAssignment** objects. (References: SBML L3V1 Section 4.2.8; SBML L3V2 Section 4.2.7.)

20212. ✅ Apart from the general notes and annotation subobjects permitted on all SBML components, a **ListOfRules** container object may only contain **AssignmentRule**, **AlgebraicRule** and/or **RateRule** objects. (References: SBML L3V1 Section 4.2.8; SBML L3V2 Section 4.2.7.)

20213. ✅ Apart from the general notes and annotation subobjects permitted on all SBML components, a **ListOfConstraints** container object may only contain **Constraint** objects. (References: SBML L3V1 Section 4.2.8; SBML L3V2 Section 4.2.7.)

20214. ✅ Apart from the general notes and annotation subobjects permitted on all SBML components, a **ListOfReactions** container object may only contain **Reaction** objects. (References: SBML L3V1 Section 4.2.8; SBML L3V2 Section 4.2.7.)

20215. ✅ Apart from the general notes and annotation subobjects permitted on all SBML components, a **ListOfEvents** container object may only contain **Event** objects. (References: SBML L3V1 Section 4.2.8; SBML L3V2 Section 4.2.7.)

20216. ✅ The value of the attribute **conversionFactor** on a **Model** object must be the identifier of an existing **Parameter** object defined in the **Model** object's **ListOfParameters**. (References: SBML L3V1 Section 4.2; SBML L3V2 Section 4.2.)

20217. ★ The value of the attribute **timeUnits** on a **Model** object should be either the units "second", "dimensionless", or the identifier of a **UnitDefinition** object based on these units, or a combination of these units. (References: SBML L3V1 Section 4.2.4; SBML L3V2 Section 4.2.3.)

20218. ★ The value of the attribute **volumeUnits** on a **Model** object should be either the units "litre", "dimensionless", or the identifier of a **UnitDefinition** object based on these units or a unit derived from "metre", or a combination of these units. (References: SBML L3V1 Section 4.2.5; SBML L3V2 Section 4.2.4.)

20219. ★ The value of the attribute **areaUnits** on a **Model** object should be either "dimensionless" or the identifier of a **UnitDefinition** object based on "dimensionless" or a unit derived from "metre", or a combination of these units. (References: SBML L3V1 Section 4.2.5; SBML L3V2 Section 4.2.4.)

20220. ★ The value of the attribute **lengthUnits** on a **Model** object should be either the units "metre", "dimensionless", or the identifier of a **UnitDefinition** object based on these units, or a combination of these units. (References: SBML L3V1 Section 4.2.5; SBML L3V2 Section 4.2.4.)

20221. ★ The value of the attribute **extentUnits** on a **Model** object should be either the units "mole", "item", "avogadro", "dimensionless", "kilogram", "gram", or the identifier of a **UnitDefinition** object based on these units, or a combination of these units. (References: SBML L3V1 Section 4.2.6; SBML L3V2 Section 4.2.5.)
20222. ✅ A **Model** object may only have the following attributes, all of which are optional: `metaid`, `sboTerm`, `id`, `name`, `substanceUnits`, `timeUnits`, `volumeUnits`, `areaUnits`, `lengthUnits`, `extentUnits` and `conversionFactor`. No other attributes from the SBML Level 3 Core namespace are permitted on a **Model** object. (References: SBML L3V1 Section 4.2; SBML L3V2 Section 4.2.)

20223. ✅ A **ListOfFunctionDefinitions** object may have the optional attributes `id`, `name`, `metaid` and `sboTerm`. No other attributes from the SBML Level 3 Core namespace are permitted on a **ListOfFunctionDefinitions** object. (References: SBML L3V1 Section 4.2.8; SBML L3V2 Section 4.2.7.)

20224. ✅ A **ListOfUnitDefinitions** object may have the optional attributes `id`, `name`, `metaid` and `sboTerm`. No other attributes from the SBML Level 3 Core namespace are permitted on a **ListOfUnitDefinitions** object. (References: SBML L3V1 Section 4.2.8; SBML L3V2 Section 4.2.7.)

20225. ✅ A **ListOfCompartments** object may have the optional attributes `id`, `name`, `metaid` and `sboTerm`. No other attributes from the SBML Level 3 Core namespace are permitted on a **ListOfCompartments** object. (References: SBML L3V1 Section 4.2.8; SBML L3V2 Section 4.2.7.)

20226. ✅ A **ListOfSpecies** object may have the optional attributes `id`, `name`, `metaid` and `sboTerm`. No other attributes from the SBML Level 3 Core namespace are permitted on a **ListOfSpecies** object. (References: SBML L3V1 Section 4.2.8; SBML L3V2 Section 4.2.7.)

20227. ✅ A **ListOfParameters** object may have the optional attributes `id`, `name`, `metaid` and `sboTerm`. No other attributes from the SBML Level 3 Core namespace are permitted on a **ListOfParameters** object. (References: SBML L3V1 Section 4.2.8; SBML L3V2 Section 4.2.7.)

20228. ✅ A **ListOfInitialAssignments** object may have the optional attributes `id`, `name`, `metaid` and `sboTerm`. No other attributes from the SBML Level 3 Core namespace are permitted on a **ListOfInitialAssignments** object. (References: SBML L3V1 Section 4.2.8; SBML L3V2 Section 4.2.7.)

20229. ✅ A **ListOfRules** object may have the optional attributes `id`, `name`, `metaid` and `sboTerm`. No other attributes from the SBML Level 3 Core namespace are permitted on a **ListOfRules** object. (References: SBML L3V1 Section 4.2.8; SBML L3V2 Section 4.2.7.)

20230. ✅ A **ListOfConstraints** object may have the optional attributes `id`, `name`, `metaid` and `sboTerm`. No other attributes from the SBML Level 3 Core namespace are permitted on a **ListOfConstraints** object. (References: SBML L3V1 Section 4.2.8; SBML L3V2 Section 4.2.7.)

20231. ✅ A **ListOfReactions** object may have the optional attributes `id`, `name`, `metaid` and `sboTerm`. No other attributes from the SBML Level 3 Core namespace are permitted on a **ListOfReactions** object. (References: SBML L3V1 Section 4.2.8; SBML L3V2 Section 4.2.7.)

20232. ✅ A **ListOfEvents** object may have the optional attributes `id`, `name`, `metaid` and `sboTerm`. No other attributes from the SBML Level 3 Core namespace are permitted on a **ListOfEvents** object. (References: SBML L3V1 Section 4.2.8; SBML L3V2 Section 4.2.7.)

20233. ★ The value of the attribute `substanceUnits` on a **Model** object should be either the units "mole", "item", "avogadro", "dimensionless", "kilogram", "gram", or the identifier of a **UnitDefinition** object based on these units, or a combination of these units. (References: SBML L3V1 Section 4.2.3; SBML L3V2 Section 4.2.2.)

## Rules for FunctionDefinition components

20301. ✅ The top-level element within the MathML `math` element in a **FunctionDefinition** object, if present, must be either exactly one MathML `lambda` element, or exactly one MathML `semantics` element containing exactly one `lambda` element. (References: SBML L3V1 Section 4.3.2; SBML L3V2 Section 4.3.2.)

20303. ✅ Inside the `lambda` MathML element within a **FunctionDefinition** object, the identifier of that object (i.e., value of the **FunctionDefinition**'s `id` attribute) cannot appear as the value of a `ci` element.
Such usage would entail a recursive function call, but SBML functions are not permitted to be recursive or mutually recursive. (References: SBML L3V1 Section 3.4.3 and 4.3.2; SBML L3V2 Section 3.4.3 and Section 4.3.2.)

20304. ✓ Inside the **lambda** MathML element within a **FunctionDefinition** object, if a **ci** element is not the first element within a MathML **apply**, then the **ci** element's value may only be an identifier provided as the value of a **bvar** element declared in that **lambda**. This restriction also applies to the **csymbol** objects for *time*, *avogadro*, *delay*, and *rateOf*. In other words, all model quantities and variables referenced inside a function definition must be passed as arguments to that function. (References: SBML L3V1 Section 3.4.3 and 4.3.2; SBML L3V2 Section 3.4.3 and Section 4.3.2.)

20305. ✓ The type of value returned by a **FunctionDefinition** object's **math** MathML expression must be either Boolean or numeric. (References: SBML L3V1 Section 3.4.9; SBML L3V2 Section 3.4.11.)

20306. ✓ A **FunctionDefinition** object may contain at most one MathML **math** element. (References: SBML L3V1 Section 4.3; SBML L3V1 Section 4.3; SBML L3V2 Section 4.3.)

20307. ✓ A **FunctionDefinition** object must have the required attribute **id**, and may have the optional attributes **metaid**, **sboTerm** and **name**. No other attributes from the SBML Level 3 Core namespace are permitted on a **FunctionDefinition** object. (References: SBML L3V1 Section 4.3; SBML L3V2 Section 4.3.)

20308. ✓ Inside the **lambda** MathML element within a **FunctionDefinition**, **bvar** elements must contain exactly one instance of a **ci** element. No other elements are permitted within a **bvar** element. (References: SBML L3V1 Section 4.3.2; SBML L3V2 Section 4.3.2.)

## Rules for Unit and UnitDefinition components

20401. ✓ The value of the attribute **id** in a **UnitDefinition** object must not be identical to any unit predefined in SBML. That is, the identifier must not be the same as any of the following base units: "ampere", "avogadro", "becquerel", "candela", "coulomb", "dimensionless", "farad", "gram", "gray", "henry", "hertz", "item", "joule", "katal", "kelvin", "kilogram", "litre", "lumen", "lux", "metre", "mole", "newton", "ohm", "pascal", "radian", "second", "siemens", "sievert", "steradian", "tesla", "volt", "watt", or "weber". (References: SBML L3V1 Section 4.4.2; SBML L3V2 Section 4.4.2.)

20410. ✓ The value of the attribute **kind** of a **Unit** object must conform to the syntax of the SBML data type **UnitSId** and may only take on the value of a base unit defined in SBML; that is, the value must be one of the following units: "ampere", "avogadro", "becquerel", "candela", "coulomb", "dimensionless", "farad", "gram", "gray", "henry", "hertz", "item", "joule", "katal", "kelvin", "kilogram", "litre", "lumen", "lux", "metre", "mole", "newton", "ohm", "pascal", "radian", "second", "siemens", "sievert", "steradian", "tesla", "volt", "watt", or "weber". The SBML unit system is not hierarchical, and user-defined units cannot be defined using other user-defined units. (References: SBML L3V1 Section 4.4.2; SBML L3V2 Section 4.4.2.)

20413. ✓ (This validation rule does not apply in SBML Level 3 Version 2 Core.) <fnref n="8" />

20414. ✓ There may be at most one **>ListOfUnits** container object in a **UnitDefinition** object. (References: SBML L3V1 Section 4.4; SBML L3V2 Section 4.4.)

20415. ✓ Apart from the general notes and annotation subobjects permitted on all SBML components, a **ListOfUnits** container object may only contain **Unit** objects. (References: SBML L3V1 Section 4.2.8; SBML L3V2 Section 4.2.7.)

20416. ✓ The attribute **exponent** on a **Unit** object must have a value of type **double**. (References: SBML L3V1 Section 3.1.5; SBML L3V2 Section 3.1.5.)

<footnote n="8">⁸Original rule: "The **ListOfUnits** container object in a **UnitDefinition** object is optional, but if present, it must not be empty."</footnote>
20417. ☑ The attribute **scale** on a **Unit** object must have a value of type **int**. (References: SBML L3V1 Section 3.1.3; SBML L3V2 Section 3.1.3.)

20418. ☑ The attribute **multiplier** on a **Unit** object must have a value of type **double**. (References: SBML L3V1 Section 3.1.5; SBML L3V2 Section 3.1.5.)

20419. ☑ A **UnitDefinition** object must have the required attribute **id** and may have the optional attributes **metaid**, **sboTerm** and **name**. No other attributes from the SBML Level 3 Core namespace are permitted on a **UnitDefinition** object. (References: SBML L3V1 Section 4.4; SBML L3V2 Section 4.4.)

20420. ☑ A **ListOfUnits** object may have the optional attributes **id**, **name**, **metaid** and **sboTerm**. No other attributes from the SBML Level 3 Core namespace are permitted on a **ListOfUnits** object. (References: SBML L3V1 Section 4.2.8; SBML L3V2 Section 4.2.7.)

20421. ☑ A **Unit** object must have the required attributes **kind**, **exponent**, **scale** and **multiplier**, and may have the optional attributes **id**, **name**, **metaid** and **sboTerm**. No other attributes from the SBML Level 3 Core namespace are permitted on a **Unit** object. (References: SBML L3V1 Section 4.4; SBML L3V2 Section 4.4.)

## Rules for Compartment components

20507. ★ The value of the attribute **units** on a **Compartment** object having **spatialDimensions** of **"1"** should be either **"metre"**, **"dimensionless"**, or the identifier of a **UnitDefinition** object based on either **metre** or **dimensionless**, or a combination of these units. (References: SBML L3V1 Section 4.5.4; SBML L3V2 Section 4.5.4.)

20508. ★ The value of the attribute **units** on a **Compartment** object having **spatialDimensions** of **"2"** should be either **"dimensionless"**, or the identifier of a **UnitDefinition** object based on either **metre** or **dimensionless**, or a combination of these units. (References: SBML L3V1 Section 4.5.4; SBML L3V2 Section 4.5.4.)

20509. ★ The value of the attribute **units** on a **Compartment** object having **spatialDimensions** of **"3"** should be either **"litre"**, or the identifier of a **UnitDefinition** object based on either **litre**, **metre** or **dimensionless**, or a combination of these units. (References: SBML L3V1 Section 4.5.4; SBML L3V2 Section 4.5.4.)

20511. ★ If the attribute **units** on a **Compartment** object having a **spatialDimensions** attribute value of **"1"** has not been set, then the unit of measurement associated with the compartment's size is determined by the value of the enclosing **Model** object's **lengthUnits** attribute. If neither the **Compartment** object's **units** nor the enclosing **Model** object's **lengthUnits** attributes are set, the unit of compartment size is undefined. (References: SBML L3V1 Section 4.5.4; SBML L3V2 Section 4.5.4.)

20512. ★ If the attribute **units** on a **Compartment** object having a **spatialDimensions** attribute value of **"2"** has not been set, then the unit of measurement associated with the compartment's size is determined by the value of the enclosing **Model** object's **areaUnits** attribute. If neither the **Compartment** object's **units** nor the enclosing **Model** object's **areaUnits** attributes are set, the unit of compartment size is undefined. (References: SBML L3V1 Section 4.5.4; SBML L3V2 Section 4.5.4.)

20513. ★ If the attribute **units** on a **Compartment** object having a **spatialDimensions** attribute value of **"3"** has not been set, then the unit of measurement associated with the compartment's size is determined by the value of the enclosing **Model** object's **volumeUnits** attribute. If neither the **Compartment** object's **units** nor the enclosing **Model** object's **volumeUnits** attributes are set, the unit of compartment size is undefined. (References: SBML L3V1 Section 4.5.4; SBML L3V2 Section 4.5.4.)

20514. ☑ The attribute **spatialDimensions** on a **Compartment** object must have a value of type **double**. (References: SBML L3V1 Section 3.1.5; SBML L3V2 Section 3.1.5.)
20515. ☑ The attribute **size** on a **Compartment** object must have a value of type **double**. (References: SBML L3V1 Section 3.1.5; SBML L3V2 Section 3.1.5.)

20516. ☑ The attribute **constant** on a **Compartment** object must have a value of type **boolean**. (References: SBML L3V1 Section 3.1.2; SBML L3V2 Section 3.1.2.)

20517. ☑ A **Compartment** object must have the required attributes **id** and **constant**, and may have the optional attributes **metaId**, **sboTerm**, **name**, **spatialDimensions**, **size** and **units**. No other attributes from the SBML Level 3 Core namespace are permitted on a **Compartment** object. (References: SBML L3V1 Section 4.5; SBML L3V2 Section 4.5.)

20518. ★ If neither the attribute **units** nor the attribute **spatialDimensions** on a **Compartment** object is set, the unit associated with that compartment's size is undefined. (References: SBML L3V1 Section 4.5.4; SBML L3V2 Section 4.5.4.)

## Rules for Species components

20601. ☑ The value of the attribute **compartment** in a **Species** object must be the identifier of an existing **Compartment** object defined in the enclosing **Model** object. (References: SBML L3V1 Section 4.6.3; SBML L3V2 Section 4.6.3.)

20608. ★ The value of a **Species** object's **substanceUnits** attribute should only be one of the following: "mole", "item", "gram", "kilogram", "dimensionless", "avogadro" or the identifier of a **UnitDefinition** object derived from "mole", "item", "gram", "kilogram", "avogadro", or "dimensionless", or a combination of these units. (References: SBML L3V1 Section 4.6.5; SBML L3V2 Section 4.6.4.)

20609. ☑ A **Species** object cannot have values for both its **initialConcentration** and **initialAmount** attributes because these attributes are mutually exclusive. (References: SBML L3V1 Section 4.6.4; SBML L3V2 Section 4.6.4.)

20610. ☑ The quantity of a **Species** object in a model cannot be determined simultaneously by both reactions and rules. More formally, if the identifier of a **Species** object having attribute values **boundaryCondition**="false" and **constant**="false" is referenced by a **SpeciesReference** object anywhere in a model, then this identifier cannot also appear as the value of a **variable** in an **AssignmentRule** or a **RateRule** object. (References: SBML L3V1 Section 4.6.6; SBML L3V2 Section 4.6.6.)

20611. ☑ A **Species** object having a value of "false" for its attribute **boundaryCondition** cannot appear as a reactant or product in any reaction if that **Species** also has a value of "true" for its attribute **constant**. (References: SBML L3V1 Section 4.6.6; SBML L3V2 Section 4.6.6.)

20614. ☑ The attribute **compartment** in **Species** is mandatory. A **Species** object in a model must include a value for this attribute. (References: SBML L3V1 Section 4.6.3; SBML L3V2 Section 4.6.3.)

20616. ★ If the attribute **substanceUnits** in a **Species** object has not been set, then the unit of measurement associated with the species' quantity is determined by the value of the enclosing **Model** object's **substanceUnits** attribute. If neither the **Species** object's **substanceUnits** attribute nor the enclosing **Model** object's **substanceUnits** attribute are set, then the unit of that species' quantity is undefined. (References: SBML L3V1 Section 4.6.5; SBML L3V2 Section 4.6.5.)

20617. ☑ The value of the attribute **conversionFactor** on a **Species** object must be the identifier of an existing **Parameter** object defined in the enclosing **Model** object. (References: SBML L3V1 Section 4.6.7; SBML L3V2 Section 4.6.7.)

20618. ☑ The attribute **initialAmount** on a **Species** object must have a value of type **double**. (References: SBML L3V1 Section 3.1.5; SBML L3V2 Section 3.1.5.)

20619. ☑ The attribute **initialConcentration** on a **Species** object must have a value of type **double**. (References: SBML L3V1 Section 3.1.5; SBML L3V2 Section 3.1.5.)
20620. ✅ The attribute `hasOnlySubstanceUnits` on a `Species` object must have a value of type `boolean`. (References: SBML L3V1 Section 3.1.2; SBML L3V2 Section 3.1.2.)

20621. ✅ The attribute `boundaryCondition` on a `Species` object must have a value of type `boolean`. (References: SBML L3V1 Section 3.1.2; SBML L3V2 Section 3.1.2.)

20622. ✅ The attribute `constant` on a `Species` object must have a value of type `boolean`. (References: SBML L3V1 Section 3.1.2; SBML L3V2 Section 3.1.2.)

20623. ✅ A `Species` object must have the required attributes `id`, `compartment`, `hasOnlySubstanceUnits`, `boundaryCondition` and `constant`, and may have the optional attributes `metaId`, `sboTerm`, `name`, `initialAmount`, `initialConcentration`, `substanceUnits` and `conversionFactor`. No other attributes from the SBML Level 3 Core namespace are permitted on a `Species` object. (References: SBML L3V1 Section 4.6; SBML L3V2 Section 4.6.)

## Rules for Parameter components

20701. ✅ [Superceded by validation rule 10313.]

20702. ★ If the attribute `units` on a given `Parameter` object has not been set, then the unit of measurement associated with that parameter's value is undefined. (References: SBML L3V1 Section 4.7.3; SBML L3V2 Section 4.7.3.)

20703. ✅ The attribute `value` on a `Parameter` object must have a value of type `double`. (References: SBML L3V1 Section 3.1.5; SBML L3V2 Section 3.1.5.)

20704. ✅ The attribute `constant` on a `Parameter` object must have a value of type `boolean`. (References: SBML L3V1 Section 3.1.2; SBML L3V2 Section 3.1.2.)

20705. ✅ A `Parameter` object referenced by the attribute `conversionFactor` on a `Species` or `Model` object must have a value of "true" for its attribute `constant`. (References: SBML L3V1 Section 4.6.7; SBML L3V2 Section 4.6.7.)

20706. ✅ A `Parameter` object must have the required attributes `id` and `constant`, and may have the optional attributes `metaId`, `sboTerm`, `name`, `value` and `units`. No other attributes from the SBML Level 3 Core namespace are permitted on a `Parameter` object. (References: SBML L3V1 Section 4.7; SBML L3V2 Section 4.7.)

## Rules for InitialAssignment components

20801. ✅ The value of the attribute `symbol` in an `InitialAssignment` object must be the identifier of an existing `Compartment`, `Species`, `Parameter` or `SpeciesReference` object defined in the model, or any identifier in the `SiD` namespace of the model belonging to an element defined by an SBML Level 3 package as having with mathematical meaning. (References: SBML L3V1 Section 4.8; SBML L3V2 Section 4.8.)

20802. ✅ A given identifier cannot appear as the value of more than one `InitialAssignment` object's `symbol` attribute across the set of all `InitialAssignment` objects in a model. (References: SBML L3V1 Section 4.8; SBML L3V2 Section 4.8.)

20803. ✅ The identifier given as the value of the attribute `symbol` in any `InitialAssignment` object cannot also appear as the value of the `variable` attribute in an `AssignmentRule` object. In other words, a model cannot simultaneously define both an initial assignment and an assignment rule for the same species, compartment or parameter in a model. (References: SBML L3V1 Section 4.8; SBML L3V2 Section 4.8.)

20804. ✅ An `InitialAssignment` object may contain at most one `MathML math` element. (References: SBML L3V1 Section 4.8; SBML L3V2 Section 4.8.)
20805. ☑ An **InitialAssignment** object must have the required attribute **symbol** and may have the optional attributes **id**, **name**, **metaid** and **sboTerm**. No other attributes from the SBML Level 3 Core namespace are permitted on an **InitialAssignment** object. (References: SBML L3V1 Section 4.8; SBML L3V2 Section 4.8.)

## Rules for AssignmentRule, RateRule and AlgebraicRule components

20901. ☑ The value of an **AssignmentRule** object's **variable** attribute must be the identifier of an existing **Compartment**, **Species**, **Parameter** or **SpeciesReference** object defined in the model, or any identifier in the SIId namespace of the model belonging to an element defined by an SBML Level 3 package as having with mathematical meaning, and that is allowed to change over the course of a simulation. (References: SBML L3V1 Section 4.9.3; SBML L3V2 Section 4.9.3.)

20902. ☑ The value of a **RateRule** object's **variable** attribute must be the identifier of an existing **Species**, **Compartment**, **Parameter** or **SpeciesReference** object defined in the model, or any identifier in the SIId namespace of the model belonging to an element defined by an SBML Level 3 package as having with mathematical meaning, and that is allowed to change over the course of a simulation. (References: SBML L3V1 Section 4.9.4; SBML L3V2 Section 4.9.4.)

20903. ☑ Any **Compartment**, **Species**, **Parameter** or **SpeciesReference** object whose identifier is the value of the attribute **variable** in an **AssignmentRule** object, must have a value of "false" for its **constant** attribute. (References: SBML L3V1 Section 4.9.3; SBML L3V2 Section 4.9.3.)

20904. ☑ Any **Compartment**, **Species**, **Parameter** or **SpeciesReference** object whose identifier is the value of the attribute **variable** in a **RateRule** object, must have a value of "false" for its **constant** attribute. (References: SBML L3V1 Section 4.9.4; SBML L3V2 Section 4.9.4.)

20906. ☑ There must not be circular dependencies in the combined set of **InitialAssignment**, **AssignmentRule** and **KineticLaw** objects in a model. Each of these constructs has the effect of assigning a value to an identifier (i.e., the identifier given in the attribute **symbol** in **InitialAssignment**, the attribute **variable** in **AssignmentRule**, and the attribute **id** on the **KineticLaw**'s enclosing **Reaction**). Each of these constructs computes the value using a mathematical formula. The formula for a given identifier cannot make reference to a second identifier whose own definition depends directly or indirectly on the first identifier. (References: SBML L3V1 Section 4.9.5; SBML L3V2 Section 4.9.5.)

20907. ☑ Every **AssignmentRule**, **RateRule** and **AlgebraicRule** object may contain at most one MathML math element. (References: SBML L3V1 Section 4.9; SBML L3V2 Section 4.9.)

20908. ☑ An **AssignmentRule** object must have the required attribute **variable** and may have the optional attributes **id**, **name**, **metaid** and **sboTerm**. No other attributes from the SBML Level 3 Core namespace are permitted on an **AssignmentRule** object. (References: SBML L3V1 Section 4.9; SBML L3V2 Section 4.9.)

20909. ☑ A **RateRule** object must have the required attribute **variable** and may have the optional attributes **id**, **name**, **metaid** and **sboTerm**. No other attributes from the SBML Level 3 Core namespace are permitted on a **RateRule** object. (References: SBML L3V1 Section 4.9; SBML L3V2 Section 4.9.)

20910. ☑ An **AlgebraicRule** object may have the optional attributes **id**, **name**, **metaid** and **sboTerm**. No other attributes from the SBML Level 3 Core namespace are permitted on an **AlgebraicRule** object. (References: SBML L3V1 Section 4.9; SBML L3V2 Section 4.9.)

20912. ☑ There must not be circular dependencies in calculating the rate of change of any model variable. The *rateOf csymbol* may not be used directly nor indirectly in the calculation of the rate of change of the variable it references. In particular, the **RateRule** and **KineticLaw** constructs are used to calculate rates of change: the formulas they use may not contain *rateOf csymbols* referencing the model variables whose rates of change they control, nor may they reference variables who in turn are calculated (directly nor indirectly) by using a *rateOf csymbol* referencing those same changing variables. (Reference: SBML L3V2 Section 4.9.5)
## Rules for Constraint components

21001. ✓ (This validation rule does not apply in SBML Level 3 Version 2 Core.) <fnref n="9" />

21004. ✓ The contents of the **Message** subobject in a **Constraint** object must not contain an XML declaration (i.e., a string of the form `"<?xml version="1.0" encoding="UTF-8"?>"` or similar). (References: SBML L3V1 Section 4.10.2; SBML L3V2 Section 4.10.2.)

21005. ✓ The contents of the **Message** subobject in a **Constraint** object must not contain an XML DOCTYPE declaration (i.e., a string beginning with the characters `"<!DOCTYPE"`). (References: SBML L3V1 Section 4.10.2; SBML L3V2 Section 4.10.2.)

21007. ✓ A **Constraint** object may contain at most one MathML **math** element. (References: SBML L3V1 Section 4.10; SBML L3V2 Section 4.10.)

21008. ✓ A **Constraint** object may contain at most one **Message** subobject. (References: SBML L3V1 Section 4.10; SBML L3V2 Section 4.10.)

21009. ✓ A **Constraint** object may have the optional attributes **id**, **name**, **metaid** and **sboTerm**. No other attributes from the SBML Level 3 Core namespace are permitted on a **Constraint** object. (References: SBML L3V1 Section 4.10; SBML L3V2 Section 4.10.)

## Rules for Reaction components

21101. ✓ (This validation rule does not apply in SBML Level 3 Version 2 Core.) <fnref n="10" />

21103. ✓ (This validation rule does not apply in SBML Level 3 Version 2 Core.) <fnref n="11" />

21104. ✓ Apart from the general notes and annotation subobjects permitted on all SBML components, the **ListOfSpeciesReferences** container objects (i.e., the **Reaction** elements **listOfReactants** and **listOfProducts**) may only contain **SpeciesReference** objects. (References: SBML L3V1 Section 4.11; SBML L3V2 Section 4.11.)

21105. ✓ Apart from the general notes and annotation subobjects permitted on all SBML components, **ListOfModifierSpeciesReferences** container objects (i.e., the **Reaction** element **listOf modifiers**) may only contain **ModifierSpeciesReference** objects. (References: SBML L3V1 Section 4.11; SBML L3V2 Section 4.11.)

21106. ✓ A **Reaction** object may contain at most one of each of the following elements: **listOfReactants**, **listOfProducts**, **listOf modifiers**, and **kineticLaw**. (References: SBML L3V1 Section 4.11; SBML L3V2 Section 4.11.)

21107. ✓ The value of the attribute **compartment** in a **Reaction** object is optional, but if present, must be the identifier of an existing **Compartment** object defined in the model. (References: SBML L3V1 Section 4.11.1; SBML L3V2 Section 4.11.1.)

21108. ✓ The attribute **reversible** on a **Reaction** object must have a value of type **boolean**. (References: SBML L3V1 Section 3.1.2; SBML L3V2 Section 3.1.2.)

21109. ✓ (This validation rule does not apply in SBML Level 3 Version 2 Core.) <fnref n="12" />

<footnote n="9">⁹Original rule: "The MathML **math** element in a **Constraint** object must evaluate to a value of type **boolean**."</footnote>

<footnote n="10">¹⁰Original rule: "A **Reaction** object must contain at least one **SpeciesReference** object, either in its **listOfReactants** or its **listOfProducts** element. A reaction without any reactant or product species is not permitted, regardless of whether the reaction has any modifier species."</footnote>

<footnote n="11">¹¹Original rule: "The following are all optional in a **Reaction** object, but if any is present, it must not be empty: **KineticLaw**, the elements **listOfReactants** and **listOfProducts** (both **ListOfSpeciesReferences** objects) and the element **listOf modifiers** (a **ListOfModifierSpeciesReferences** object)."</footnote>

<footnote n="12">¹²Original rule: "The attribute **fast** on a **Reaction** object must have a value of type **boolean**."</footnote>
21110. ☑ A **Reaction** object must have the required attributes **id** and **reversible**, and may have the optional attributes **metaid**, **sboTerm**, **name** and **compartment**. No other attributes from the SBML Level 3 Core namespace are permitted on a **Reaction** object. (References: SBML L3V1 Section 4.11; SBML L3V2 Section 4.11.)

21150. ☑ A **ListOfSpeciesReferences** object may have the optional attributes **id**, **name**, **metaid** and **sboTerm**. No other attributes from the SBML Level 3 Core namespace are permitted on a **ListOfSpeciesReferences** object. (References: SBML L3V1 Section 4.11; SBML L3V2 Section 4.11.)

21151. ☑ A **ListOfModifierSpeciesReferences** object may have the optional attributes **id**, **name**, **metaid** and **sboTerm**. No other attributes from the SBML Level 3 Core namespace are permitted on an object of class **ListOfModifierSpeciesReferences**. (References: SBML L3V1 Section 4.11; SBML L3V2 Section 4.11.)

## Rules for SpeciesReference and ModifierSpeciesReference components

21111. ☑ The value of a **SpeciesReference** object's **species** attribute must be the identifier of an existing **Species** object in the model. (References: SBML L3V1 Section 4.11.3; SBML L3V2 Section 4.11.3.)

21114. ☑ The attribute **stoichiometry** on a **SpeciesReference** object must have a value of type **double**. (References: SBML L3V1 Section 3.1.5; SBML L3V2 Section 3.1.5.)

21115. ☑ The attribute **constant** on a **SpeciesReference** object must have a value of type **boolean**. (References: SBML L3V1 Section 3.1.2; SBML L3V2 Section 3.1.2.)

21116. ☑ A **SpeciesReference** object must have the required attributes **species** and **constant**, and may have the optional attributes **metaid**, **sboTerm**. **id**, **name** and **stoichiometry**. No other attributes from the SBML Level 3 Core namespace are permitted on a **SpeciesReference** object. (References: SBML L3V1 Section 4.11; SBML L3V2 Section 4.11.)

21117. ☑ A **ModifierSpeciesReference** object must have the required attribute **species** and may have the optional attributes **metaid**, **sboTerm**, **id** and **name**. No other attributes from the SBML Level 3 Core namespace are permitted on a **ModifierSpeciesReference** object. (References: SBML L3V1 Section 4.11; SBML L3V2 Section 4.11.)

## Rules for KineticLaw components

21121. ☑ All **Species** objects referenced in the MathML **math** element of a **KineticLaw** object within a given **Reaction** object must first be declared using **SpeciesReference** or **ModifierSpeciesReference** objects. In other words, if a **Species** object identifier appears in a MathML **ci** element within the **Reaction**'s **KineticLaw** **math** content, that same species' identifier must also appear in at least one object of type **SpeciesReference** or **ModifierSpeciesReference** within the **listOfReactants**, **listOfProducts** and/or **listOf Modifiers** elements of the **Reaction** object. (References: SBML L3V1 Section 4.11.5; SBML L3V2 Section 4.11.5.)

21123. ☑ (This validation rule does not apply in SBML Level 3 Version 2 Core.) <fnref n="13" />

21127. ☑ A **KineticLaw** object may contain at most one **ListOfLocalParameters** container object. (References: SBML L3V1 Section 4.11; SBML L3V2 Section 4.11.)

21128. ☑ Apart from the general notes and annotation subobjects permitted on all SBML components, a **ListOfLocalParameters** container object may only contain **LocalParameter** objects. (References: SBML L3V1 Section 4.2.8; SBML L3V2 Section 4.2.7.)

21129. ☑ A **ListOfLocalParameters** object may have the optional attributes **id**, **name**, **metaid** and **sboTerm**. No other attributes from the SBML Level 3 Core namespace are permitted on a **ListOfLocalParameters** object. (References: SBML L3V1 Section 4.11; SBML L3V2 Section 4.11.)

<footnote n="13">¹³Original rule: "The **ListOfLocalParameters** container object in a **KineticLaw** object is optional, but if present, it must not be empty."</footnote>
21130. ✓ **A KineticLaw** object may contain at most one MathML **math** element. (References: SBML L3V1 Section 4.11; SBML L3V2 Section 4.11.)

21132. ✓ A KineticLaw object may have the optional attributes id, name, metaid and sboTerm. No other attributes from the SBML Level 3 Core namespace are permitted on a KineticLaw. (References: SBML L3V1 Section 4.11; SBML L3V2 Section 4.11.)

## Rules for LocalParameter components

21171. ✓ The attribute **value** on a **LocalParameter** object must have a value of type **double**. (References: SBML L3V1 Section 3.1.5; SBML L3V2 Section 3.1.5.)

21172. ✓ **A LocalParameter** object must have the required attribute **id** and may have the optional attributes **id**, **name**, **metaid**, **sboTerm**, **name**, **value** and **units**. No other attributes from the SBML Level 3 Core namespace are permitted on a **LocalParameter** object. (References: SBML L3V1 Section 4.11; SBML L3V2 Section 4.11.)

21173. ✓ The **id** of a **LocalParameter** object must not be the same as the **species** attribute of any **Species-Reference** in the same **Reaction**. (References: SBML L3V2 Section 4.11.6.)

21174. ★ If the attribute **units** on a given **LocalParameter** object has not been set, then the unit of measurement associated with that parameter's value is undefined. (References: SBML L3V1 Section 4.11.6; SBML L3V2 Section 4.11.6.)

## Rules for Event components

21201. ✓ An **Event** object may contain at most one **Trigger** object. (References: SBML L3V1 Section 4.12.2; SBML L3V2 Section 4.12.2.)

21202. ✓ (This validation rule does not apply in SBML Level 3 Version 2 Core.) <fnref n="14" />

21203. ✓ (This validation rule does not apply in SBML Level 3 Version 2 Core.) <fnref n="15" />

21208. ✓ The attribute **useValuesFromTriggerTime** on an **Event** object must have a value of type **boolean**. (References: SBML L3V1 Section 3.1.2; SBML L3V2 Section 3.1.2.)

21209. ✓ A **Trigger** object may contain at most one MathML **math** element. (References: SBML L3V1 Section 4.12; SBML L3V2 Section 4.12.)

21210. ✓ A **Delay** object may contain at most one MathML **math** element. (References: SBML L3V1 Section 4.12; SBML L3V2 Section 4.12.)

21221. ✓ An **Event** object may contain at most one **Delay** object. (References: SBML L3V1 Section 4.12; SBML L3V2 Section 4.12.)

21222. ✓ An **Event** object may contain at most one **ListOfEventAssignments** object. (References: SBML L3V1 Section 4.12; SBML L3V2 Section 4.12.)

21223. ✓ Apart from the general notes and annotation subobjects permitted on all SBML components, a **ListOfEventAssignments** container object may only contain **EventAssignment** objects. (References: SBML L3V1 Section 4.12.5; SBML L3V2 Section 4.12.5.)

21224. ✓ A **ListOfEventAssignments** object may have the optional attributes **id**, **name**, **metaid** and **sboTerm**. No other attributes from the SBML Level 3 Core namespace are permitted on a **ListOfEventAssignments** object. (References: SBML L3V1 Section 4.12.5; SBML L3V2 Section 4.12.5.)

<footnote n="14">¹⁴Original rule: "The MathML math element of a Trigger object must evaluate to a value of type boolean."</footnote>

<footnote n="15">¹⁵Original rule: "The **ListOfEventAssignments** container object in an **Event** object is optional, but if present, it must not be empty."</footnote>
21225. ☑ An **Event** object must have the required attribute **useValuesFromTriggerTime**, and in addition, it may have the optional attributes **metaid**, **sboTerm**, **id**, and **name**. No other attributes from the SBML Level 3 Core namespace are permitted on an **Event** object. (References: SBML L3V1 Section 4.12; SBML L3V2 Section 4.12.)

21226. ☑ A **Trigger** object must have the required attributes **persistent** and **initialValue**, and in addition, it may have the optional attributes **id**, **name**, **metaid** and **sboTerm**. No other attributes from the SBML Level 3 Core namespace are permitted on a **Trigger** object. (References: SBML L3V1 Section 4.12; SBML L3V2 Section 4.12.)

21227. ☑ A **Delay** object may have the optional attributes **id**, **name**, **metaid** and **sboTerm**. No other attributes from the SBML Level 3 Core namespace are permitted on a **Delay** object. (References: SBML L3V1 Section 4.12; SBML L3V2 Section 4.12.)

21228. ☑ The attribute **persistent** on an **Trigger** object must have a value of type **boolean**. (References: SBML L3V1 Section 3.1.2; SBML L3V2 Section 3.1.2.)

21229. ☑ The attribute **initialValue** on a **Trigger** object must have a value of type **boolean**. (References: SBML L3V1 Section 3.1.2; SBML L3V2 Section 3.1.2.)

21230. ☑ An **Event** object may contain at most one **Priority** object. (References: SBML L3V1 Section 4.12; SBML L3V2 Section 4.12.)

21231. ☑ A **Priority** object may contain at most one MathML **math** element. (References: SBML L3V1 Section 4.12; SBML L3V2 Section 4.12.)

21232. ☑ A **Priority** object may have the optional attributes **id**, **name**, **metaid** and **sboTerm**. No other attributes from the SBML Level 3 Core namespace are permitted on a **Priority** object. (References: SBML L3V1 Section 4.12; SBML L3V2 Section 4.12.)

## Rules for EventAssignment components

21211. ☑ The value of the attribute **variable** in an **EventAssignment** object may only be the identifier of an existing **Compartment**, **Species**, **Parameter** or **SpeciesReference** object in the model, or any identifier in the SId namespace of the model belonging to an element defined by an SBML Level 3 package as having with mathematical meaning, and that is allowed to change over the course of a simulation. (References: SBML L3V1 Section 4.12.5; SBML L3V2 Section 4.12.5.)

21212. ☑ Any **Compartment**, **Species**, **Parameter** or **SpeciesReference** object whose identifier is used as the value of the attribute **variable** of an **EventAssignment** object, must have a value of **false** for its **constant** attribute. (References: SBML L3V1 Section 4.12.5; SBML L3V2 Section 4.12.5.)

21213. ☑ An **EventAssignment** object may contain at most one MathML **math** element. (References: SBML L3V1 Section 4.12; SBML L3V2 Section 4.12.)

21214. ☑ An **EventAssignment** object must have the required attribute **variable** and may have the optional attributes **id**, **name**, **metaid** and **sboTerm**. No other attributes from the SBML Level 3 Core namespace are permitted on an **EventAssignment** object. (References: SBML L3V1 Section 4.12; SBML L3V2 Section 4.12.)
## B A method for assessing whether an SBML model is overdetermined

As explained in Section 4.9.5 on p. 64, an SBML model must not be overdetermined. It is possible to use purely static analysis to assess this condition for the system of equations implied by a model, by constructing a bipartite graph of the model's variables and equations and then searching for a maximal matching (Chartrand, 1977). An efficient algorithm for finding a maximal matching is described by Hopcroft and Karp (1973). In this appendix, we provide a concrete application to SBML of the general approach described in Section 4.9.5 on p. 64. The approach is defined in terms of the ordinary differential equations (ODEs) implied by an SBML model; despite our use of a differential equation framework for this explanation, it should be understood that this use of ODEs has no implication about the framework actually used to simulate the model.

### Definition of the method

First, we assume that an ODE is constructed for each species determined by one or more Reaction's KineticLaw math expressions. We also assume that the model has already been determined to be valid in all other respects (e.g., there are no undefined variables in the equations), and what remains is to evaluate whether it is overdetermined.

We construct the bipartite graph for a given SBML model as follows:

1. For each of the following in the model, create one vertex representing an equation:

(a) Every Species object having `boundaryCondition`="false", `constant`="false", and which is referenced as a reactant or product in one or more Reaction objects containing KineticLaw objects

(b) Every AssignmentRule object

(c) Every RateRule object

(d) Every AlgebraicRule object

(e) Every KineticLaw object

2. For each of the following in the model, create one vertex representing a variable:

(a) Every Species object having `constant`="false"

(b) Every Compartment object having `constant`="false"

(c) Every global Parameter having `constant`="false"

(d) Every SpeciesReference object having `constant`="false"

(e) Every Reaction object

3. For each of the following, create one edge:

(a) Every vertex created in step 2(a) to that species' equation vertex created in step 1(a)

(b) Every vertex created in step 1(b) to the particular vertex created in steps 2(a)–2(e) that represents the variable referenced by the **variable** attribute of the rule

(c) Every vertex created in step 1(c) to the particular vertex created in steps 2(a)–2(e) that represents the variable referenced by the **variable** attribute of the rule

(d) Every vertex created in step 1(e) to the particular vertex created in step 2(e) that is the Reaction object containing that particular KineticLaw object

(e) Every vertex created in steps 2(a)–2(e) representing an identifier appearing as the content of a MathML ci element within an expression of an AlgebraicRule, to the vertex for that particular AlgebraicRule created in step 1(d)

### Example application of the method

What follows is an example of applying the method above to the SBML model shown below:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<sbml xmlns="http://www.sbml.org/sbml/level3/version2/core" level="3" version="2">
    <model id="example" substanceUnits="mole" volumeUnits="litre"
           timeUnits="second" extentUnits="mole">
        <listOfUnitDefinitions>
            <unitDefinition id="per_time">
                <listOfUnits>
                    <unit kind="second" exponent="-1" scale="0" multiplier="1"/>
                </listOfUnits>
            </unitDefinition>
        </listOfUnitDefinitions>
        <listOfCompartments>
            <compartment id="C" size="1" spatialDimensions="3" constant="true"/>
        </listOfCompartments>
        <listOfSpecies>
            <species id="S1" compartment="C" initialConcentration="1" constant="false"
                     boundaryCondition="false" hasOnlySubstanceUnits="false"/>
            <species id="S2" compartment="C" initialConcentration="0" constant="false"
                     boundaryCondition="false" hasOnlySubstanceUnits="false"/>
        </listOfSpecies>
        <listOfRules>
            <algebraicRule>
                <math xmlns="http://www.w3.org/1998/Math/MathML">
                    <apply>
                        <minus/>
                        <apply> <plus/> <ci> S1 </ci> <ci> S2 </ci> </apply>
                        <cn> 5 </cn>
                    </apply>
                </math>
            </algebraicRule>
        </listOfRules>
        <listOfReactions>
            <reaction id="R" reversible="false">
                <listOfReactants>
                    <speciesReference species="S1" stoichiometry="1" constant="true"/>
                </listOfReactants>
                <listOfProducts>
                    <speciesReference species="S2" stoichiometry="1" constant="true"/>
                </listOfProducts>
                <kineticLaw>
                    <math xmlns="http://www.w3.org/1998/Math/MathML">
                        <apply> <times/> <ci> C </ci> <ci> k1 </ci> <ci> S1 </ci> </apply>
                    </math>
                </kineticLaw>
                <listOfLocalParameters>
                    <localParameter id="k1" value="0.1" units="per_time"/>
                </listOfLocalParameters>
            </reaction>
        </listOfReactions>
    </model>
</sbml>
```

For the model above, we create *equation* vertices as follows:

1. [Corresponding to step 1(a) in Section B on the preceding page.] For every *Species* object which has **boundaryCondition** = "false", **constant** = "false", and which is referenced as a reactant or product in one or more *Reaction* objects containing *KineticLaw* objects. This generates two vertices, for "S1" and "S2".

2. [Corresponding to step 1(b) in Section B on the previous page.] Every *AlgebraicRule* object. This generates one vertex, for the model's lone algebraic rule (call it "rule").

3. [Corresponding to step 1(e) in Section B on the preceding page.] Every *KineticLaw* object. This generates one vertex, for the lone kinetic law in the model (call it "law").
We create *variable* vertices for the following:

1. [Corresponding to step 2(a) in Section B on p. 175.] Every *Species* object having *constant* = "false". This generates two vertices, for "S1" and "S2".

2. [Corresponding to step 2(e) in Section B on p. 175.] Every *Reaction* object. This generates one vertex, for "R".

Note that it is not necessary to include parameters declared within **KineticLaw** objects because they are local to a particular reaction and cannot be affected by rules. With the steps above, we have the following set of graph nodes:

<figure><img src="image_40.png" /><figcaption>Vertices for variables</figcaption></figure>

Next, we create edges following the procedure described above. Doing so results in the following graph:

<figure><img src="image_41.png" /><figcaption>Vertices for variables</figcaption></figure>

The algorithm of Hopcroft and Karp (1973) can now be applied to search for a maximal matching of the bipartite graph. A maximal matching is a graph in which each vertex is connected to at most one other vertex and the maximum possible number of connections have been made. Doing so here results in the following:

<figure><img src="image_42.png" /><figcaption>Vertices for variables</figcaption></figure>

If the maximal matching of the bipartite graph leaves any equation vertex unconnected, then the model is considered overdetermined. That is the case for the example shown here, because the equation vertex for "rule" is unconnected in the maximal matching.