## Kappa tools reference manual (release e52465f)

corresponding author: jean.krivine@irif.fr

## Chapter 1Introduction

### 1.2 Preamble

This manual describes the Kappa language and details the usage of its tool suite.

Kappa is one member of the growing family of rule-based languages. Rule-based modelling has attracted recent attention in developing biological models that are concise, comprehensible, easily extensible, and allows one to deal with the combinatorial complexity of multi-state and multi-component biological molecules.

From the description of a system by the deﬁnition of a set of entities and the enumeration of their local rule of interraction, Kappa tools provide a framework to study statically and dynamically the system without ever enumerating all its reachable states (unless very explicitely asked to by users).

In Kappa, a mixture of entities is represented as a site graphs and temporal local transformations as rewrites.

First contact with Kappa as well as interactive model developement could occurs in the Kappapp available online and as downloadable software on main platforms. Intensive scientiﬁc usage should occurs by scripting around the command line tools or by using the Python client.

After a small teaser, this manual provides an exhaustive list of what can be done and how with the tools. It is not intended as a tutorial on rule-based modelling.

To get an idea of how Kappa is used in a modelling context, the reader can consult the following note Agile modelling of cellular signalling (SOS’08). A longer article, expounding on causal analysis is also available: Rule-based modelling of cellular signalling (CONCUR’07). See also this tutorial: Modelling epigenetic information maintenance: a Kappa tutorial.

### 1.3 Show me a running example

See it really running in the online user interface by clicking on the try button on https://www.kappalanguage.org/.

A minimal Kappamodel looks like:

1/* Signatures*/
2%agent: A(x, c)             // Declaration of agent A
3%agent: B(x)               // Declaration of agent B
4%agent: C(x1{u p}, x2{u p}) // Declaration of agent C with 2 modifiable sites
5/* Variables */
6%var: on_rate  1.0E-4 // per molecule per second
7%var: off_rate 0.1    // per second
8%var: mod_rate 1      // per second
9/* Rules */
10a.b A(x[.]),B(x[.]) <-> A(x[1]),B(x[1]) @ on_rate, off_rate       //A and B bind and dissociate
11ab.c A(x[_], c[.]),C(x1{u}[.]) -> A(x[_], c[2]),C(x1{u}[2]) @ on_rate //AB binds unphosphorilated C
12modx1 C(x1{u}[1]),A(c[1]) -> C(x1{p}[.]),A(c[.]) @ mod_rate        //ABC modifies x1
13a.c A(x[.],c[.]), C(x1{p}[.], x2{u}[.]) ->
14      A(x[.],c[1]), C(x1{p][.], x2{u}[1]) @ on_rate    //A binds x1_phos C on x2
15modx2 A(x[.], c[1]),C(x1{p}[.], x2{u}[1]) ->
16         A(x[.], c[.]),C(x1{p}[.], x2{p}[.]) @ mod_rate  //AC modifies x2
17/* Observation */
18%obs: AB  |A(x[x.B])|
19%obs: Cuu |C(x1{u}, x2{u})|
20%obs: Cpu |C(x1{p}, x2{u})|
21%obs: Cpp |C(x1{p}, x2{p})|
22/*Initial conditions */
23%init: 1000  A(),B()
24%init: 10000 C(x1{u}, x2{u})

Lines 1-4 of this kappa ﬁle contain signature declarations. Agents of type C have two sites x1 and x2 whose internal state may be u (unphosphorylated) or p (phosphorylated). Line 11, rule 'ab.c' binds an A connected to someone on site x to a C.

There are two main points to notice about this model: A can modify both sites of C once it is bound to them. However, only an A bound to a B can connect on x1 and only a free A can connect on x2. Note also that x2 is available for connection only when x1 is already modiﬁed.

We try ﬁrst a coarse simulation of $100,000$ events (10 times the number of agents in the initial system).

• KaSim ABC.ka -u event -l 100000 -p 1000 -o abc.csv

Plotting the content of the abc.csv ﬁle, one notices that nothing signiﬁcantly interesting happens to the observables after 250s. So we can now specify a meaningful time limit by running:

• KaSim ABC.ka -l 250 -p 0.25 -o abc.out

which produces the data points whose rendering is given in Fig. 1.1.

We will use variant of this model as a running example for the next chapter.

## Chapter 2The Kappa language

### 2.1 General structure

A model is represented in Kappa by a set of Kappa Files. We use KF to denote the union of the ﬁles that are given as input to a tool.

A KF is composed of a list of declaration. Declarations can be: agent and token signatures (Sec. 2.3), rules (Sec. 2.5), variables (Sec. 2.4), initial conditions (Sec. 2.6), intervention (Sec. 2.7) and parameter conﬁgurations (Sec. 5.4).

The KF’s structure is quite ﬂexible. Neither dividing into several sub-ﬁles nor the order of declarations matters (for the exception of interventions and variable declarations, see respectively Sections 2.7 and 2.4 for details).

Comments works like in the C language. It can be used either by inserting the marker // that tells KaSim to ignore the rest of the line or by putting any text between the delimiters /* and */.

The following sections present formal grammars. Here are hints to read them. Terminal symbols are written in (blue) typed font, and $𝜀$ stands for the empty list. An identiﬁer Id can be any string generated by a regular expression of the type $\text{_}\phantom{\rule{1em}{0ex}}{\left[a-z\phantom{\rule{1em}{0ex}}A-Z\phantom{\rule{1em}{0ex}}0-9\phantom{\rule{1em}{0ex}}\text{_}\phantom{\rule{1em}{0ex}}-\phantom{\rule{1em}{0ex}}+\right]}^{+}|\left[a-z\phantom{\rule{1em}{0ex}}A-Z\right]{\left[a-z\phantom{\rule{1em}{0ex}}A-Z\phantom{\rule{1em}{0ex}}0-9\phantom{\rule{1em}{0ex}}\text{_}\phantom{\rule{1em}{0ex}}-\phantom{\rule{1em}{0ex}}+\right]}^{\ast }$.

### 2.2 Sited-graph pattern: Kappa expression

The state of the system is represented in Kappa as a sited graph: a graph where edges use sites in nodes. One must think sites as resources. At most one edge of the graph can use a site of a node (representing an agent in our case). Moreover, all the sites of an agent must have diﬀerent names.

This leads to the property that an embedding between 2 sited graphs is completely deﬁned by the image of one node. This is absolutely critical for the eﬃciency and we call this concept the rigidity of Kappa.

Table 2.1: Kappa expressions.
 Kappa_expression ::= agent_expression , Kappa_expression $\mid 𝜀$ agent_expression ::= Id(interface) interface ::= Id internal_state link_state , interface $\mid 𝜀$ internal_state ::= $𝜀$ | {.} | {Id} link_state ::= $𝜀$ | [.] | [n] | [_] | [#] | [Id.Id]

#### 2.2.1 Graphs

The ASCII syntax we use to represent sited graphs follows the skeletons (describe formally in Table 2.1):

• We write the type of the agent and then its interface (the space separated list its sites) between parenthesis.
• The state of a site is written after its name. Sites can have 2 kind of states: a linking state and an internal states. The order in which they are speciﬁed does not matter.
• The linking state of a site is written in between squared brackets: []
• The internal state of a site is written in between curly brackets: {}
• When the site is free (i.e. it is not a member of an edge), its linking state is written with a dot: [.]. For example, the following graph:

is written as A(x[.], y{p}[.], z{e0}[.]).

• When a site is a part of an edge, one assign an arbitrary positive integer identiﬁer $n$ to this edge and one specify the appurtenance of the site to this edge by writing the linking state [n]. The following graph:

can be reprensented as A(x[23], y[4]{u}, z{e1}[.]), A(x[4], y{u}[95], z{e1}[.]), A(x[95], y{u}[23], z{e1}[.]).

Remark Each link identiﬁer appears exactly twice.

#### 2.2.2 Patterns

Kappa strength is to describe transformations by only mentioning (and storing) the relevant part of the subgraph required for that transformation to be possible. This is the don’t care, don’t write (DCDW) principle which plays a key role in resisting combinatorial explosion when writing models.

If a transformation occurs independently from the state of a site of an agent, do not mention it in the pattern to match. The pattern A(x[.],z[.]) represents an agent of type A whose sites x and z are free but the sites y and z can be in any internal state and the site y can be linked or not to anything.

If the link state of a site does not matter but the internal state does, just mention it. An agent A whose sites x and z are free, y is in state u and z in state e2 is written as A(x[.],y{u},z{e2}[.]).

A state that is modiﬁed (by a rule that will be presented just below) always matter. For such situation, the symbol # (meaning “whatever” state) has been introduced.

In Kappa, in order to require a site to be bound for an interaction to occur, one may use the semi-link construct [_] which does not specify who the partner of the bond is. For instance, in the following instruction: %var: ab|A(x[_]),B(y[_])|, the variable 'ab' will count the number of As and Bs connected to some agents, including the limit case A(x[1]),B(y[1]). It is sometimes convenient to specify the type of the semi-link, in order to restrict the choice of the binding partner. For instance, in the following instruction: %var: ab|A(x[y.B]),B(y[x.A])|, the variable 'ab' will count the number of As whose site x is connected to a site y of B, plus the number of Bs whose site y is connected to a site x of A. Note that, this still includes the case A(x[1]),B(y[1]).

Remark Transformations on semi-links and links type induce side eﬀects (eﬀect on unmentioned agents/unmentioned site of agent) and can even do not make sense at all. What would mean to remove the link to A but not the link to B in the example above? Be careful when one use them.

### 2.3 Agent signatures

Kappa tools can seek in the KF what agents are used, what sites they have and what states the sites are in but it is error prone: just make a typo once and the tools won’t complain and create a nonsens new agent/site/states...

To avoid that, Agent signatures can be deﬁned and tools will then ensure that agents respect their signature.

Agent signatures list all the agents that will appear in the KF. They enumerate the name of interaction sites an agent has. They provide information about sites binding capabilities. They specify whether a site has internal state and if so give the possibilities.

A signature is declared in the KF by the following line:

• %agent: signature_expression

according to an extention of the grammar given in Table 2.1. Linking states and internal states are space separated lists instead of being singleton. Site binding capabilities are speciﬁed by giving a list typed semi-links.

For instance, the line:

1%agent: A(x[y.A], y{u p}[x.A], z{e0 e1 e2}) // Signature of agent A

will declare an agent A with 3 (interaction) sites x,y and z, the site y possessing two internal states u and p (for instance, for the unphosphorylated and phosphorylated forms of y) and the site z having three possible states $e0$, $e1$ and $e2$, sites x and sites y being able to bind (intra agent or inter agents).

Special case If no agent signature provides any site binding capabilities, constraints are released and any site of any agent is allowed to bind any site of any agent.

### 2.4 Algebraic expressions, variables and observables

Algebraic expressions original purpose was to deﬁne kinetic rates for rules but many components of a KF will now implies algebraic expressions. Their syntax are deﬁned in Table 2.2 (available symbols for variable, constants and operators are given in Table 2.3).

Table 2.2: Algebraic expressions.
 algebraic_expression ::= $x\in ℝ$ $\mid$ variable $\mid$ algebraic_expression binary_op algebraic_expression $\mid$  tcbunary_op (algebraic_expression) $\mid$ boolean_expression [?] algebraic_expression [:] algebraic_expression

The last item of the list is an if-expression. boolean_expression are described in Table 2.7. Think very carefully whether it is the correct thing to do before using it. Mechanistic conditions have to be expressed in rule bodies and not in rule rates!

Table 2.3: Symbols usable in algebraic expressions.
[int]                                                                           the ﬂoor function x  x  +,-,*,/,^                                                                       basic mathematical operators (inﬁx notation)                                                                                    [mod]                                                                           the modulo operator (inﬁx notation)                                                                                                [max]                                                                           the maximum of two values                                                                                                           [min]                                                                           the minimum of two values
 variable Interpretation [E] the total number of (productive) simulation events since the beginning of the simulation [E-] the total number of null events [T] the bio-time of the simulation [Tsim] the cpu-time since the beginning of the simulation 'v' the value of variable 'v' (declared by using the %var: statement) |t| the concentration of token 2.5.5 t |Kappa_expression| number of occurences of the pattern Kappa_expression inf symbol for $\infty$ unary/binary_op Interpretation [$f$] usual mathematical functions and constants with $f\in \left\{\mathtt{\text{log,exp,sin,cos,tan,sqrt,pi}}\right\}$

It is possible to declare variables for later use with the declaration:            %var: 'var_name'  (algebraic_expression) where var_name can be any string. For instance, the declaration 1%var: homodimer |A(x[1]),A(x[1])| 2%var: aa homodimer/2 deﬁne two variables, the ﬁrst one tracking the number of embeddings of A(x[1]),A(x[1]) in the graph over time, while the second divides this value by 2: the number of automorphisms in A(x[1]),A(x[1]). Note that variables that are used in the expression of another variable must be declared beforehand. More importantly, KaSim may output values of an algebraic expression in the data ﬁle (see option -p in Chapter 4) by using the primitive  1%plot: var_name One may use the shortcut:            %obs: 'var_name'  algebraic_expression to declare a variable and at the same time require it to be outputted in the data ﬁle. 2.5    Rules Dynamics of agents is described in the KF by deﬁning rules. There are two ways of specifying rules:            following the chemical intuition (with the burden of a subtle before/after correspondance),      by giving two Kappa_expressions. The ﬁrst one, called left hand side (LHS), represents                                                                                                                                                                            what one need to apply the rule. The second, the right hand side (RHS), describes      what one obtain once the rule is applied. In Kappa, they are separated by an arrow       .            by giving one Kappa_expression with edition. The Kappa expression still represents      the necessary context for the rule to apply. Modiﬁcations are speciﬁed locally inside      the expression right after tests. Both are allowed in Kappa and are described in both next subsections. In any case, rule speciﬁcation is optionally preﬁxed by a rule name (written between two symbols ') and always followed by a rule rate. Rate expressions (which are syntactically algebraic expressions) are given by the grammars in Table 2.5 and Table 2.2 (respectively) but can be thought at ﬁrst as positive real numbers. A complete rule in the chemical representation looks like:            'rule nameKappa_expression        Kappa_expression rate One may also declare a bi-directional rule in chemichal notation by using the convention:            'bi-rule'Kappa_expression        Kappa_expression @rate+,rate The above declaration is equivalent to write, in addition to the rule named 'bi-ruleand another rule named 'bi-rule_opwhich swaps left and right hand sides, and has rate rate. 2.5.1    Chemical notation rules This is the most intuitive representation. Nevertheless, it induces duplication of the unmodiﬁed context between LHS and RHS which can lead to even more errors when edition a posteriori on the left are not correctly reported on the right.                                                                                                                                                                       A simple rule With the signature of deﬁned in Section 2.3, the line  1Adimerization A(x[.]),A(y{p}[.]) -> A(x[1]),A(y{p}[1]) @ gamma declares a dimerization rule between two instances of agent provided the second agent is phosphorylated on site (this is the meaning of p). Remember that the identiﬁer [1] of the bound is arbitrary and that following DCDW, the site z of is not mentioned in the expression because it has no inﬂuence on the triggering of this rule. Degradation and synthesis In the RHS of a rule, the k-th agent must correspond to the (transformed) k-th agent of the LHS. If one want to create or delete agent, one must put a ghost agent (written with a dot) at their corresponding place on the left/right hand side of the rule. Sticking with A’s signature, one can express that an unphosphoralated can collapse if not linked to anyone (regardless of the state of z) by writing  1destroyA A(x[.], y{u}[.], z[.]) -> . @ gamma Similarly, the rule  1buildingA A(z[.]), . -> A(z[1]),A(x[1]) @ gamma                                                                                                                                                                       indicates that an agent is free on site z, no matter what its internal state is, may beget a new copy of bound to it via site x. Note that in the RHS, the interface of the new copy is not completely described. Following the DCDW conventionKaSim will assume that the sites that are not mentioned are created in the default state, i.e. they appear free of any bond and their internal state (if any) is the ﬁrst of the list shown in the signature (here state for and for z). Side eﬀects It may happen that the application of a rule has some side eﬀects on agents that are not mentioned explicitly in the rule. Consider for instance the previous rule:  1deletingA A(x[1]), A(z[1]) -> A(x[.]), . @ gamma The in the graph that is matched to the second occurrence of in the LHS will be deleted by the rule. As a consequence, all its sites will disappear together with the bonds that were pointing to them. For instance, when applied to the following graph:            G =A(x[1],y{p}[.],z{e2}[.]),      A(x[2], y{u}[.], z{e0}[1]), C(t[2]) the above rule will result in a new graph G = A(x[1],y{p}[.],z{e2}[.]),C(t[.]) where the site t of C is now free as side eﬀect.

Whatever symbols for link state [#] (for whatever state bound or not), [_] (for bound to some site), may also induce side eﬀects when they are not preserved in the RHS of a rule, as in

1DisconnectA A(x[_]) -> A(x[.]) @ gamma

or

1ForcebindA A(x[#]),C(t[.]) -> A(x[1]),C(t[1]) @ gamma

To avoid mistakes, sites and states mentioned on the left must be exactly the same as sites mentioned on the right. Use the explicit “whatever” [#] state when needed.

#### 2.5.2 Edit notation rules

Near any modiﬁed element, modiﬁcation is speciﬁed. Created agents are postﬁxed by a $+$. Degraded agents are postﬁxed by a $-$. Site modiﬁcations are described by writing the new (linking or internal) state after the symbol $∕$ inside the (curly/squared) bracket. Therefore, $∕.$ (inside squared brackets) means that the site becomes free, $∕9$ means that the site becomes part of link $9$ and $∕zzz$ inside curly brackets means that the new internal state of the site is $zzz$.

Here are all the rules mentioned above (+1 extra) translated in this unambiguous notation:

2destroyA A(x, y{u}, z)- @ gamma
3buildingA A(z[./1]), A(x[1])+ @ gamma
4deletingA A(x[1/.]), A(z[1])- @ gamma
5weird A(z[1])-, A(x[1])-, A(x[.])+ @ gamma
6DisconnectA A(x[_/.]) @ gamma
7ForcebindA A(x[#/1]), C(t[./1]) @ gamma
8phosC C(x1{u/p}[1/.]),A(c[1/.]) @ modrate

#### 2.5.3 Rates

Kappa rules are equipped with one (or two) kinetic rate(s). A rate is an algebraic expression (often simply a real number) evaluated as such, called the individual-based or stochastic rate constant, it is the rate at which the corresponding rule is applied per instance of the rule. Its dimension is the inverse of a time $\left[{T}^{-1}\right]$.

The stochastic rate is related to the concentration-based rate constant $k$ of the rule of interest by the following relation:

 $k=\gamma {\left(\mathsc{𝒜}\phantom{\rule{3.0235pt}{0ex}}V\right)}^{\left(a-1\right)}$ (2.1)

where $V$ is the volume where the model is considered, $\mathsc{𝒜}=6.022\cdot 1{0}^{23}$ is Avogadro’ s number, $a\ge 0$ is the arity of the rule (i.e. $2$ for a bimolecular rule).

In a modelling context, the constant $k$ is typically expressed using molars $M:=\mathit{m}oles\phantom{\rule{0.3em}{0ex}}{l}^{-1}$ (or variants thereof such as $\mu M$, $nM$), and seconds or minutes. If we choose molars and seconds, $k$’ s unit is ${\mathit{M}}^{1-a}{\mathit{s}}^{-1}$, as follows from the relation 2.1.

Concentration-based rates are usually favoured for measurements and/or deterministic models, so it is useful to know how to convert them into individual-based ones used by KaSim. Here are typical volumes used in modelling:

• Mammalian cell: $V=2.25\phantom{\rule{3.0235pt}{0ex}}1{0}^{-12}l$ ($1l=1{0}^{-3}{m}^{3}$), and $\mathsc{𝒜}V=1.35\phantom{\rule{3.0235pt}{0ex}}1{0}^{12}$.

A concentration of $1M$ in a mammalian cell volume corresponds to $1.35\phantom{\rule{3.0235pt}{0ex}}1{0}^{12}$ molecules; $1nM\approx 1350$ molecules per cell.

• Yeast cell (haploid): $V=4\phantom{\rule{3.0235pt}{0ex}}1{0}^{-14}l$, and $\mathsc{𝒜}V=2.4\phantom{\rule{3.0235pt}{0ex}}1{0}^{10}$.

A concentration of $1M$ in a yeast cell volume corresponds to $2.4\phantom{\rule{3.0235pt}{0ex}}1{0}^{10}$ molecules; $1nM\approx 24$ molecules per cell. The volume is doubled in a diploid cell.

• E. Coli cell: $V=1{0}^{-15}l$, and $\mathsc{𝒜}V=1{0}^{8}$.

A concentration of $1M$ in a yeast cell volume corresponds to $1{0}^{8}$ molecules; $1{0}^{n}M\approx 1$ molecule per cell.

The table 2.4 lists typical ranges for deterministic rate constants and their stochastic counterparts assuming a mammalian cell volume.

Table 2.4: Example of kinetic rates.
 process $k$ $\gamma$ general binding $1{0}^{7}-1{0}^{9}$ $1{0}^{-5}-1{0}^{-3}$ general unbinding $1{0}^{-3}-1{0}^{-1}$ $1{0}^{-3}-1{0}^{-1}$ dephosphorylation 1 1 phosphorylation 0.1 0.1 receptor dimerization $2\phantom{\rule{3.0235pt}{0ex}}1{0}^{6}$ $1.6\phantom{\rule{3.0235pt}{0ex}}1{0}^{-6}$ receptor dissociation $1.6\phantom{\rule{3.0235pt}{0ex}}1{0}^{-1}$ $1.6\phantom{\rule{3.0235pt}{0ex}}1{0}^{-1}$

#### 2.5.4 Ambiguous molecularity

Using a Kappa rule of the form A(x[.]),B(y[.])$\to \dots \phantom{\rule{0.3em}{0ex}}$ @ $\gamma$ is not a good practice, where this rule could be applied in a context where A and B are sometimes already connected and sometimes disconnected. This would lead to an inconsistency in the deﬁnition of the kinetic rate $\gamma$ which should have a volume dependency in the former case and be volume independent in the latter case (e.g. see Section 2.5.3).

This sort of ambiguity should be resolved, if possible, by reﬁning the ambiguous rule into cases that are either exclusively unary or binary. Each reﬁnement having a kinetic rate that is consistent with its molecularity. Note that in practice, for models having a large number of agents, it is suﬃcient to assume that the rule A(x[.]),B(y[.])$\to \dots \phantom{\rule{0.3em}{0ex}}$ @ $\gamma$ will have only binary instances. In this case, it suﬃces to consider the approximate model:

1assumedbinaryAB A(x[.]),B(y[.]) -> ... @ ga_2
2unaryAB A(x[.],c[1]),C(a[1],b[2]),B(y[.],c[2]) -> ... @ k_1

There exist systems where enumerating unary cases becomes impossible or where the approximation on binary instances is wrong. As an alternative, one should use the Kappa notation for ambiguous rules:

• 'my rule'Kappa_expression $\to$ Kappa_expression @${\gamma }_{2}\left\{{k}_{1}\right\}$

which will tell KaSim to apply the rule named 'my rule' with a rate ${\gamma }_{2}$ for binary instances and a rate ${k}_{1}$ for unary instances.

The obtained model will behave exactly as a model in which the ambiguous rule has been replaced by unambiguous reﬁnements. However the usage of such rule slowdowns simulation in a signiﬁcant manner depending on various parameters (such as the presence of large polymers in the model). We give below an example of a model utilizing binary/unary rates for rules1 .

1%agent: A(b,c)
2%agent: B(a,c)
3%agent: C(b,a)
4//
5%var: V 1
6%var: k1 INF
7%var: k2 1.0E-4/V
8%var: k_off 0.1
9//
10a.b A(b[.]),B(a[.]) -> A(b[1]),B(a[1]) @ k2{k1}
11a.c A(c[.]),C(a[.]) -> A(c[1]),C(a[1]) @ k2{k1}
12b.c B(c[.]),C(b[.]) -> B(c[1]),C(b[1]) @ k2{k1}
13//
14a..b A(b[a.B]) -> A(b[.]) @ k_off
15a..c A(c[a.C]) -> A(c[.]) @ k_off
16b..c B(c[b.C]) -> B(c[.]) @ k_off
17//
18%var: n  1000
19//
20%init: n  A(),B(),C()
21%mod: [E] = 10000 do \$STOP "snap.dot";

Notice at lines 10-12 the use of binary/unary notation for rules. As a result binding between freely ﬂoating agents will occur at rate 'k2' while binding between agents that are part of the same complex will occur at rate 'k1'. Line 21 contains a intervention that requires KaSim to stop the simulation after 10,000 events and output the list of molecular species present in the ﬁnal mixture as a dot ﬁle (e.g. see Section 2.7) that we give in Figure 2.1.

For rules with unary rates, one can also specify a horizon. For example in the following rule:

1a.b A(b[.]),B(a[.]) -> A(b[1]),B(a[1]) @ k2{k1:5}

the unary rate is applied only when the agents $A$ and $B$ are at a horizon $5$ (or closer), of each other. Horizon is an algebraic expression. It is always truncated to a positive integer during simulation. This feature can change in the future.

Table 2.5: Rate expressions.
 rate_expression ::= algebraic_expression | algebraic_expression {algebraic_expression:algebraic_expression}

#### 2.5.5 Hybrid rules

In Kappa, there can be a special treatment of entities that cannot bind anything: tokens. Tokens can only appear or disappear, they are typically used to represent small particles such as ions, ATP, etc.

Tokens may have a continuous concentration.

Token signatures are declared using a statement of the form:

1%token: ca+ # Signature of calcium token

It is possible to mix agents and tokens in hybrid rules (which may also be bi-directional). A hybrid rule has the following form:

• Kappa_expression | token_expression $\to$ Kappa_expression | token_expression @ rate

Token expressions follow the grammar in Table 2.6.

Table 2.6: Token expressions.
 token_expression ::= algebraic_expression token_name | token_expression , token_expression token_name ::= Id

Using Kappa hybrid rules, one may declare that an action has eﬀects on the concentration of some particles of the system. For instance, a rule may consume atp, calcium ions, etc. It would be a waste of memory and time to use discrete agents to represent such particles. Instead one may declare tokens using declarations of the form:

1%token: atp
• lhs | a${}_{1}$ t${}_{1}$, ..., a${}_{n}$ t${}_{n}$ $\to$ rhs | a${}_{1}^{\prime }$ t${}_{1}^{\prime }$, ..., a${}_{k}^{\prime }$ t${}_{k}^{\prime }$ @ r
where each ${a}_{i},{a}_{i}^{\prime }$ is an arbitrary algebraic expression (e.g. see Table 2.2) and each ${t}_{i},{t}_{i}^{\prime }$ is a declared token. In the above hybrid rule, denoting by ${n}_{i},{n}_{i}^{\prime }$ the respective evaluation of ${a}_{i}$ and ${a}_{i}^{\prime }$, the concentration of token ${t}_{i}$ will decrease from ${n}_{i}$ and the concentration of token ${t}_{i}^{\prime }$ will increase from ${n}_{i}^{\prime }$.