sitemap.xml llms.txt
Skip to main content

SimLang Language

SimLang is a system dynamics-inspired modeling language created by Forio.

SimLang is designed for time-based models. Therefore, a project with a SimLang model has access to several operations that advance the model through time (e.g., step). Each step recalculates the model state.

A SimLang model is written as an equations file (*.eqn) that describes external conditions, user decisions, and the relationships between them. The EQN file can contain three types of elements in any order: decisions, variables, and properties. Each element is identified by a single-letter prefix.

Decision and variable definitions can include function calls, operators, loops, and conditionals.

Note

In a SimLang model, you do not define your own functions. All functions used in the definition of a decision or variable are built into the language.

Learn more

For a reference on the built-in functions, read SimLang Functions.

Decisions and variables

Decisions

A decision is a model element subject to end-user control. It is prefixed with D. Its equation sets the default value, calculated at the start of the simulation. After that, it takes its value from user input — unless the recalculate operation is called to reset it to its equation.

D Initial Savings = 5000
D Interest Rate = 10%
D Yearly Deposits = 1000

In your Epicenter application, decisions are typically bound to inputs such as sliders, text fields, or radio groups.

Variables

A variable is a model element prefixed with V. Its equation is automatically recalculated at every time step. A variable can also accept user input, but once set by the user it will not recalculate at each step until recalculate is explicitly called.

V Interest = Previous Year Savings * Interest Rate
V Total Savings = Previous Year Savings + Interest + Yearly Deposits

In your Epicenter application, variables are typically displayed using output elements such as line charts, results tables, or inline text.

Naming convention

The names of both decisions and variables must start with a letter. They can contain uppercase letters, lowercase letters, spaces, and numbers. Often, SimLang models follow the traditional system-dynamics convention of using multi-word variable names with spaces.

Scalers

Many decisions and variables are scalars, that is, single values. Scalar decisions and variables can be strings, boolean values, any kind of number (integers, floating-point), or mathematical formulas or equations.

Arrays

Arrays are sets of values that use the same equations. Both decisions and variables can be arrays.

To define a variable or decision as an array, you must specify both an equation and a range. To define a range, prefix if with an R.

For example, a sales model might have the variables Sales and Revenue, and the decision Price, each of which is split among Books, CDs, and Games. To define these, use an enumerated range.

Enumerated ranges

Enumerated ranges define meaningful labels for array dimensions:

R Products = Books, CDs, Games
D Price[Products] = {100, 150, 175}

Numeric ranges

Numeric ranges use a count or start..end notation (1-based):

D Price[3] = {100, 150, 175}
V Sales[1..3] = {100, 200, 150}

Multidimensional arrays

Multidimensional arrays use a comma in the range:

V MySales[5, 2] = {{100, 200}, {100, 200}, {100, 200}, {100, 200}, {100, 200}}

Default values

Default values simplify large array initialization:

# Define an array with 1st element 100, 2nd element 200, and all other elements 1000.
V MySales[10] = {100, 200, Default: 1000}

# Define an array with 5th element 100, 2nd element 200, and all other elements 1000.
V MySales[10] = {5: 100, 2: 200, Default: 1000}

# Define an array and set Pencils to 100, all other elements to 200.
R Products = Pencils, Markers, Crayons
V Sales[Products] = {Pencils: 100, Default: 200}

# Define an array and set the first five elements to 1000, and all other elements to 6000.
V MySales[10] = {1..5: 1000, Default: 6000}

Using expressions

Any array definition can include an expression:

V Other Sales[1..2] = {New Sales, New Sales + Repeat Sales}

You can also use a FOREACH loop to apply an expression to each array element:

# These two definitions are equivalent
V NewSales[10] = FOREACH(item, 10, item * 10)
V NewSales[10] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100}

Referencing arrays

You can define an array using another array of the same dimensions in an equation. For example:

R Products = Books, CDs, Games
D Price[Products] = {100, 150, 175}
V Sales[Products] = {100, 200, 150}
V Revenue[Products] = Sales * Price

Equations can also refer to individual elements of an array, either by numeric index or by enumerated index:

V MyBookProfit = Revenue[Books] - Cost[Books]
V Demand = NewSales[1]

You can also reference sub-dimensions:

V X[5, 2] = {{100, 200}, {100, 200}, {100, 200}, {100, 200}, {100, 200}}

# Y is a one-dimensional array of two elements
V Y[2] = X[1, *]

# Z is a two-dimensional array, but with three rows instead of five
V Z[3, 2] = X[1..3, *]

Array definitions can refer to themselves in equations, as long as they do not cause a circular reference error:

V Fib[1..5] = {1, 1, Fib[1] + Fib[2], Fib[2] + Fib[3], Fib[3] + Fib[4]}

Combining arrays

To combine arrays with different dimensions:

Often, you may want to combine arrays of different ranges. The way to do this is with a FOREACH statement.

R Products = Books, CDs, Games
R Market Segments = 1..2

V Market Size[Market Segments] = {1000, 2000}
V Market Share[Products, Market Segments] =
{{20%, 30%}, {22%, 33%}, {44%, 46%}}

V Our Market[Products, Market Segments] =
FOREACH(p, Products,
FOREACH(m, Market Segments,
Market Share[p, m] * Market Size[m]
)
)

The equation for Our Market is arrayed over Products and Market Segments. The two FOREACH statements construct that array, applying the given expression to each new array item. This can be expressed in English as "For each product p and each market segment m in the result, the equation is Market Share[p, m] multiplied by Market Size[m]".

Properties

Properties configure overall model behavior. Model-level properties are prefixed with M and can appear anywhere in the EQN file. Variable-level properties are prefixed with P and must appear after the variable they configure.

M StartTime = 2010
M EndTime = 2020
M TimeStep = 1

D Price = 100
P Price.ExecuteDecisionImmediately = false

The following properties are supported in SimLang on Epicenter:

PropertyScopeDefaultDescription
StartTimeModel0Starting time of the simulation
EndTimeModel10Final time of the simulation
TimeStepModel1Time units advanced per step() call
InitialStepsModel0Steps to auto-advance on initialization
ExecuteDecisionImmediatelyModel or DecisiontrueIf true, a new decision value immediately affects variables
ResetDecisionModel or DecisionfalseIf true, decisions reset to their equation value after each step

Control flow

Models written in SimLang don't have control flow in the same sense as, say, a Julia or Python program does. However, within a variable or decision equation, you can use control flow in the form of conditionals and loops.

IF

Chooses a value conditionally:

V Profitable = IF(Profit > 0, true, false)

FOREACH

Loops over a range to build an array:

V NewSales[10] = FOREACH(item, 10, item * 10)