Boost logo

Boost :

Subject: [boost] [msm] internal/external conflicting transitions
From: Christophe Henry (christophe.j.henry_at_[hidden])
Date: 2009-12-07 06:02:57


Hi Michael,

Looks like you are thoroughly testing MSM and I find it great :)

>The docs have a section on "Conflicting Transitions". It has
>two conflicts described:
>
>1. an event enables multiple transitions because
> multiple guards test valid,
>
>2. an internal and external transition are both enabled
>
>I see a clear definition for the behavior of #1 in the
>discussion; however, it is not clear that #2 will follow
>the same rule.

I was maybe unclear with "internal" so let's see if we can converge.
With internal, I mean internal to a composite. Suppose we have a fsm
named Top containing a state State and a composite Sub.
Top has a transition on Event from Sub to State. Sub has 2 states,
SubState1 and SubState2 and a transition on Event from SubState2 to
SubState1.
If the fsm is in the state Sub::SubState2 and Event is detected, we
now have a conflict between Sub->State and SubState2->SubState1.
UML defines this as a conflict and orders that SubState2->SubState1 wins.
It also surprised me a bit until I implemented exit points, which are
in themselves a conflict (they are defined as a connection between a
transition inside a composite and one outside, triggered by the same
event). So, if SubState1 were an exit point, it would still work.

>It was actually a little surprising to me that the order
<of the transition definitions affected #2. (Well, maybe
>not surprising ... but not what I wanted). I used
>the SimpleTutorial to test the behavior with:
>
> a_row < Stopped , play , Stopped , &p::test_conflict >,
> a_row < Stopped , play , Playing , &p::start_playback >,
> a_row < Stopped , open_close , Open , &p::open_drawer >,
>
>and
>
> a_row < Stopped , play , Playing , &p::start_playback >,
> a_row < Stopped , play , Stopped , &p::test_conflict >,
> a_row < Stopped , open_close , Open , &p::open_drawer >,
>
>
>The last transition defined "wins" in a conflict.

This is were I'm unsure if I follow you. SimpleTutorial has no
composite, so no internal transition so we must be talking about
different things.
I can, however, still answer about the order of evaluation.
UML orders that conflicts be solved by guards which are mutually
exclusive, so your machine is currently ill-formed (no guards) and UML
says the behavior is undefined and I, as implementer, am allowed to
punish you like I wish ;-)
Seriously, if you have guards and they are mutually exclusive, your
machine is correct and all will work as expected, no matter the order
of evaluation.

If you still want to know how it works, with pleasure (this is where
normal users could stop reading ;-) ).
First, for every event used inside a composite, MSM adds a forwarding
row at the end of your table (at the end, so they have no influence on
the state index calculation system).
Then, for a given event, MSM iterates at compile-time through the STT,
from back to front and replaces the conflicts by a new row containing
all of the conflicts (this is were your compiler suffers). Thus,
transitions internal to a composite are given higher priority in the
evaluation.
This also means that for "normal" conflicts, the last transition wins.
I was already asked if I would change it. It is
implementation-specific so you should not rely on it, but it is very
unlikely that I will ever want to change it.

I hope I brought enough elements to bring clarity. If not, please let me know.

Christophe


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk