Aborts
Cutting a superstate short: weak and strong aborts, immediate aborts, priorities, and what the inside may still do in the tick it is left.
Press cancel on a printer, and one of two things can happen: it finishes the sheet it is printing and then stops, or it stops dead. Both are right in their place. A cancelled job should not leave half a sheet in the printer; a paper jam has to stop the rollers at once, whatever they were about to do.
SCCharts has a transition for each. You met the first kind in Superstates: a
transition written after a superstate’s closing brace leaves the superstate from whichever state is
active inside it. Such a transition is an abort, and it comes in two strengths: the go to you know
is the weak one, and ABRO’s reset at the end of Concurrent regions,
if R abort to ABO, is the strong one.
(Aborts and suspension, which comes in Going further, together make up
preemption: something outside a state taking control away from it.) This chapter is about the
tick in which a superstate is left: what its inside may still do, and which way out wins when several
apply at once.
Weak and strong
Section titled “Weak and strong”Here is a print job twice, once ended by go to and once by abort to. Every sheet that comes out
of the printer is counted, and cancel ends the job.
Diagrams
WeakCancel
StrongCancel
Code
WeakCancel
scchart WeakCancel { input bool start, sheet, cancel output int printed
initial state Idle if start go to Job
state Job { initial state Printing if sheet do printed++ go to Printing } if cancel go to Idle}StrongCancel
scchart StrongCancel { input bool start, sheet, cancel output int printed
initial state Idle if start go to Job
state Job { initial state Printing if sheet do printed++ go to Printing } if cancel abort to Idle}| Tick | input bool start | input bool sheet | input bool cancel | WeakCancel: output int printed | WeakCancel: Active state of the chart | WeakCancel: Active state of the region of Job | StrongCancel: output int printed | StrongCancel: Active state of the chart | StrongCancel: Active state of the region of Job |
|---|
Guided tour, 6 ticks, the same inputs for both charts:
- start = false, sheet = false, cancel = falseTick 1 enters
Idlein both charts. - start = true
start: both printers enterJobandPrinting. - start = false, sheet = trueA sheet comes out:
printedis 1 on both sides. - Another sheet (
sheetis still true): 2 on both sides. - cancel = true
canceland a sheet in the same tick.WeakCancel’sgo tois a weak abort: the inside ofJobfirst finishes its tick, so the sheet is counted (3), and only then isJobleft.StrongCancel’sabort tois a strong abort:Jobis left before anything inside it runs, so the sheet is not counted andprintedstays 2. - cancel = false, sheet = falseBoth printers are back in
Idle.
cancel and a sheet arrive together: WeakCancel counts the sheet, StrongCancel does not.The tour starts the job in tick 2, sends a sheet in every tick from tick 3 and cancels in tick 5. KIELER gives:
| Tick | sheet |
cancel |
printed, weak |
printed, strong |
|---|---|---|---|---|
| 3 | true | false (held) | 1 | 1 |
| 4 | true (held) | false (held) | 2 | 2 |
| 5 | true (held) | true | 3 | 2 |
In tick 5 the two kinds of abort part ways:
- A weak abort, written
go to, is the default. In the tick it fires, the inside of the superstate first completes its reaction: its transitions fire, chains of immediate transitions run to their end. Only then is the superstate left.WeakCancelcounts the sheet of tick 5. - A strong abort, written
abort to, leaves the superstate before anything inside it reacts in that tick.StrongCancelnever sees the sheet of tick 5.
Either way, the abort’s own effect runs next, and then its target is entered. In the diagram KIELER marks a strong abort with a red circle where it starts; a weak abort has no mark.
Which one to use is a question of what the inside may still do. Use a strong abort when nothing inside may act any more once the trigger is there: an emergency stop, a reset that has to win. Use a weak abort when the inside should finish what it is doing in this tick: complete a step, let a last output out. A weak abort grants the inside a last wish.
States can also carry actions of their own, which run when a state is entered, while it is active and when it is left. What an abort does to them is part of the next chapter, Entry, during and exit actions.
Delayed and immediate aborts
Section titled “Delayed and immediate aborts”An abort is a transition, and the rule from Delayed and immediate transitions
applies to it: without immediate, it is not checked in the tick its superstate is entered.
Usually that is what you want. It makes a difference when the trigger is already there as the
superstate is entered:
Diagrams
DelayedAbort
ImmediateAbort
Code
DelayedAbort
scchart DelayedAbort { input bool start, cancel output bool busy
initial state Idle if start do busy = true go to Job
state Job { initial state Printing } if cancel do busy = false abort to Idle}ImmediateAbort
scchart ImmediateAbort { input bool start, cancel output bool busy
initial state Idle if start do busy = true go to Job
state Job { initial state Printing } immediate if cancel do busy = false abort to Idle}| Tick | input bool start | input bool cancel | DelayedAbort: output bool busy | DelayedAbort: Active state of the chart | DelayedAbort: Active state of the region of Job | ImmediateAbort: output bool busy | ImmediateAbort: Active state of the chart | ImmediateAbort: Active state of the region of Job |
|---|
Guided tour, 4 ticks, the same inputs for both charts:
- start = false, cancel = falseTick 1 enters
Idlein both charts. - start = true, cancel = true
startwhilecancelis held down. Both charts setbusyand enterJob.DelayedAbort’s abort is not checked in the tickJobis entered, so it stays inJobwithbusytrue.ImmediateAbort’s abort is checked at once: it fires, setsbusyback to false and returns toIdle. ItsJobwas entered and left in one tick. - start = false
cancelis still true, and nowDelayedAbort’s abort may fire too:Jobis left andbusyis false. Both charts are inIdle. - cancel = falseBoth idle.
start arrives in tick 2 while cancel is held: DelayedAbort stays in Job for that tick, ImmediateAbort is back in Idle at once.With immediate, the abort is checked in the entry tick and in every tick after it. If it fires in
the entry tick, the superstate is entered and left in that one tick. For a weak abort, the immediate
transitions inside the superstate still run first; a strong abort skips them.
When the trigger is read
Section titled “When the trigger is read”A strong abort is decided before the inside reacts, a weak abort after it. That matters when the inside itself changes the abort’s trigger. This print job ends by itself once three sheets are out:
Diagrams
TrayWeak
TrayStrong
Code
TrayWeak
scchart TrayWeak { input bool start, sheet output int printed
initial state Idle if start go to Job
state Job { initial state Printing if sheet do printed++ go to Printing } if printed >= 3 go to Idle}TrayStrong
scchart TrayStrong { input bool start, sheet output int printed
initial state Idle if start go to Job
state Job { initial state Printing if sheet do printed++ go to Printing } if printed >= 3 abort to Idle}| Tick | input bool start | input bool sheet | TrayWeak: output int printed | TrayWeak: Active state of the chart | TrayWeak: Active state of the region of Job | TrayStrong: output int printed | TrayStrong: Active state of the chart | TrayStrong: Active state of the region of Job |
|---|
Guided tour, 7 ticks, the same inputs for both charts:
- start = false, sheet = falseTick 1 enters
Idlein both charts. - start = true
start: both enterJob. - start = false, sheet = trueSheet 1 on both sides.
- Sheet 2 on both sides.
- Sheet 3:
printedis 3 on both sides.TrayWeak’s weak abort readsprinted >= 3after the inside has run, sees 3 and leaves in this tick.TrayStrong’s strong abort read its trigger before the inside ran, whenprintedwas still 2, soTrayStrongstays inJob. - Another sheet.
TrayWeakis inIdleand ignores it.TrayStrong’s abort now sees 3 and fires before the inside runs, so this sheet is not counted: both charts stay at 3. - sheet = falseBoth idle.
TrayWeak leaves in that tick, TrayStrong one tick later.In tick 5 the third sheet makes printed 3. The weak abort reads its trigger after the inside has
reacted, sees 3, and leaves at once. The strong abort read its trigger before the inside reacted,
when printed was still 2, so it fires one tick later, in tick 6, and skips that tick’s sheet.
Strong looks before the inside moves; weak looks after. To leave a superstate because of something
its inside did, use a weak abort or, better, a final state and join to. Avoid strong aborts whose
trigger is written by the state they abort: with several regions inside, KIELER then aborts the
regions one by one, some a tick later than others, and some such charts are rejected as causality
cycles. Watchdogs shows both outcomes, and the
arrangement that avoids them.
Several ways out
Section titled “Several ways out”A superstate can have several outgoing transitions. As for any state, they are tried in the order written, and the first whose trigger holds wins (see Triggers, effects and priority). Aborts add one rule: strong aborts come first. KIELER rejects any state, simple states included, in which a strong abort is written after a weak abort or a termination transition.
Diagram
Code
scchart WrongOrder { input bool start, sheet, cancel, jam output int printed
initial state Idle if start go to Job
state Job { initial state Printing if sheet do printed++ go to Printing } if cancel go to Idle if jam abort to Idle}KIELER rejects this chart
- Line 13, column 3A strong abort (
abort to) must come before the other transitions of the stateKIELER says:Causality problem! Strong abort transitions must have a higher priority than weak abort or termination transitions.
A strong abort is checked before the state runs, so it needs a higher priority thango toandjoin totransitions: move it above them.About this message
jam is a strong abort, written below the weak cancel. KIELER rejects the chart.The fix is to move every abort to of a state above its go to and join to transitions.
The rule follows from the timing in the previous section. A strong abort has to be decided before the inside reacts; a weak abort or a join can only be decided after. A weak abort with a higher priority than a strong one would have to be decided first, so it would need the inside’s reaction before the strong abort had its chance to prevent that reaction. KIELER calls that a causality problem and refuses.
With the order right, a strong and a weak abort that hold in the same tick are easy to decide: the strong one comes first, so it wins, and nothing inside runs.
Finishing versus being stopped
Section titled “Finishing versus being stopped”A termination transition is the third way out of a superstate. It is not an abort: it leaves because the inside has finished, not because something outside says so. In its timing it behaves like a weak abort, though. The inside reacts first in the tick, and the join fires after it.
Now suppose the inside finishes in the same tick in which a weak abort fires. Both ways out apply, and the order decides:
Diagrams
TwoPages
TwoPagesJoinFirst
Code
TwoPages
scchart TwoPages { input bool start, sheet, cancel output int printed output signal finished, cancelled
initial state Idle if start go to Job
state Job { initial state First if sheet do printed++ go to Second state Second if sheet do printed++ go to Done final state Done } if cancel do cancelled go to Idle do finished join to Idle}TwoPagesJoinFirst
scchart TwoPagesJoinFirst { input bool start, sheet, cancel output int printed output signal finished, cancelled
initial state Idle if start go to Job
state Job { initial state First if sheet do printed++ go to Second state Second if sheet do printed++ go to Done final state Done } do finished join to Idle if cancel do cancelled go to Idle}| Tick | input bool start | input bool sheet | input bool cancel | TwoPages: output int printed | TwoPages: output signal finished | TwoPages: output signal cancelled | TwoPages: Active state of the chart | TwoPages: Active state of the region of Job | TwoPagesJoinFirst: output int printed | TwoPagesJoinFirst: output signal finished | TwoPagesJoinFirst: output signal cancelled | TwoPagesJoinFirst: Active state of the chart | TwoPagesJoinFirst: Active state of the region of Job |
|---|
Guided tour, 5 ticks, the same inputs for both charts:
- start = false, sheet = false, cancel = falseTick 1 enters
Idlein both charts. - start = true
start: both enterJob, atFirst. - start = false, sheet = trueThe first sheet: 1 on both sides.
- cancel = trueThe second sheet and
cancelin the same tick. Both ways out are weak, so in both charts the inside runs first: the sheet is counted (2) andDoneis reached. Each job has finished and been cancelled, and the transition written first wins:TwoPagesemitscancelled,TwoPagesJoinFirstemitsfinished. - cancel = false, sheet = falseBoth idle.
In both charts the second sheet is counted in tick 4 (both ways out are weak, so the inside reacts
first), and Job has both finished and been cancelled. TwoPages writes the cancel first and emits
cancelled; TwoPagesJoinFirst writes the join first and emits finished. Put first the transition
that should win.
To leave a superstate when its inside is done, use join to, not a go to without a trigger. On a
superstate, an abort without a trigger only gets the warning Abort transitions should have a trigger., and it fires in the tick after the superstate was entered, whatever the inside is doing.
Aborts on simple states
Section titled “Aborts on simple states”A transition out of a simple state counts as an abort too, but a simple state has no inside to finish
or to skip. For a simple state without actions, go to and abort to behave exactly alike; KIELER
turns such strong aborts into weak ones. A state with a during action is the one case where they
differ, and the next chapter shows it.
ABRO, the classic
Section titled “ABRO, the classic”Back to ABRO from Concurrent regions. Its last line, if R abort to ABO, is a
strong abort from ABO back to itself. Such a self-loop is a full exit and re-entry: ABO is left
and entered again from its initial state, so every region inside starts over.
Why strong? Look at the tick in which R arrives together with the last of A and B. ABRO’s
specification says that R starts again from the beginning, so that B should not complete the old
round. Here is ABRO next to a copy whose reset is weak:
Diagrams
ABRO
ABROWeak
Code
ABRO
scchart ABRO { input signal A, B, R output signal O
initial state ABO { initial state WaitAB { region HandleA { initial state WaitA if A go to DoneA final state DoneA } region HandleB { initial state WaitB if B go to DoneB final state DoneB } } do O join to Done
state Done } if R abort to ABO}ABROWeak
scchart ABROWeak { input signal A, B, R output signal O
initial state ABO { initial state WaitAB { region HandleA { initial state WaitA if A go to DoneA final state DoneA } region HandleB { initial state WaitB if B go to DoneB final state DoneB } } do O join to Done
state Done } if R go to ABO}| Tick | input signal A | input signal B | input signal R | ABRO: output signal O | ABRO: Active state of the chart | ABRO: Active state of the region of ABO | ABRO: Active state of region HandleA (in ABO.WaitAB) | ABRO: Active state of region HandleB (in ABO.WaitAB) | ABROWeak: output signal O | ABROWeak: Active state of the chart | ABROWeak: Active state of the region of ABO | ABROWeak: Active state of region HandleA (in ABO.WaitAB) | ABROWeak: Active state of region HandleB (in ABO.WaitAB) |
|---|
Guided tour, 7 ticks, the same inputs for both charts:
- A = false, B = false, R = falseTick 1 enters
ABO,WaitAB,WaitAandWaitBin both charts. - A = true
A:HandleAis done in both charts. - A = falseBoth wait for
B. - B = true, R = true
BandRin the same tick.ABRO’s strong reset leavesABObefore anything inside it moves:HandleBnever sees thisB, the join does not happen andOis absent.ABROWeak’s weak reset lets the inside finish its tick first:HandleBseesB,WaitABterminates andOis emitted. Then both charts enterABOagain, with both regions waiting. - B = false, R = falseBoth wait for
AandBagain. - A = true, B = true
AandBtogether: both regions finish in this tick, and both charts emitO. - A = false, B = falseIn
Doneuntil the nextR.
Warning: KIELER warns about a potential instantaneous loop here, but compiles and runs the chart correctly (ABROWeak)
- Warning in
ABROWeak, line 6, column 19KIELER says:Instantaneous loop detected!
KIELER's loop check also warns about a superstate that a transition leaves and enters again in one tick, hereWaitAB: in the compiled chart, leaving it and starting it again look like a circle, although the new start only enters its initial states and then waits for the next tick. The chart works as written.About this message
A comes in tick 2, then B and R together in tick 4: the strong reset suppresses O; with the weak one the inside finishes first, and O is present.With abort to, ABO is left before HandleB sees B: no join, no O, and in tick 4 the new
round starts with both regions waiting. That B does not count for the new round either: WaitB was
entered in tick 4, and its delayed transition cannot fire in its entry tick. With go to, the last
wish lets HandleB finish, WaitAB terminates and emits O, and only then is ABO restarted.
Which behaviour is right is a matter of specification. The classic answer is the strong one: R
wins.
KIELER compiles ABROWeak with a warning, Instantaneous loop detected! (SCCharts Lab:
Potential instantaneous loop.). KIELER gives this warning for many charts in which a weak abort leads
straight back into its own superstate; the chart still compiles and behaves as described here
(more about this warning).
Try it
Section titled “Try it”A paper jam
Add an input jam to WeakCancel that ends the job at once: a sheet that comes out in the tick of the
jam must not be counted. cancel keeps its behaviour and still counts the sheet of its tick. Check
both in the simulation, and mind the order of the two transitions.
Show the starter chart
scchart WeakCancel { input bool start, sheet, cancel output int printed
initial state Idle if start go to Job
state Job { initial state Printing if sheet do printed++ go to Printing } if cancel go to Idle}Show a hint
The sheet of the jam’s tick must not be counted, so nothing inside Job may react in that tick. And KIELER wants one kind of abort written before the other.
Show a solution
scchart Jam { input bool start, sheet, cancel, jam output int printed
initial state Idle if start go to Job
state Job { initial state Printing if sheet do printed++ go to Printing } if jam abort to Idle if cancel go to Idle}Check your understanding
Section titled “Check your understanding”TwoPagesStrong is TwoPages with a strong cancel, written first as it must be. In tick 4 the second
sheet and cancel arrive together.
Diagram
Code
scchart TwoPagesStrong { input bool start, sheet, cancel output int printed output signal finished, cancelled
initial state Idle if start go to Job
state Job { initial state First if sheet do printed++ go to Second state Second if sheet do printed++ go to Done final state Done } if cancel do cancelled abort to Idle do finished join to Idle}finished and cancelled are signals: is each present in tick 4?
Inputs per tick. A value in grey was not set in that tick: it holds from an earlier one.
| Tick | start | sheet | cancel |
|---|---|---|---|
| 1 | false | false | false |
| 2 | true | false | false |
| 3 | false | true | false |
| 4 | false | true | true |
Explanation
printed is 1, finished is absent and cancelled is present. The strong cancel is decided before
anything inside Job reacts, so the second sheet of tick 4 is not counted, Job never reaches Done,
and the join cannot fire. In TwoPages, with its weak cancel, the inside counted that sheet first.
Show the answer
Answer C: The question does not arise: KIELER rejects the chart
Strong aborts must come before every weak abort and termination transition of the same state.
Written after a go to, the abort to makes KIELER reject the chart:
Causality problem!Strong abort transitions must have a higher priority than weak abort or termination transitions.Show the answer
Answer A: Nothing
A simple state has no inside, so there is nothing for a strong abort to skip: KIELER treats strong
aborts of simple states without actions as weak ones. With a during action the two would differ in
the leaving tick, as the next chapter shows.
Key ideas
- A transition written on a superstate is an abort: it can cut the inside short. A weak abort
(
go to) lets the inside finish its tick first; a strong abort (abort to) leaves before the inside moves. - Aborts are delayed unless written
immediate. A strong abort reads its trigger before the inside reacts, a weak abort after. - Transitions are tried in the order written, and strong aborts must come first. A join behaves like a weak abort; when a join and a weak abort both apply, the first written wins.
- On a simple state there is no inside to skip:
go toandabort tobehave alike unless the state has aduringaction.
Next, Entry, during and exit actions: effects that belong to a state, and which of them still run when the state is aborted.