See also the Heta tutorial
The Heta code represents a sequence of statements that create and modify elements in a modeling platform. The parsing and interpretation of the code result in the creation of a static (database-like) structure representing the modeling platform, see compilation. There are many ways to write the same modeling system using Heta code, and a developer has the freedom to make their code more organized and readable.
-
Action statements are separated by semicolons, and line breaks within and between statements do not affect interpretation; they can be used for code formatting.
<statement one>; <statement two>; <statement three>; ...
-
An action statement consists of a dictionary part and a set of shortened properties. The parts follow a priority rule, where the subsequent part has a higher priority. The list of part types includes:
- Dictionary
- Index
- Class
- Action
- Title
- Notes
- Assignments (with several subtypes)
-
The plain format is the most straightforward way to describe action properties. It begins with the
{
symbol and ends with the}
symbol, and it can contain a set of key-value pairs divided by commas (,
), similar to a dictionary in JSON or YAML format.Example:
{ prop1: value 1, prop2: value 2, ...};
The property name is always a string without spaces, it must be unique within a dictionary. The value can be one of five types: <String>, <Number>, <Boolean>, <Dictionary>, <Array> or <Null>. <Dictionary> and <Array> values might include other types.
Example:
{ stringProp: some text, numberProp: 1.2e-3, booleanProp: true, dictionaryProp: { nestedProp: true }, arrayProp: [1, 2, 3], someProp: null };
-
String values inside dictionaries start from the first non-space symbol and end with the non-space symbol before the stop-list:
, } ] @ # '
. If you want to use symbols from the stop list inside a <String> value, use parentheses.Example:
{ prop1: Some string, prop2: "String with # stop-symbols @" };
-
There are special string formats used to describe specific properties of actions or classes. They follow the same <String> syntax but also have specific rules.
Example:
{ id: r1, // follows the ID format class: Reaction, actors: A => B // follows the ProcessExpr format };
-
The <Number> value inside a dictionary is in <Double> format.
Example:
{ prop1: 1, prop2: 1.2, prop3: 1.1e-2, prop4: 1.2E+3 };
-
The <Boolean> value inside a dictionary may have two values:
true
orfalse
.Example:
{ prop1: true, // this is Boolean prop2: false, stringProp: "true" // this is String };
-
Nested <Dictionary> values follow the same rules as the plain format of an action statement and can be nested.
Example:
{ prop: { nestedProp: { nextLevel: Hello! } } };
-
The <Array> value is a sequence of numbered elements divided by commas. Numeration starts from 0 (zero) index.
Example:
{ prop1: [], prop2: [1, 2, 3], prop3: [string, "string"], prop4: [[1, 2, 3], []], prop5: [{a: 1, b: 2, c: 3}, {}] };
-
The <Null> value is used to describe the value which must be empty. See more detailes in Null values
-
To simplify code reading and writing, there are several types of statement parts that describe commonly used properties in a compact form. See the Classes description for details.
-
Index describes identifiers, such as
id
andspace
for components. The examples if indexes are:space::id
or justid
for nameless space.Example:
one::k1 { prop1: some text };
Which is equivalent to
{ space: one, id: k1, prop1: some text };
The specific form of index is "star index" which is helpful for some actions. This can be used when you do not want to state id.
Example:
#importNS target_ns::* { fromSpace: source_ns };
which is equivalent to the following
#importNS {space: target_ns, fromSpace: source_ns };
-
Class sets the
class
property. A particular class defines a list of properties that can be set. This property is denoted by the "@" symbol. The list of possible classes can be found in Classes description. Classes' names always start from the uppercase symbol. When you use class shortened property@
the parser will replace the first lowercase symbol for the capital one.Example:
k2 @const { num: 1.3 };
Equivalent to:
{ id: k2, class: Const, num: 1.3 };
-
Action sets the
action
property. Theaction
describes what to do with the statement, see Actions. This property is denoted by the#
symbol and is a required property in the base statement. Its default value isupsert
.Example:
#insert k3 @Const; k3 { num: 1 };
Equivalent to:
{ action: insert, id: k3, class: Const }; { action: upsert, id: k3, num: 1 };
-
Title sets the
title
property, denoted by single quotes'
.Example:
a 'Some title';
which is equivalent to
{ id: a, title: Some title };
-
Notes sets the
notes
property, designated by three single quotes'''
. Thenotes
part is usually located before other parts.Example:
''' Some notes ''' a @Const;
which is equivalent to the following plain version
{ notes: Some notes, id: a, class: Const };
-
Const Assignment set the
num
property and is designed only for the@Const
class. The=
symbol is used to mark an assignment.Example:
k1 @Const = 1.1;
Equivalent to:
{ id: k1, class: Const, num: 1.1 };
-
Start Assignment sets the initial assignment for the
@Record
instances. The symbols.=
or[]=
can be used. (Do not put spaces between the symbols.)Example:
s @Record .= 10; p @Species []= 0;
Equivalent to:
{ id: s, class: Record, assignments: { start_: 10 } }; { id: p, class: Species, assignments: { start_: 0 } };
-
Rule Assignment sets the
ode_
assignment for@Record
instances. The:=
symbol can be used.Example:
rule1 @Record := x*y;
Equivalent to:
{ id: rule1, class: Record, assignments: { ode_: x*y } };
-
Switcher Assignment sets the re-assignment of records managed by a Switcher. The symbol
[<switcher id>]=
can be used.Example:
s [dose_switch_1]= 0.1;
Which is equivalent to
{ id: s, assignments: { dose_switch_1: 0.1 } };
-
The
include
statement is used to describe module loading, where the file content is included (while compilation) into the current one. -
The
include
statement can be replaced by the#include
action with equivalent meaning. -
The statement consists of the reserved word
include
followed by a relative or absolute file path. The full form of the statement can be presented as follows:include <filepath> type <module type> with {...};
Where
<module type>
is one of the supported modules, and{...}
is a dictionary to set additional options. For more details on modules, refer to the modules page. -
The
include
statement can set additional parameters after thewith
keyword in dictionary format. -
The statement must be finalized with semicolon
;
.
Example 1:
include ./addon.heta type heta;
Example 2:
include file.xlsx type table with {
sheet: 2,
omitRows: 3
};
-
Platform components are grouped in namespaces, and the
namespace
statement can be used to work with namespaces more easily. For details about namespaces, refer to the namespaces page. -
The first use of a namespace block with a new space name initializes the
namespace
(in the same manner as the#setNS
action). -
To clarify the type of the namespace, one of the reserved words
abstract
orconcrete
should be used. The default type isconcrete
. -
The statement must be finalized with semicolon
;
or must includebegin/end
block part. -
The block is organized as follows:
namespace <space id> begin <action statement>; ... end
Example:
namespace one begin rec @Record .= 1; comp @Compartment .= 10; end
Equivalent to:
#setNS { space: one, type: concrete }; one::rec @Record .= 1; one::comp @Compartment .= 10;
or equivalent to the plain format:
{ space: one, type: concrete, action: setNS }; { space: one, id: rec, class: Record, assignments: { start_: 1} }; { space: one, id: comp, class: Compartment, assignments: { start_: 10} };
-
Comments are parts of the code that are not compiled and are used solely for annotating the code.
-
A single-line comment starts with
//
symbols and ends with line breaks.Example:
// this is not part of the platform but only a comment to the code
-
A multiline comment starts with
/*
and ends with*/
or at the end of the file.Example:
/* Compiler will not parse this part. */
Special string formats are additional rules for specific properties of actions and classes.
The ID format is used for indexing Heta components, creating identifiers for components and namespaces, and referencing elements. The following properties must follow the ID format:
id
,space
for all actions- Properties that describe references to elements like
compartment
in theSpecies
class,fromSpace
in theimportNS
action, etc. - References used inside
MathExpr
,UnitsExpr
,ProcessExpr
. The base rules for an ID are as follows:
- The first symbol should be a letter or underscore.
- The second and following elements should be letters, numbers, or underscores.
- The last symbol should not be an underscore.
Additionally, some words cannot be used as identifiers because they are reserved for statements or specific object names, such as
NaN
,Infinity
,e
,pi
,include
,block
,namespace
,abstract
,concrete
,begin
,end
Example
Correct: x
, x12
, x_12
, _12
, x___12
, _begin
Incorrect: 12x
, x-12
, x 9
Incorrect usage of reserved words as an ID: begin
, block
Incorrect underscore position: _
, x12_
A string representing a relative or absolute file path.
The following properties must follow the Filepath format:
source
property in theinclude
statement
Examples:
Correct Filepath: output
, ./output
, ../output
, Y:/my-platform/src/module1/model.heta
UnitsExpr strings represent complex units combined from predefined unit IDs. Available operators are *
, /
, ^
, and 1/
.
The following properties must follow the UnitsExpr format:
unit
property in@Const
and@Record
classesunit
property in#defineUnit
action
See more details see units page.
Example:
Correct UnitsExpr: mg
, g/mole
, 1/h
, kg/m2
, kg/m^2
Incorrect UnitsExpr: g/(mole*L)
, 5*g
, km + kg
MathExpr describes mathematical expressions in string format.
Available operators are +
, -
, *
, /
, and ^
. See details in Math expressions
The following properties must follow the MathExpr
format:
assignments
sub-properties in theRecord
classtrigger
property inDSwitcher
andCSwitcher
classes Example:
Correct MathExpr: x*y*pow(x,y)
A ProcessExpr
formatted string represents process stoichiometry.
The "arrow" syntax (->
, <->
, =>
, <=>
, >
, <>
) divides two parts into influx (left) and outflux (right).
The +
symbol divides two or more actors, and stoichiometry coefficients are shown by numbers before the reference. The asterisk symbol is optional.
The following properties must follow the ProcessExpr
format:
actors
property in theProcess
class
Example
Correct ProcessExpr:
A->B
A =>
2A <=> 3*B + C
2 A <=> 3 * B + C
2A > 3R + C