forio Toggle navigation

Model Creation in SimLang

To create your model in SimLang, see:

If you already have a model in SimLang because of your work with Simulate, see:

Once you have a model in SimLang, you can use it with the Epicenter platform by:

After your model is uploaded, you'll want to:

Creating and Uploading your Model Code

Use the Epicenter user interface to upload your model code (.eqn file) to the Model folder within your project.

SimLang was originally developed for use with the previous version of the Forio platform, Simulate. You can bring your Simulate model code into Epicenter, but you'll need to recreate the user interface for your simulation. See more about migrating your model from Simulate to Epicenter and creating an interface for your project.

Referencing Variables from the UI

You can reference any SimLang decision or variable from your project's user interface. For example, in Flow.js, add the decision or variable to an element on the page, for example using data-f-bind. (Read more about the options for creating your interface.)

SimLang decisions and variable names are not case-sensitive in Epicenter.

Only decisions (D) can be updated (patched). Only decisions in the current step can be updated. Both decisions (D) and variables (V) can be read. The value of the variable during any step (including the current step) can be retrieved. (See more on decisions and variables in SimLang.)

Scalars

To update or reference a scalar decision or variable, simply use the name. Optionally, include the step in square brackets, [s]. Only decisions in the current step can be updated. The value of the variable during any step (including the current step) can be retrieved.

SimLang models are typically time-based: they deal in discrete steps, and the model advances over time. For this reason, each variable is actually an array of values over steps.

For example, if you have the decision Sales it may initially be defined as:

D Sales = 100

Now suppose the end user changes it over time:

SalesStep
1000
1201
1302

If you are using Flow.js, by default the value at the current step is selected. You can also specify a particular step. This looks like:

<!-- update Sales for current step -->
<input data-f-bind="Sales"></input>

<!-- Sales for step 1: returns "120". can reference, but not update -->
<span data-f-bind="Sales[1]"></span>

You can also list values of an array — in this case, your scalar variable arrayed over all steps — using the data-f-foreach attribute. For example, if your model is currently in step 2, using:

<ul data-f-foreach="Sales">
    <li></li>
</ul>

creates

<ul data-f-foreach="Sales">
    <li>100</li>
    <li>120</li>
    <li>130</li>
</ul>

which displays

* 100
* 120
* 130

If you are using the Run API, you can also update Sales for the current step, or get Sales for a particular step. This looks like:

// update sales for the current step
curl -X PATCH \
    'https://api.forio.com/run/acme-simulations/sample-simlang-model/a1f03a72-0cd2-4c84-bad5-e97e875d65b2/variables' \
    --header 'Content-Type:application/json' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
    --data '{"sales": 250}'

// retrieve sales for step 1: returns "120"
curl -G \
    'https://api.forio.com/run/acme-simulations/sample-simlang-model/a1f03a72-0cd2-4c84-bad5-e97e875d65b2/variables/sales[1]' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'

Using the Run API, you can also ask for the variable over all steps. For example:

curl -G \
    'https://api.forio.com/run/acme-simulations/sample-simlang-model/a1f03a72-0cd2-4c84-bad5-e97e875d65b2/variables?include=sales' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'

returns:

{
    "Sales": [
        100,
        120,
        130
    ]
}

One-Dimensional Arrays

To update (patch) or reference an element of an array, use numeric indices with [n]. Optionally, include the step as the second subscript: [n, s]. Only decisions in the current step can be updated. The value of the variable from any step (including the current step) can be retrieved.

For example, suppose you have the arrayed decision Price. It is defined initially as

D Price[3] = {100, 150, 175}

and to reference the second element (in the current step), you use

Price[2]

If you are using Flow.js, this looks like:

<!-- retrieve the 2nd element of the array, in the current step.
     returns "150"  -->
<span data-f-bind="Price[2]"></span>

<!-- update the 2nd element of the array, in the current step. -->
<input data-f-bind="Price[2]"></input>

Note that by default the Flow.js data-f-bind attribute returns the final element of an array. You can use the data-f-foreach attribute to loop over all elements if needed. See details.

<!-- displays final element of the array, in the current step: 175 -->
<span data-f-bind="Price"></span>

<!-- displays list with three items: 100, 150, and 175 -->
<ul data-f-foreach="Price">
    <li></li>
</ul>

If you are using the Run API, this looks like:

// returns the 2nd element of the price array, in the current step: 150
curl -G \
    'https://api.forio.com/run/acme-simulations/sample-simlang-model/a1f03a72-0cd2-4c84-bad5-e97e875d65b2/variables/price[2]' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'

// updates the 2nd element of the price array, in the current step
curl -X PATCH \
    'https://api.forio.com/run/acme-simulations/sample-simlang-model/a1f03a72-0cd2-4c84-bad5-e97e875d65b2/variables' \
    --header 'Content-Type:application/json' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
    --data '{"price[2]": 167}'

Now suppose that as your model advances, the end user changes your Price decision over time:

PriceStep
{100, 150, 175}0
{200, 250, 275}1
{300, 350, 375}2

You can still use Flow.js or the Run API to reference a particular element of the array; by default, you'll retreive the array from the current step.

If you want a particular value from the a previous step, include the step as the second subscript:

<!-- returns 2nd array element from step 1: "250" -->
<span data-f-value="Price[2,1]"/>

And if you want the entire array over all time, request it without any subscripts:

curl -G \
        'https://api.forio.com/run/acme-simulations/sample-simlang-model/a1f03a72-0cd2-4c84-bad5-e97e875d65b2/variables?include=price' \
        --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'

returns each element of Price as an array over time.

{
    "price": [
        [
            100, // Price[1] at step 0
            200, // Price[1] at step 1
            300  // Price[1] at step 2
        ],
        [
            150, // Price[2] at step 0
            250, // etc.
            350
        ],
        [
            175,
            275,
            375
        ]
    ]
}    

Enumerated Ranges in Arrays

You can use the same format when working with arrays that you have declared using enumerated ranges, using [n] to describe the index of the array. Optionally, include the step as the second subscript: [n, s]. Only decisions in the current step can be updated. The value of the variable from any step (including the current step) can be retrieved.

For example, if you have

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

you use

Cost[Books]

to get the value from this decision array at the current step.

If you are using Flow.js, this looks like:

<!-- display or update value from current step -->
<span data-f-bind="Cost[Books]"></span>
<input data-f-bind="Cost[Books]"></input>

By default, Flow.js returns the value from the current step. Include the step as a second index if you want to show the value from a previous step:

<!-- displays value from step 0 -->
<span data-f-value="Cost[Books, 0]"></span>

If you are using the Run API, you'll need to include the step for retrieving (GET). The update (PATCH) assumes the current time step:

curl -G \
    'https://api.forio.com/run/acme-simulations/sample-simlang-model/a1f03a72-0cd2-4c84-bad5-e97e875d65b2/variables/cost[books,0]' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'

curl -X PATCH \
    'https://api.forio.com/run/acme-simulations/sample-simlang-model/a1f03a72-0cd2-4c84-bad5-e97e875d65b2/variables' \
    --header 'Content-Type:application/json' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
    --data '{"cost[books]": 45}'

If you do not include the step during a GET request, you see all values over time. For example, if the end user has updated the cost of books over several steps,

curl -G \
    'https://api.forio.com/run/acme-simulations/sample-simlang-model/a1f03a72-0cd2-4c84-bad5-e97e875d65b2/variables/cost[books]' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'

might return:

[100, 240, 357, 239]

Finally, if you do not include a subscript at all, you see the entire enumerated array, returned as a JSON object. For example, after two steps only,

curl -G \
    'https://api.forio.com/run/acme-simulations/sample-simlang-model/a1f03a72-0cd2-4c84-bad5-e97e875d65b2/variables?include=Cost' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'

might return:

{
    "Cost": {
        "Books": [
            100,
            240
        ],
        "Games": [
            175,
            189
        ],
        "CDs": [
            150,
            153
        ]
    }
}

Multidimensional Arrays

To update (patch) or reference a single element of a multidimensional array, use numeric indices, e.g. [n,m]. As always, optionally include the step as the final subscript: [n,m,s]. Only decisions in the current step can be updated. The value of the variable from any step (including the current step) can be retrieved.

For example, to reference the first item of the second element in

D SalesByRegion[5,2] = { 
    {100, 200}, 
    {300, 400}, 
    {500, 600}, 
    {700, 800}, 
    {900, 1000} 
}

If you are using Flow.js and working with the current step, this looks like:

<!-- working with 2nd array element, 1st item: 300 -->
<span data-f-bind="SalesByRegion[2,1]"></span>
<input data-f-bind="SalesByRegion[2,1]"></input>

Note that by default the Flow.js data-f-bind attribute returns the final element of an array. You can use the data-f-foreach attribute to loop over all elements if needed. See details.

<!-- displays 2nd array element, final item: 400 -->
<span data-f-bind="SalesByRegion[2]"></span>

<!-- displays list with all items in 2nd array element: 300, 400 -->
<ul data-f-foreach="SalesByRegion[2]">
    <li></li>
</ul>

If you are using the Run API to retrieve the SalesByRegion for a particular step, this looks like:

// retrieve the 2nd array element, 1st item, from step 0: 300 
curl -G \
    'https://api.forio.com/run/acme-simulations/sample-simlang-model/a1f03a72-0cd2-4c84-bad5-e97e875d65b2/variables/SalesByRegion[2,1,0]' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'

You can also read all dimensions or particular dimensions of multidimensional arrays. Once your model has advanced (stepped), each innermost element is itself an array over time:

curl -G \
    'https://api.forio.com/run/acme-simulations/sample-simlang-model/a1f03a72-0cd2-4c84-bad5-e97e875d65b2/variables/SalesByRegion[2]' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'

returns

[ [300], [400] ]

if your model is still in step 0, but

[ [300, 301, 302], [400, 401, 402] ]

for example, if your model has advanced through steps 0, 1 and 2.

Similarly, after three steps

curl -G \
    'https://api.forio.com/run/acme-simulations/sample-simlang-model/a1f03a72-0cd2-4c84-bad5-e97e875d65b2/variables/SalesByRegion' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'

might return

[ 
    [
        [100, 101, 102], //1st region, 1st item sales over steps 0, 1, 2
        [200, 201, 202]  //1st region, 2nd item sales over steps 0, 1, 2
    ], 
    [
        [300, 301, 302], //2nd region, 1st item sales over steps 0, 1, 2
        [400, 401, 402]  //2nd region, 2nd item sales etc.
    ],
    [[500, 501, 502],[600, 601, 602]],
    [[700, 701, 702],[800, 801, 802]],
    [[900, 901, 902],[1000, 1001, 1002]]
]

Calling operations from the UI

You can call any operation (function) from your project's user interface as well. For example, in Flow.js, add the operation to an element on the page, or call it when the run is created. (Read more about the options for creating your interface.)

The operations available from your project's user interface are listed in the SimLang Language Overview and include step, stepTo, getTimeDetails, and reset. (Specific SimLang functions that you use in the definition of your decisions and variables cannot be called from your project's user interface; you can only reference the decisions or variables.)