Skip to content

Reusing charts

Using one chart inside another with state S is Other(...), wiring up its inputs and outputs, and keeping several charts in one file or in imported files.

A building has dozens of light switches, and every one of them works the same way. You would not want to draw the same two states and two transitions for each lamp. SCCharts lets you write the switch once, as a chart of its own, and use it wherever you need a switch. Each use is a reference: a state that says “I behave like that chart, wired to these variables”.

PushSwitch is an ordinary chart: one press switches its lamp on, the next switches it off. LampPanel uses it twice, once for each lamp, in two concurrent regions:

LampPanelSimulation

Diagram

Diagram of LampPanelStates: Left (initial, superstate), Left/PushSwitch (superstate), Off (initial), On, Right (initial, superstate), Right/PushSwitch (superstate), Off (initial), On. Transitions: Off to On: press / lit = true; On to Off: press / lit = false; Off to On: press / lit = true; On to Off: press / lit = false.LampPanelinput boolleft, rightoutput boolleftLamp = false, rightLamp = falseLeft@PushSwitch (left, leftLamp)PushSwitchinput boolpressoutput boollit = falseOffOnpress/ lit = truepress/ lit = falseRight@PushSwitch (right, rightLamp)PushSwitchinput boolpressoutput boollit = falseOffOnpress/ lit = truepress/ lit = false

Code

scchart LampPanel {
input bool left, right
output bool leftLamp = false, rightLamp = false
region {
initial state Left is PushSwitch(left to press, leftLamp to lit)
}
region {
initial state Right is PushSwitch(right to press, rightLamp to lit)
}
}
scchart PushSwitch {
input bool press
output bool lit = false
initial state Off
if press do lit = true go to On
state On
if press do lit = false go to Off
}
Tick 0 of 5
Inputs for tick 1 Boolean input: true while on. It keeps its value until you change it. Boolean input: true while on. It keeps its value until you change it.
Timing diagram of LampPanel
Tickinput bool leftinput bool rightoutput bool leftLampoutput bool rightLampActive state of region 1 of the chartActive state of region 2 of the chart
Click a tick to show it, or use the Left and Right arrow keys to go back and step.
Guided tour, 5 ticks Press Next to run tick 1, or Take over to set the inputs yourself.

Guided tour, 5 ticks:

  1. left = false, right = falseTick 1 enters Left and Right. Each is a fresh copy of PushSwitch, starting in its own Off.
  2. left = trueleft is wired to the first copy’s press, and leftLamp to its lit: the left lamp comes on. The right copy is unaffected.
  3. left = false, right = trueThe right copy switches on rightLamp. The two copies run side by side, each in its own region.
  4. right = false, left = trueThe left copy is in its On state and switches off. The right copy stays On.
  5. left = falseLeft off, right on.
left and right each drive their own copy of PushSwitch, drawn inside Left and Right: pressing one never affects the other lamp.

The line that does the work is

initial state Left is PushSwitch(left to press, leftLamp to lit)

state Left is PushSwitch(...) makes Left a referencing state: it behaves exactly like the chart PushSwitch. The list in brackets is the binding, the wiring between the two charts. left to press means “my left is your press”, and leftLamp to lit means “my leftLamp is your lit”. Every input and output of the referenced chart must be wired to something; bindings below shows the ways to do it.

In the diagram, a referencing state shows the name of the chart it uses after an @ sign, followed by the actuals it is bound to. KIELER draws it collapsed, as a box that you can expand to see the chart inside. The simulations on this page show the copies expanded, so that you can watch their states.

KIELER treats a reference like a macro. Before compiling, it replaces Left with a copy of PushSwitch’s inside: its regions, its states and transitions, its local declarations and its own entry, during and exit actions. The copy keeps the name Left, its initial or final flag, and its incoming and outgoing transitions. Everywhere in the copy, press is replaced by left and lit by leftLamp.

So a referencing state is simply a superstate that you did not have to write out, and everything you know about superstates applies to it: it can be left by a weak or strong abort, it can be suspended, and it can be the target of a history transition. A few consequences are worth spelling out:

  • Every reference is a separate copy. Left and Right each have their own Off and On. If the referenced chart has local variables, each copy has its own set. (A variable declared global in the referenced chart is the exception: all copies share it.)
  • The referenced chart’s own actions become the referencing state’s. An entry do ... written at the top of PushSwitch would run every time Left is entered; its exit actions every time Left is left.
  • Aborts see the copy’s writes like any inner behaviour. A weak abort if leftLamp go to ... on Left sees what the copy wrote in that tick and fires at once; a strong abort abort to reads the value from before the copy ran, so it fires a tick later.

Two copies of one counter show the first point. Tally counts clicks with a self-loop; DoorCounters uses it for the front door and for the back door:

DoorCountersSimulation

Diagram

Diagram of DoorCountersStates: Front (initial, superstate), Front/Tally (superstate), Counting (initial), Back (initial, superstate), Back/Tally (superstate), Counting (initial). Transitions: Counting to Counting: click / count++; Counting to Counting: click / count++.DoorCountersinput boolfront, backoutput intfrontCount = 0, backCount = 0Front@Tally (front, frontCount)Tallyinput boolclickoutput intcount = 0Countingclick/ count++Back@Tally (back, backCount)Tallyinput boolclickoutput intcount = 0Countingclick/ count++

Code

scchart DoorCounters {
input bool front, back
output int frontCount = 0, backCount = 0
region {
initial state Front is Tally(front to click, frontCount to count)
}
region {
initial state Back is Tally(back to click, backCount to count)
}
}
scchart Tally {
input bool click
output int count = 0
initial state Counting
if click do count++ go to Counting
}
Tick 0 of 6
Inputs for tick 1 Boolean input: true while on. It keeps its value until you change it. Boolean input: true while on. It keeps its value until you change it.
Timing diagram of DoorCounters
Tickinput bool frontinput bool backoutput int frontCountoutput int backCountActive state of region 1 of the chartActive state of region 2 of the chart
Click a tick to show it, or use the Left and Right arrow keys to go back and step.
Guided tour, 6 ticks Press Next to run tick 1, or Take over to set the inputs yourself.

Guided tour, 6 ticks:

  1. front = false, back = falseTick 1 enters Front and Back, two copies of Tally, each in its own Counting state.
  2. front = trueSomeone comes in at the front: the self-loop of Front’s copy fires and adds one to frontCount. Back’s copy does nothing.
  3. front is still true (inputs keep their value), so Front’s copy counts again: 2.
  4. front = false, back = trueNow the back door: only Back’s copy counts.
  5. front = trueBoth doors at once: both copies take their self-loop in the same tick, each adding one to its own output.
  6. front = false, back = falseNobody: 3 at the front, 2 at the back. Each copy has counted only its own door.
Each door has its own copy of Tally, drawn inside Front and Back. In tick 5 both doors click, and both copies count, each into its own output.

The two copies share nothing but their source: Front’s Counting state and self-loop are not Back’s, and count is frontCount in one copy and backCount in the other.

A file may contain any number of scchart definitions, in any order: a reference may name a chart that is defined further down. But only one chart in a file is simulated, and it is the first one. The others are only there to be referenced.

Here is the lamp panel again, with the two charts the other way round:

PushSwitchFirstSimulation

Diagram

Diagram of PushSwitchFirstStates: Off (initial), On. Transitions: Off to On: press / lit = true; On to Off: press / lit = false.PushSwitchFirstinput boolpressoutput boollit = falseOffOnpress/ lit = truepress/ lit = false

Code

scchart PushSwitchFirst {
input bool press
output bool lit = false
initial state Off
if press do lit = true go to On
state On
if press do lit = false go to Off
}
scchart PanelSecond {
input bool left, right
output bool leftLamp = false, rightLamp = false
region {
initial state Left is PushSwitchFirst(left to press, leftLamp to lit)
}
region {
initial state Right is PushSwitchFirst(right to press, rightLamp to lit)
}
}
Tick 0 of 3
Inputs for tick 1 Boolean input: true while on. It keeps its value until you change it.
Timing diagram of PushSwitchFirst
Tickinput bool pressoutput bool litActive state of the chart
Click a tick to show it, or use the Left and Right arrow keys to go back and step.
Guided tour, 3 ticks Press Next to run tick 1, or Take over to set the inputs yourself.

Guided tour, 3 ticks:

  1. press = falsePushSwitchFirst comes first in the file, so it is the chart that is simulated: its interface is press and lit. PanelSecond, with its left and right, never runs.
  2. press = truepress toggles lit, exactly as if the file held only PushSwitchFirst.
  3. press = falseIn On.
With the switch first in the file, the switch is what runs: the interface is press and lit, and the panel never starts.

The panel, PanelSecond, is not broken. It is simply not the chart that runs. Put the chart you want to run at the top of the file and the charts it uses below it. SCCharts Lab’s Simulate command and this site’s simulator both follow KIELER here.

Two more rules apply to files with several charts:

  • The whole file is checked. A misspelt variable in a chart that nothing uses still rejects the file, with the usual Couldn't resolve reference to ValuedObject 'q'. Problems that only the scheduler finds, such as a causality cycle, are found only in the simulated chart and the charts it references.

  • Give every chart its own name. With two charts of the same name, KIELER warns

    There are multiple root states with the same name. 'Twin'

    and simulates the first; a reference to the name may pick either. This happens easily when you copy a chart within a file and forget to rename it.

To use a chart that lives in another file, import the file. Its charts can then be referenced by name. HallLights imports the file push-switch.sctx, shown below it, and uses its chart ImportedSwitch:

HallLightsSimulation

Diagram

Diagram of HallLightsStates: Hall (initial, superstate), Hall/ImportedSwitch (superstate), Off (initial), On. Transitions: Off to On: press / lit = true; On to Off: press / lit = false.HallLightsinput boolswitchAoutput boolhall = falseHall@ImportedSwitch (switchA, hall)ImportedSwitchinput boolpressoutput boollit = falseOffOnpress/ lit = truepress/ lit = false

Code

import "push-switch"
scchart HallLights {
input bool switchA
output bool hall = false
initial state Hall is ImportedSwitch(switchA to press, hall to lit)
}
Tick 0 of 3
Inputs for tick 1 Boolean input: true while on. It keeps its value until you change it.
Timing diagram of HallLights
Tickinput bool switchAoutput bool hallActive state of the chart
Click a tick to show it, or use the Left and Right arrow keys to go back and step.
Guided tour, 3 ticks Press Next to run tick 1, or Take over to set the inputs yourself.

Guided tour, 3 ticks:

  1. switchA = falseimport "push-switch" loads push-switch.sctx from the same folder, so its chart ImportedSwitch can be referenced. This file’s first chart, HallLights, is the one simulated.
  2. switchA = trueThe imported switch turns hall on.
  3. switchA = falseOn.
Switch to Code: the first line, import "push-switch", makes the chart ImportedSwitch from the other file available.
push-switch.sctx
scchart ImportedSwitch {
input bool press
output bool lit = false
initial state Off
if press do lit = true go to On
state On
if press do lit = false go to Off
}
  • import "push-switch" loads push-switch.sctx from the folder of the importing file. The .sctx may be left out or written. A path relative to that folder works too, and import "lib/*" loads every .sctx file in the folder lib.
  • Imports come first in the file, before the first scchart.
  • Imported charts are only for referencing. The chart that runs is still the first chart of the file you simulate, here HallLights.
  • import names a file; is names a chart. The two names need not match, and a file may hold several charts.

Three mistakes, and what KIELER says about them:

  • No import. A chart in another file is invisible, even if it sits in the same folder:

    Couldn't resolve reference to NamedObject 'ImportedSwitch'.
  • A file that does not exist. KIELER only warns,

    Broken Import: There is no SCCharts model with the given name.

    and then reports the references it cannot resolve, as above.

  • The old pragma #import "beep", which older examples use. Current KIELER does not accept it (no viable alternative at input 'import'): write import.

The formals of a referenced chart are its inputs and outputs, in the order they are declared. A binding connects each formal to an actual: a variable or signal of the referencing chart, or for an input, a constant. There are three ways to write it.

actual to formal, as in left to press: “my left to your press”. Explicit bindings say exactly what is meant, they survive changes to the referenced chart, and they can be written in any order. Prefer them.

You may leave out the names: PushSwitch(left, leftLamp) binds left to the first formal and leftLamp to the second, in the order the formals are declared in PushSwitch. This is shorter, but it breaks silently as soon as someone reorders or adds declarations in the referenced chart, and KIELER does not check that the types match. The exercise at the end of this chapter shows how badly that can go.

You can mix the two styles, but the order bindings then follow a rule that few people guess. Here ThreeDigits has the formals a, b, c (inputs) and result (an output), and computes result = a * 100 + b * 10 + c. The reference is ThreeDigits(1 to b, 2, number, seven to a), where seven is a local with the value 7. (If you switch to the diagram, note that it lists only the actuals, not the formals they are bound to.) Predict number in tick 2, then open the explanation:

PointerPuzzlePrediction

Diagram

Diagram of PointerPuzzleStates: R (initial, superstate). Transitions: none.PointerPuzzleoutput intnumber = 0intseven = 7R@ThreeDigits (1, 2, number, seven)

Code

scchart PointerPuzzle {
output int number = 0
int seven = 7
initial state R is ThreeDigits(1 to b, 2, number, seven to a)
}
scchart ThreeDigits {
input int a, b, c
output int result
initial state Compute
do result = a * 100 + b * 10 + c go to Compute
}

1 to b comes first. Which formal does the 2 after it bind to?

Plays the scenario on the diagram, then marks each answer.
Explanation

number is 712. KIELER binds the arguments left to right with a pointer into the list of formals. An explicit binding x to f moves the pointer to f and then one past it; an order binding takes the formal at the pointer and moves on. So after 1 to b, the 2 binds to c, the formal declared after b, and number binds to result. Then seven to a binds a. If the pointer runs past the last formal, the binding is an error.

A formal that is not bound by any argument is bound by name to a variable or signal of the same name that is visible at the referencing state (declared in it, in a state around it, or in the chart). is ImplicitSwitch(), or just is ImplicitSwitch, binds every formal this way:

ImplicitPanelSimulation

Diagram

Diagram of ImplicitPanelStates: Switch (initial, superstate), Switch/ImplicitSwitch (superstate), Off (initial), On. Transitions: Off to On: press / lit = true; On to Off: press / lit = false.ImplicitPanelinput boolpressoutput boollit = falseSwitch@ImplicitSwitch ()ImplicitSwitchinput boolpressoutput boollit = falseOffOnpress/ lit = truepress/ lit = false

Code

scchart ImplicitPanel {
input bool press
output bool lit = false
initial state Switch is ImplicitSwitch()
}
scchart ImplicitSwitch {
input bool press
output bool lit = false
initial state Off
if press do lit = true go to On
state On
if press do lit = false go to Off
}
Tick 0 of 3
Inputs for tick 1 Boolean input: true while on. It keeps its value until you change it.
Timing diagram of ImplicitPanel
Tickinput bool pressoutput bool litActive state of the chart
Click a tick to show it, or use the Left and Right arrow keys to go back and step.
Guided tour, 3 ticks Press Next to run tick 1, or Take over to set the inputs yourself.

Guided tour, 3 ticks:

  1. press = falseImplicitSwitch() binds nothing explicitly, so press and lit are bound by name to the parent’s press and lit. The editor warns Valued Objects are bound implicitly!, followed by the names.
  2. press = trueThe implicitly bound press is the parent’s input: lit comes on.
  3. press = falseOn.
Warning: press, lit are bound by name
  • Warning, line 5, column 27KIELER says: Valued Objects are bound implicitly! press, lit, press, lit of ImplicitSwitch are connected to the variables of the same name here. Write them in the parameter list (press to press) to make it explicit.About this message
press and lit are wired to the parent’s press and lit because the names match. The editor warns about it.

The editor warns Valued Objects are bound implicitly!, followed on the next line by the names, each followed by a comma (here press, lit, ). Implicit binding saves typing when a big interface is passed straight through, but it is easy to bind something you did not mean to. If no variable of that name is visible, the binding is an error.

A variable or a signal, of course, and for an input also a literal such as true or 3: the input is then that constant inside the copy. Any other expression, such as a && b, cannot be bound: compute it into a variable of the referencing chart first and bind the variable.

Arrays, signals and types
Actual to an input to an output
a variable or signal yes yes
a whole array yes, to an array formal yes, to an array formal
one array element, a[1] yes, to a scalar formal yes, to a scalar formal
a literal, true or 3 yes: the input is that constant inside the copy no
any other expression, a && b no no

Signals bind to signals, valued signals included. Types are not checked: KIELER will happily bind a float to a bool input.

Inside the copy, the formal is your variable

Section titled “Inside the copy, the formal is your variable”

Binding is not copying values in and out. Inside the copy, the formal is replaced by the actual, so the copy works directly on your variables:

  • When the copy writes an output, the bound variable changes at that moment, and the regions next to the referencing state see the new value in the same tick, as with any write.
  • When the copy writes one of its inputs, it writes the variable you bound to it. A referenced chart that does level -= 1 on its input level changes your variable.
  • Bind one variable to two outputs and both writes go to that variable.

Initial values follow the same logic, with a result that surprises most people, so they get a section of their own.

Output initial values are applied on every entry

Section titled “Output initial values are applied on every entry”

In the chart below, remaining starts at 0, but the referenced Countdown declares its output as output int left = 3. KIELER turns that initial value into an entry action of the referencing state: the bound variable is set to 3 every time Timing is entered.

OvenTimerSimulation

Diagram

Diagram of OvenTimerStates: Idle (initial), Timing (superstate), Timing/Countdown (superstate), Counting (initial). Transitions: Counting to Counting: left > 0 / left--; Idle to Timing: start; Timing to Idle: stop.OvenTimerinput boolstart, stopoutput intremaining = 0IdleTiming@Countdown (remaining)Countdownoutput intleft = 3Countingleft > 0/ left--startstop

Code

scchart OvenTimer {
input bool start, stop
output int remaining = 0
initial state Idle
if start go to Timing
state Timing is Countdown(remaining to left)
if stop go to Idle
}
scchart Countdown {
output int left = 3
initial state Counting
if left > 0 do left-- go to Counting
}
Tick 0 of 9
Inputs for tick 1 Boolean input: true while on. It keeps its value until you change it. Boolean input: true while on. It keeps its value until you change it.
Timing diagram of OvenTimer
Tickinput bool startinput bool stopoutput int remainingActive state of the chart
Click a tick to show it, or use the Left and Right arrow keys to go back and step.
Guided tour, 9 ticks Press Next to run tick 1, or Take over to set the inputs yourself.

Guided tour, 9 ticks:

  1. start = false, stop = falseTick 1 starts in Idle. remaining has the parent’s initial value, 0.
  2. start = trueEntering Timing applies Countdown’s initial value for its output left to the bound variable: remaining = 3, not 0.
  3. start = falseCounting down: 2.
  4. 1.
  5. 0.
  6. The countdown has finished; remaining stays 0.
  7. stop = trueBack to Idle.
  8. stop = false, start = trueEvery entry of Timing applies the initial value again: remaining = 3.
  9. start = false2.
Note: remaining gets the initial value of Countdown's output left whenever Timing is entered, not its own
  • Note, line 8, column 19KIELER turns the referenced chart's output initial values into entry actions of the referencing state, so they win over the initial value declared here and are applied again on every entry.
remaining is 0 in tick 1, becomes 3 when Timing is entered in tick 2, and is set to 3 again on the next entry in tick 8.

Here that is convenient: every start restarts the countdown. But it also means that the referenced chart’s initial value wins over yours, and that a value you wanted to keep across visits is overwritten whenever the state is entered. Leave the initial value off the referenced chart’s output if the referencing chart should decide. Initial values of the referenced chart’s inputs, on the other hand, are ignored: the input is your variable, with your value.

A referenced chart terminates when all its regions reach final states, and then the referencing state terminates: a join to on it fires in the same tick, as for any superstate. This combination lock uses one small chart, Await, twice: once for a, then once for b.

CombinationSimulation

Diagram

Diagram of CombinationStates: First (initial, superstate), First/Await (superstate), Waiting (initial), Got (final), Second (superstate), Second/Await (superstate), Waiting (initial), Got (final), Opened (superstate). Transitions: Waiting to Got: key; Waiting to Got: key; First to Second; Second to Opened.Combinationinput boola, boutput boolopen = falseFirst@Await (a)Awaitinput boolkeyWaitingGotkeySecond@Await (b)Awaitinput boolkeyWaitingGotkeyOpenedentry/ open = true

Code

scchart Combination {
input bool a, b
output bool open = false
initial state First is Await(a to key)
join to Second
state Second is Await(b to key)
join to Opened
state Opened {
entry do open = true
}
}
scchart Await {
input bool key
initial state Waiting
if key go to Got
final state Got
}
Tick 0 of 6
Inputs for tick 1 Boolean input: true while on. It keeps its value until you change it. Boolean input: true while on. It keeps its value until you change it.
Timing diagram of Combination
Tickinput bool ainput bool boutput bool openActive state of the chart
Click a tick to show it, or use the Left and Right arrow keys to go back and step.
Guided tour, 6 ticks Press Next to run tick 1, or Take over to set the inputs yourself.

Guided tour, 6 ticks:

  1. a = false, b = falseTick 1 enters First, a copy of Await waiting for a.
  2. b = trueb is the wrong button now: First waits for a.
  3. b = false, a = truea: the copy reaches its final state Got, so First terminates and join to Second fires in the same tick.
  4. a = falseSecond, a new copy of Await, waits for b.
  5. b = trueb: Second terminates and the lock opens.
  6. b = falseOpen.
Pressing b first (tick 2) does nothing; a (tick 3) finishes First, and b (tick 5) finishes Second and opens the lock.

If the referenced chart has no final state in some region, it can never finish. KIELER then warns

The referenced SCChart does not terminate, but you are using a termination to proceed.

and the join to never fires.

  • ref declarations. ref C g(X, Y, O) among a state’s declarations also makes a copy of C, which runs alongside the state’s regions. They are mostly used in dataflow regions; elsewhere, an extra region with initial state G is C(X, Y, O) says the same more visibly.

  • region R is C(...) is not a reference. KIELER rejects it with Couldn't resolve reference to NamedObject 'C'. The form belongs to inheritance (extends, override), which Enums, structs and classes touches on and the KIELER wiki’s Object Orientation page describes. To run a chart as a region, write region { initial state R is C(...) }.

  • state S calls C(...) is accepted by KIELER’s grammar, but its C simulation cannot compile it.

  • A chart cannot contain itself, directly or through other charts: the copies would never end. Official KIELER’s compiler runs out of stack on such a chart, without a useful message; SCCharts Lab reports

    Recursive reference: chart Main uses itself (Main -> Main).

    Compiler messages explains it.

The silent doorbells

DoorbellPanel uses the chart Bell for its front and back doors, but neither bell ever rings: press front or back, and frontRings and backRings stay 0. KIELER reports no error and no warning. Find out why, and fix the panel without changing Bell.

Show the starter chart
scchart DoorbellPanel {
input bool front, back
output int frontRings = 0, backRings = 0
region {
initial state Front is Bell(front, frontRings)
}
region {
initial state Back is Bell(back, backRings)
}
}
scchart Bell {
output int rings = 0
input bool button
initial state Quiet
if button do rings++ go to Ringing
state Ringing
if !button go to Quiet
}
Show a hint

Bell(front, frontRings) binds by order. In which order does Bell declare its input and its output?

Show a solution
scchart DoorbellPanel {
input bool front, back
output int frontRings = 0, backRings = 0
region {
initial state Front is Bell(front to button, frontRings to rings)
}
region {
initial state Back is Bell(back to button, backRings to rings)
}
}
scchart Bell {
output int rings = 0
input bool button
initial state Quiet
if button do rings++ go to Ringing
state Ringing
if !button go to Quiet
}
A file contains scchart Helper { ... } followed by scchart Main { ... }, and Main references Helper. What happens when you simulate the file?
Show the answer

Answer D: Helper runs, because it is the first chart in the file

KIELER always simulates the first chart in a file, and nothing chooses another. Move Main to the top. The order of definitions does not matter for references: a reference may name a chart defined further down.

Counter declares output int n = 10 and counts n up with a delayed self-loop, do n++ go to Count. A chart declares output int total = 0 and has state C is Counter(total to n), entered in tick 3. What is total at the end of tick 3?
Show the answer

Answer B: 10

The initial value of Counter’s output becomes an entry action of C, applied to the bound variable on every entry: total = 10. The counting is delayed, so it starts in tick 4.

Two regions contain state A is Count(...) and state B is Count(...). Count has a local variable k. How many k are there?
Show the answer

Answer C: Two: each reference is a separate copy of Count

A reference is expanded into a copy of the referenced chart, locals included, so each instance counts on its own. To share a value, bind the same variable of the referencing chart to both.

Key ideas

  • state S is C(bindings) makes S a copy of chart C, wired to your variables; it then behaves like any superstate.
  • Only the first chart in a file is simulated. Put the main chart first; other charts, and imported files, are there to be referenced.
  • import "file" makes another file’s charts available; is names the chart.
  • Bind explicitly (actual to formal). Order bindings and implicit bindings work, but break silently.
  • Inside the copy, a formal is your variable: writes go straight to it, and an output’s initial value is assigned to it on every entry.
  • join to on a referencing state fires when the referenced chart reaches its final states.

Next, Arrays and for regions: a region written once and copied for every index of an array.

Report a mistake on this page