Skip to content

Entry, during and exit actions

Effects that belong to a state rather than a transition: they run when the state is entered, while it stays active, and when it is left, however that happens.

Open a fridge and the light comes on; close it and the light goes off. Why the door opened, or how long it stays open, makes no difference: the light belongs to being open. Until now every effect in your charts has belonged to a transition. This chapter attaches effects to states instead, with entry, during and exit actions, and shows exactly when each one runs.

FridgeSimulation

Diagram

Diagram of FridgeStates: Closed (initial), Open (superstate). Transitions: Closed to Open: doorOpen; Open to Closed: !doorOpen.Fridgeinput booldoorOpenoutput boollamp = falseClosedOpenentry/ lamp = trueexit/ lamp = falsedoorOpen!doorOpen

Code

scchart Fridge {
input bool doorOpen
output bool lamp = false
initial state Closed
if doorOpen go to Open
state Open {
entry do lamp = true
exit do lamp = false
}
if !doorOpen go to Closed
}
Tick 0 of 5
Inputs for tick 1 Boolean input: true while on. It keeps its value until you change it.
Timing diagram of Fridge
Tickinput bool doorOpenoutput bool lampActive 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, 5 ticks Press Next to run tick 1, or Take over to set the inputs yourself.

Guided tour, 5 ticks:

  1. doorOpen = falseTick 1 enters Closed. The lamp starts off (lamp = false from its declaration).
  2. doorOpen = trueThe door opens: Closed to Open fires, and entering Open runs its entry action, lamp = true. The transition itself has no effect.
  3. doorOpen is still true (inputs keep their value). Open has nothing to do, so lamp stays true.
  4. doorOpen = falseThe door closes: leaving Open runs its exit action, lamp = false.
  5. doorOpen = trueOpen again: the entry action runs again, as it does on every entry.
Neither transition has an effect. Watch lamp in ticks 2 and 4: the state Open switches it.

The two lines inside Open are its actions:

state Open {
entry do lamp = true
exit do lamp = false
}

An entry action runs every time its state is entered. An exit action runs every time its state is left. They are written inside the state’s braces, after any declarations and before any inner states, and the diagram lists them under the state’s name as entry / lamp = true and exit / lamp = false.

With one way into Open and one way out, you could have written do lamp = true on the transition in and do lamp = false on the transition out. The difference shows as a chart grows. Every new way into Open would need its own copy of lamp = true, and a forgotten copy is a bug that no compiler will point out. An entry action says “whenever I am entered” once, in the one place where it belongs.

A fridge that beeps when its door has been left open needs to count ticks while the door is open. That is the job of a during action: it runs in every tick in which its state is already active.

FridgeAlarmSimulation

Diagram

Diagram of FridgeAlarmStates: Closed (initial), Open (superstate), Quiet (initial), Beeping (superstate). Transitions: Quiet to Beeping: openFor == 3; Closed to Open: doorOpen; Open to Closed: !doorOpen.FridgeAlarminput booldoorOpenoutput boollamp = false, beep = falseoutput intopenFor = 0ClosedOpenentry/ lamp = true; openFor = 0during/ openFor++exit/ lamp = falseQuietBeepingentry/ beep = trueexit/ beep = falseopenFor == 3doorOpen!doorOpen

Code

scchart FridgeAlarm {
input bool doorOpen
output bool lamp = false, beep = false
output int openFor = 0
initial state Closed
if doorOpen go to Open
state Open {
entry do lamp = true; openFor = 0
during do openFor++
exit do lamp = false
initial state Quiet
if openFor == 3 go to Beeping
state Beeping {
entry do beep = true
exit do beep = false
}
}
if !doorOpen go to Closed
}
Tick 0 of 8
Inputs for tick 1 Boolean input: true while on. It keeps its value until you change it.
Timing diagram of FridgeAlarm
Tickinput bool doorOpenoutput bool lampoutput bool beepoutput int openForActive state of the chartActive state of the region of Open
Click a tick to show it, or use the Left and Right arrow keys to go back and step.
Guided tour, 8 ticks Press Next to run tick 1, or Take over to set the inputs yourself.

Guided tour, 8 ticks:

  1. doorOpen = falseTick 1 enters Closed.
  2. doorOpen = trueThe door opens. Entering Open runs its entry action (lamp = true; openFor = 0) and enters Quiet. The during action does not run in this tick: Open was only just entered.
  3. Open was already active when this tick began, so its during action runs: openFor becomes 1.
  4. openFor becomes 2.
  5. openFor becomes 3. The during action and Quiet’s trigger run in the same tick, and the update comes first, so openFor == 3 sees 3: Quiet to Beeping fires and Beeping’s entry action sets beep.
  6. Still open: openFor is 4, and the fridge keeps beeping.
  7. doorOpen = falseThe door closes. Open is left by a go to, so its during action still runs in this tick (openFor is 5). Then the exit actions run from the inside out: Beeping’s (beep = false), then Open’s (lamp = false).
  8. In Closed nothing changes: openFor keeps its last value.
openFor counts the ticks after the door opened. Look at tick 2, when it stays 0, and at tick 7, when the door closes and it still goes up.

Open is now a superstate with three actions and two inner states. Here is what KIELER’s simulation shows:

Tick doorOpen State after openFor lamp beep
1 false Closed 0 false false
2 true Open, Quiet 0 true false
3 true (held) Open, Quiet 1 true false
4 true (held) Open, Quiet 2 true false
5 true (held) Open, Beeping 3 true true
6 true (held) Open, Beeping 4 true true
7 false Closed 5 false false

Three things are worth a closer look.

The entry tick doesn’t count. In tick 2 the door opens and Open is entered: its entry action sets openFor = 0, and the during action does nothing. A plain during action is delayed, like a transition without immediate: it starts in the tick after its state was entered.

A superstate’s during action runs alongside its inner states. In tick 5, openFor++ and the trigger openFor == 3 of Quiet happen in the same tick, and the trigger sees 3. KIELER treats a superstate’s during action like one more concurrent region: as with any two regions, the update of openFor is scheduled before the read of it, whichever comes first in the source. This is the initialise–update–read order from Concurrent regions.

The tick of leaving does count. In tick 7 the door closes and openFor still goes from 4 to 5. if !doorOpen go to Closed is a weak abort, and as you saw in Aborts a weak abort lets the state finish its tick before it is left. The during action is part of that tick. Then the exit actions run from the inside out: Beeping’s switches the beep off, then Open’s switches the lamp off.

To run a during action in the entry tick too, write immediate during:

DuringCount and ImmediateDuringCountComparison

Diagrams

DuringCount

Diagram of DuringCountStates: Idle (initial), Busy (superstate). Transitions: Idle to Busy: start.DuringCountinput boolstartoutput intn = 0IdleBusyduring/ n++start

ImmediateDuringCount

Diagram of ImmediateDuringCountStates: Idle (initial), Busy (superstate). Transitions: Idle to Busy: start.ImmediateDuringCountinput boolstartoutput intn = 0IdleBusyimmediate during/ n++start

Code

DuringCount

scchart DuringCount {
input bool start
output int n = 0
initial state Idle
if start go to Busy
state Busy {
during do n++
}
}

ImmediateDuringCount

scchart ImmediateDuringCount {
input bool start
output int n = 0
initial state Idle
if start go to Busy
state Busy {
immediate during do n++
}
}
Tick 0 of 4
Inputs for tick 1, for both charts Boolean input: true while on. It keeps its value until you change it.
Timing diagram of DuringCount and ImmediateDuringCount, no ticks yet
Tickinput bool startDuringCount: output int nDuringCount: Active state of the chartImmediateDuringCount: output int nImmediateDuringCount: Active 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, 4 ticks Both charts get the same inputs. Press Next to run tick 1, or Take over to set the inputs yourself.

Guided tour, 4 ticks, the same inputs for both charts:

  1. start = falseTick 1 enters Idle in both charts.
  2. start = trueIdle to Busy fires in both charts, so Busy is entered in this tick. DuringCount’s plain during action skips the entry tick: n stays 0. ImmediateDuringCount’s immediate during runs in it: n is 1 at once.
  3. Busy was active when the tick began, so both during actions run: 1 in DuringCount, 2 in ImmediateDuringCount.
  4. One more in each, every tick: the immediate during version stays one ahead.
The same chart with during (DuringCount) and immediate during (ImmediateDuringCount). Busy is entered in tick 2.
Tick start n with during n with immediate during
1 false 0 0
2 true 0 1
3 true (held) 1 2
4 true (held) 2 3

An immediate during action runs in the entry tick even if the state is left again in that same tick by an immediate go to. An immediate abort to skips it, as a strong abort skips every during action in the tick it leaves (more on that below).

When a transition is taken, several actions can run in one tick. KIELER always runs them in the same order. In this chart every action adds 1 to step and records the number it got, so the outputs show the order:

ActionOrderSimulation

Diagram

Diagram of ActionOrderStates: A (initial, superstate), B (superstate). Transitions: A to B: leave / step++; effectAt = step.ActionOrderinput boolleaveoutput intstep = 0output intduringAt = 0, exitAt = 0, effectAt = 0, entryAt = 0Aduring/ step++; duringAt = stepexit/ step++; exitAt = stepBentry/ step++; entryAt = stepleave/ step++;effectAt = step

Code

scchart ActionOrder {
input bool leave
output int step = 0
output int duringAt = 0, exitAt = 0, effectAt = 0, entryAt = 0
initial state A {
during do step++; duringAt = step
exit do step++; exitAt = step
}
if leave do step++; effectAt = step go to B
state B {
entry do step++; entryAt = step
}
}
Tick 0 of 4
Inputs for tick 1 Boolean input: true while on. It keeps its value until you change it.
Timing diagram of ActionOrder
Tickinput bool leaveoutput int stepoutput int duringAtoutput int exitAtoutput int effectAtoutput int entryAtActive 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, 4 ticks Press Next to run tick 1, or Take over to set the inputs yourself.

Guided tour, 4 ticks:

  1. leave = falseTick 1 enters A. Its during action waits for the next tick: step is 0.
  2. A’s during action runs: step is 1, so duringAt is 1.
  3. leave = trueleave is true. In this one tick: A’s during action (duringAt = 2), A’s exit action (exitAt = 3), the transition’s effect (effectAt = 4) and B’s entry action (entryAt = 5). Each action adds 1 to step and records what it got.
  4. leave = falseB has no transitions and no during action: nothing changes.
Each action records when it ran. Step to tick 3, when leave is true.

In tick 3, duringAt is 2, exitAt 3, effectAt 4 and entryAt 5 (step was already 1, from A’s during action in tick 2). So: A’s during action, then A’s exit action, then the transition’s effect, then B’s entry action. With superstates, the full rule is:

  1. If the transition is a weak abort (go to) or a termination (join to): the source state’s behaviour for this tick, including its during actions. A strong abort (abort to) skips this step.
  2. The exit actions of every state being left, innermost first.
  3. The transition’s effects, left to right.
  4. The entry actions of every state being entered, outermost first.
  5. The immediate behaviour of the target: its immediate transitions and immediate during actions.

Each step sees the values that the steps before it wrote. A short way to remember it: leave inside out, enter outside in, and the transition’s effect sits in the middle.

Test yourself on a chart with superstates on both sides. Every action again records the value of step it produced.

NestedOrderPrediction

Diagram

Diagram of NestedOrderStates: Outer (initial, superstate), Inner (initial, superstate), Target (superstate), First (initial, superstate), Second. Transitions: First to Second: / step++; immediateAt = step; Outer to Target: leave / step++; effectAt = step.NestedOrderinput boolleaveoutput intstep = 0output intinnerExitAt = 0, outerExitAt = 0, effectAt = 0output intouterEntryAt = 0, innerEntryAt = 0, immediateAt = 0Outerexit/ step++; outerExitAt = stepInnerexit/ step++; innerExitAt = stepTargetentry/ step++; outerEntryAt = stepFirstentry/ step++; innerEntryAt = stepSecond/ step++;immediateAt = stepleave/ step++;effectAt = step

Code

scchart NestedOrder {
input bool leave
output int step = 0
output int innerExitAt = 0, outerExitAt = 0, effectAt = 0
output int outerEntryAt = 0, innerEntryAt = 0, immediateAt = 0
initial state Outer {
exit do step++; outerExitAt = step
initial state Inner {
exit do step++; innerExitAt = step
}
}
if leave do step++; effectAt = step go to Target
state Target {
entry do step++; outerEntryAt = step
initial state First {
entry do step++; innerEntryAt = step
}
immediate do step++; immediateAt = step go to Second
state Second
}
}

In tick 2, leave takes the chart from Outer to Target. Predict the order, then run it.

Inputs per tick. A value in grey was not set in that tick: it holds from an earlier one.

Tickleave
1false
2true
Plays the scenario on the diagram, then marks each answer.
Explanation

innerExitAt is 1, outerEntryAt 4, innerEntryAt 5 and immediateAt 6. Leaving runs the exit actions from the inside out (Inner 1, Outer 2), then the transition’s effect (3). Entering runs the entry actions from the outside in (Target 4, First 5). Last comes the immediate behaviour of the target: First’s immediate transition (6).

Two more details about order. Several entry actions of one state run in the order they are written, and so do several exit actions. A variable declared inside a state gets its initial value each time the state is entered, just before the state’s entry actions (see Superstates).

A transition from a state to itself is a real exit and a real entry: the exit actions run, then the effect, then the entry actions. For a superstate, the inside starts again from its initial states. That is sometimes what you want, and often not:

SelfLoop and StayComparison

Diagrams

SelfLoop

Diagram of SelfLoopStates: Ready (initial, superstate). Transitions: Ready to Ready: press / presses++.SelfLoopinput boolpressoutput intpresses = 0, entries = 0Readyentry/ entries++press/ presses++

Stay

Diagram of StayStates: Ready (initial, superstate). Transitions: none.Stayinput boolpressoutput intpresses = 0, entries = 0Readyentry/ entries++duringpress/ presses++

Code

SelfLoop

scchart SelfLoop {
input bool press
output int presses = 0, entries = 0
initial state Ready {
entry do entries++
}
if press do presses++ go to Ready
}

Stay

scchart Stay {
input bool press
output int presses = 0, entries = 0
initial state Ready {
entry do entries++
during if press do presses++
}
}
Tick 0 of 5
Inputs for tick 1, for both charts Boolean input: true while on. It keeps its value until you change it.
Timing diagram of SelfLoop and Stay, no ticks yet
Tickinput bool pressSelfLoop: output int pressesSelfLoop: output int entriesSelfLoop: Active state of the chartStay: output int pressesStay: output int entriesStay: Active 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, 5 ticks Both charts get the same inputs. Press Next to run tick 1, or Take over to set the inputs yourself.

Guided tour, 5 ticks, the same inputs for both charts:

  1. press = falseTick 1 enters Ready in both charts and runs its entry action: entries is 1 on both sides.
  2. press = trueA press. SelfLoop’s self-loop leaves Ready and enters it again, so its entry action runs again (entries 2) and the effect counts the press. Stay’s guarded during action counts the press without leaving: entries stays 1.
  3. press = falseNo press: nothing changes on either side.
  4. press = trueSecond press: presses is 2 on both sides, entries is 3 in SelfLoop and still 1 in Stay.
  5. press is held, so both count again: presses is 3. SelfLoop has been entered four times, Stay once.
Both charts count presses. In SelfLoop a self-loop does it, in Stay a during if press action. Watch entries.
Tick press presses entries in SelfLoop entries in Stay
1 false 0 1 1
2 true 1 2 1
3 false 1 2 1
4 true 2 3 1
5 true (held) 3 4 1

Both charts count the same presses, but only the self-loop leaves Ready and enters it again each time. If you mean “do this while staying here”, write a during action with a trigger. If you mean “start this state over”, a self-loop is right, and its entry actions are part of starting over.

Aborts and actions meet in one question: when a state is cut short, which of its actions still run?

MachineSimulation

Diagram

Diagram of MachineStates: Running (initial, superstate), Halted. Transitions: Running to Halted: 1: emergency; Running to Halted: 2: stop; Halted to Running: start.Machineinput boolstart, stop, emergencyoutput boolmotor = falseoutput intticks = 0Runningentry/ motor = trueduring/ ticks++exit/ motor = falseHalted1: emergency2: stopstart

Code

scchart Machine {
input bool start, stop, emergency
output bool motor = false
output int ticks = 0
initial state Running {
entry do motor = true
during do ticks++
exit do motor = false
}
if emergency abort to Halted
if stop go to Halted
state Halted
if start go to Running
}
Tick 0 of 7
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. Boolean input: true while on. It keeps its value until you change it.
Timing diagram of Machine
Tickinput bool startinput bool stopinput bool emergencyoutput bool motoroutput int ticksActive 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, 7 ticks Press Next to run tick 1, or Take over to set the inputs yourself.

Guided tour, 7 ticks:

  1. start = false, stop = false, emergency = falseTick 1 enters Running: the entry action switches the motor on. The during action waits for the next tick.
  2. Running: the during action counts the tick (ticks is 1).
  3. stop = truestop leaves Running by a weak abort (go to): the during action still runs (ticks is 2), then the exit action switches the motor off.
  4. stop = false, start = truestart enters Running again: the motor is on.
  5. start = falseticks is 3.
  6. emergency = trueemergency leaves by a strong abort (abort to). The during action is skipped (ticks stays 3), but the exit action still runs: the motor is off.
  7. emergency = falseIn Halted: nothing changes.
stop in tick 3 is a weak abort, emergency in tick 6 a strong one. Compare ticks and motor in those two ticks.

In tick 3, stop leaves Running with go to: the during action still counts the tick (ticks is 2) and the exit action switches the motor off. In tick 6, emergency leaves with abort to: the during action is skipped (ticks stays 3), but the exit action still runs and the motor is off. Running is a simple state, and this is the one difference between go to and abort to on a simple state that Aborts promised.

For a superstate the same holds at every level. Here is the full picture of the tick in which a state is left by a weak abort, a strong abort or a termination:

In the leaving tick go to abort to join to
inner transitions run skipped run
during actions run skipped run
exit actions run run run
effect, then entry actions run run run

The during row means the state’s own during actions and those of every active state inside it, and so does the exit row: exit actions run innermost first and the left state’s own last. The first row and the last column only apply to superstates, which have an inside and can terminate.

So exit actions run however a state is left: by a weak abort, a strong abort, a termination, a self-loop, or because an enclosing state is left. Think of an exit action as the finally block of a state; Mode switching relies on exactly that. Entry actions are just as dependable: they run on every entry, even when the state is left again in the same tick, and even when an immediate abort to fires in the very tick the state is entered. (Two constructs of Going further are the exceptions: suspend and deferred entries.) Of the three plain kinds, only during actions depend on how a state is left.

Every kind of action can have a trigger: entry if c do …, during if c do … and exit if c do …. What matters is when the trigger is checked. A car’s courtesy light shows it:

CourtesyLightSimulation

Diagram

Diagram of CourtesyLightStates: Closed (initial), Open (superstate). Transitions: Closed to Open: doorOpen; Open to Closed: !doorOpen.CourtesyLightinput booldoorOpen, darkoutput boollight = falseClosedOpenentrydark/ light = trueexit/ light = falsedoorOpen!doorOpen

Code

scchart CourtesyLight {
input bool doorOpen, dark
output bool light = false
initial state Closed
if doorOpen go to Open
state Open {
entry if dark do light = true
exit do light = false
}
if !doorOpen go to Closed
}
Tick 0 of 7
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 CourtesyLight
Tickinput bool doorOpeninput bool darkoutput bool lightActive 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, 7 ticks Press Next to run tick 1, or Take over to set the inputs yourself.

Guided tour, 7 ticks:

  1. doorOpen = false, dark = falseTick 1 enters Closed.
  2. doorOpen = trueThe door opens in daylight. The entry action’s trigger dark is checked now, at the moment Open is entered: false, so the light stays off.
  3. dark = trueIt gets dark while the door is open. The entry action has already had its chance: the light stays off.
  4. doorOpen = falseThe door closes: the exit action runs (the light was off anyway).
  5. doorOpen = trueThe door opens in the dark: dark is true at the moment of entry, so the light comes on.
  6. dark = falseDaylight again, but nothing checks dark now: the light stays on.
  7. doorOpen = falseThe door closes and the exit action switches the light off.
The light comes on only if it is dark at the moment the door opens. Watch ticks 3 and 6, when dark changes while the door is open.
  • An entry trigger is checked once, at the moment the state is entered, after the effect of the transition that led in. In tick 3 it gets dark while the door is open, and nothing switches the light on: the entry action has had its chance. In tick 6, the other way round, daylight returns while the light is on, and nothing checks dark either: the light stays on until the door closes.
  • An exit trigger is checked at the moment the state is left, before the effect of the transition that leaves.
  • A during trigger is checked in every tick in which the during action would run.

To switch the light on as soon as it gets dark while the door is open, you would need a during action, during if dark do light = true, whose trigger is checked in every tick.

A transition or an action can end with label "…". The diagram then shows the label instead of the trigger and effects:

FridgeLabelsChart

Diagram

Diagram of FridgeLabelsStates: Closed (initial), Open (superstate), Quiet (initial), Beeping (superstate). Transitions: Quiet to Beeping: open too long; Closed to Open: door opens; Open to Closed: door closes.FridgeLabelsinput booldoorOpenoutput boollamp = false, beep = falseoutput intopenFor = 0ClosedOpenentrylamp on, start countingduringcount the ticksexitlamp offQuietBeepingentrystart beepingexitstop beepingopen too longdoor opensdoor closes

Code

scchart FridgeLabels {
input bool doorOpen
output bool lamp = false, beep = false
output int openFor = 0
initial state Closed
if doorOpen go to Open label "door opens"
state Open {
entry do lamp = true; openFor = 0 label "lamp on, start counting"
during do openFor++ label "count the ticks"
exit do lamp = false label "lamp off"
initial state Quiet
if openFor == 3 go to Beeping label "open too long"
state Beeping {
entry do beep = true label "start beeping"
exit do beep = false label "stop beeping"
}
}
if !doorOpen go to Closed label "door closes"
}
FridgeAlarm with labels. Switch to the code to see the label clauses; the chart behaves exactly as before.

Labels change only the picture, which makes them useful for diagrams that people other than programmers will read. KIELER notes each hidden part with an information message, on actions and transitions alike:

The trigger of this action is hidden by the label.
The effects of this action are hidden by the label.

A state can have a display name as well, written after its name: state Open "Door open". More on comments and annotations in Comments and annotations.

You may meet four more keywords in other people’s charts. strong entry and strong exit mean the same as entry and exit. The weak forms are cut short by aborts:

Written Runs
entry, strong entry on every entry
weak entry on every entry, except when the state is strongly aborted in its entry tick
exit, strong exit on every exit
weak exit on a superstate only when the superstate terminates through join to; skipped by go to as well as by abort to
weak exit on a simple state on every exit, like exit

The names suggest “skipped only by strong aborts”, which is not what KIELER does for weak exit. Here is the same superstate twice, with exit and with weak exit, left once by its join and once by a plain go to:

PlainExit and WeakExitComparison

Diagrams

PlainExit

Diagram of PlainExitStates: Task (initial, superstate), Working (initial), Finished (final), Idle. Transitions: Working to Finished: finish; Task to Idle: 1: cancel; Task to Idle: 2:; Idle to Task.PlainExitinput boolfinish, canceloutput intexits = 0Taskexit/ exits++WorkingFinishedfinishIdle1: cancel2:

WeakExit

Diagram of WeakExitStates: Task (initial, superstate), Working (initial), Finished (final), Idle. Transitions: Working to Finished: finish; Task to Idle: 1: cancel; Task to Idle: 2:; Idle to Task.WeakExitinput boolfinish, canceloutput intexits = 0Taskweak exit/ exits++WorkingFinishedfinishIdle1: cancel2:

Code

PlainExit

scchart PlainExit {
input bool finish, cancel
output int exits = 0
initial state Task {
exit do exits++
initial state Working
if finish go to Finished
final state Finished
}
if cancel go to Idle
join to Idle
state Idle
go to Task
}

WeakExit

scchart WeakExit {
input bool finish, cancel
output int exits = 0
initial state Task {
weak exit do exits++
initial state Working
if finish go to Finished
final state Finished
}
if cancel go to Idle
join to Idle
state Idle
go to Task
}
Tick 0 of 5
Inputs for tick 1, for both charts 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 PlainExit and WeakExit, no ticks yet
Tickinput bool finishinput bool cancelPlainExit: output int exitsPlainExit: Active state of the chartPlainExit: Active state of the region of TaskWeakExit: output int exitsWeakExit: Active state of the chartWeakExit: Active state of the region of Task
Click a tick to show it, or use the Left and Right arrow keys to go back and step.
Guided tour, 5 ticks Both charts get the same inputs. Press Next to run tick 1, or Take over to set the inputs yourself.

Guided tour, 5 ticks, the same inputs for both charts:

  1. finish = false, cancel = falseTick 1 enters Task and Working in both charts.
  2. finish = truefinish: Working moves to the final state Finished, Task terminates, and join to leaves it. On a termination both exit actions run: exits is 1 in both charts.
  3. finish = falseIdle’s delayed transition starts a new Task.
  4. cancel = truecancel leaves Task with go to, a weak abort. PlainExit’s exit action runs (exits is 2); WeakExit’s weak exit is skipped and exits stays 1.
  5. cancel = falseA new Task again. Only a termination runs a weak exit on a superstate.
Note: This weak exit only runs when Task finishes through join to, not when it is left by go to or abort to (WeakExit)
  • Note in WeakExit, line 6, column 5On a superstate, KIELER expands weak exit actions before the aborts, so both kinds of abort bypass them. Use a plain exit action to run something however the state is left.
Tick 2 leaves Task with join to, tick 4 with go to. Watch exits in tick 4.

Both exit actions run when Task terminates (tick 2). In tick 4 go to leaves Task: a weak abort, which lets the during actions and the inner transitions run, but the weak exit is skipped all the same, and only PlainExit counts. Read weak exit as “on normal completion only”. You will rarely need either weak form; plain entry and exit are what you want almost always.

You can also write actions directly inside the scchart braces, after the declarations and before the first state. They belong to the chart’s invisible outermost state: its entry actions run first in tick 1, its during actions run in every tick from tick 2 (from tick 1 with immediate), and its exit actions run when the whole chart terminates.

One place for the siren

This alarm sets siren = true on two transitions and siren = false on a third. Move the siren into an entry and an exit action of Ringing, so that no transition mentions it. Then add a panic input that also starts the alarm from Armed. With the actions in place, the new transition needs no effect at all.

Show the starter chart
scchart Alarm {
input bool door, window, code
output bool siren = false
initial state Armed
if door do siren = true go to Ringing
if window do siren = true go to Ringing
state Ringing
if code do siren = false go to Disarmed
state Disarmed
if code go to Armed
}
Show a solution
scchart Alarm {
input bool door, window, code, panic
output bool siren = false
initial state Armed
if door go to Ringing
if window go to Ringing
if panic go to Ringing
state Ringing {
entry do siren = true
exit do siren = false
}
if code go to Disarmed
state Disarmed
if code go to Armed
}

A stopwatch stuck at zero

elapsed should count the ticks since start, but it never leaves 0. Simulate it and work out why from what you know about self-loops. Then fix it so that elapsed counts while Running is active and stop still leaves.

Show the starter chart
scchart Stopwatch {
input bool start, stop
output bool running = false
output int elapsed = 0
initial state Stopped
if start go to Running
state Running {
entry do running = true; elapsed = 0
exit do running = false
}
if stop go to Stopped
do elapsed++ go to Running
}
Show a solution
scchart Stopwatch {
input bool start, stop
output bool running = false
output int elapsed = 0
initial state Stopped
if start go to Running
state Running {
entry do running = true; elapsed = 0
during do elapsed++
exit do running = false
}
if stop go to Stopped
}
A heater’s state On has during do onTicks++ and exit do power = false. At the start of a tick onTicks is 3 and power is true, and in that tick if off abort to Off leaves On. What are onTicks and power after the tick?
Show the answer

Answer A: 3 and false

A strong abort skips the state’s during actions in the leaving tick, so onTicks stays 3, but exit actions run however a state is left, so power is false. With go to Off it would be 4 and false. Machine above shows both, in ticks 3 and 6.

In FridgeAlarm, the door opens in tick 2 and closes in tick 7. during do openFor++ is the only action that changes openFor after the entry. What is openFor after tick 7?
Show the answer

Answer B: 5

The during action skips tick 2, the entry tick, and runs in ticks 3, 4, 5 and 6. In tick 7 the state is left by go to, a weak abort, so the during action runs once more before the exit actions: 5.

A state has entry do elapsed = 0 and a self-loop do elapsed++ go to Running that fires every tick. What is elapsed after the self-loop has fired?
Show the answer

Answer A: 0: the effect adds 1, then re-entering runs the entry action

Order on a transition: exit actions, then effects, then entry actions. The effect makes elapsed 1, and the entry action of the re-entered state sets it back to 0. That is the stopwatch bug above.

Key ideas

  • An entry action runs every time its state is entered and an exit action every time it is left, whichever transition did it. Put an effect in a state when it belongs to being in that state.
  • A during action runs in every tick in which its state is already active: not in the entry tick, but in the tick the state is left by go to. immediate during adds the entry tick.
  • When a transition is taken: the source’s during actions (not for abort to), exit actions innermost first, the transition’s effects, entry actions outermost first, then the target’s immediate behaviour.
  • Exit actions run on strong aborts too. Only during actions depend on the kind of abort.
  • A self-loop leaves and re-enters its state, so its exit and entry actions run.
  • A trigger on an action is checked at that moment; a label changes only the diagram.

Next, The previous tick: comparing a value with its value one tick ago, to react to changes instead of levels.

Report a mistake on this page