Boost logo

Boost Users :

Subject: Re: [Boost-users] [MSM] stack overflow happens when there is a false-guard anonymous transition
From: Christophe Henry (christophe.j.henry_at_[hidden])
Date: 2010-09-06 14:54:07


Hi Michael,

It's always nice to hear from you and have an interesting UML
discussion with an expert!

> I hope you are well. You know how I like to dig into this stuff... so
> I'll give my thoughts. They are tainted by the the UML predecessor;
> however, I think there is good logic and possibly even a specification
> argument for my point of view.
>
> UML 2.2 Superstructure section 15.3.14 [Transition] provides the
> associations for:
>
> trigger : Trigger[0..*] -- I am assuming that no trigger is what
> you are referring to as
> an anonymous transition. I don't see
> that term used in current
> specifications anymore.
>
> guard: Constraint[0..1] -- "A guard is a constraint that provides
> a fine-grained control
> over the firing of the transition. The
> guard is evaluated
> when an event occurrence is dispatched
> by the state machine.
> If the guard is true at that time, the
> transition may be
> enabled; otherwise, it is disabled.
> Guards should be
> pure expressions without side effects.
> Guard expressions
> with side effects are ill formed."
>
>
> I would argue that the definition of the guard constraint requires that
> the transition is evaluated when an event is dispatched and is only
> evaluated once for that event. Because the transition is disabled if the
> guard evaluates false, then the transition cannot be evaluated again
> until another event is dispatched.

I think your interpretation makes sense. Agreed.

> I would also argue that the system is considered stable once evaluation
> of an event begins. Guards are not allowed to cause side effects;
> therefore, the 'state' of the system when evaluation begins should be
> the same as when evaluation has completed if no transition is taken.

Agreed again.

> Personally, the least surprising thing (imnsho) would be that:
>
> 1. event is dispatched
> 2. internal transitions are evaluated for current state
> 3. external transitions are evaluated for current state
> 4. hierarchy is followed up and 2/3 repeated
> 5. if top is reached without satisfying event ... an error has
> occurred and is acted upon as normal

This is what is implemented for all events except for what the
standard calls "Completion Events" (also called anonymous transitions
in an UML book from the Booch/Rumbaugh collection).

> I do not think whether a trigger is defined or not for a transition will
> affect this behavior. Transitions without a trigger are simply
> candidates for any event. The steps outlined above are those used for
> transitions with triggers, no?

I agree on the first part and disagree on the second. So, I took from
the standard:

"A completion transition is a transition originating from a state or
an exit point but which does not have an explicit trigger,
although it may have a guard defined. A completion transition is
implicitly triggered by a completion event. In case of a
leaf state, a completion event is generated once the entry actions and
the internal activities (“do” activities) have been
completed. If no actions or activities exist, the completion event is
generated upon entering the state. If the state is a
composite state or a submachine state, a completion event is generated
if either the submachine or the contained region
has reached a final state and the state’s internal activities have
been completed. This event is the implicit trigger for a
completion transition. The completion event is dispatched before any
other events in the pool and has no associated
parameters. For instance, a completion transition emanating from an
orthogonal composite state will be taken
automatically as soon as all the orthogonal regions have reached their
final state.
If multiple completion transitions are defined for a state, then they
should have mutually exclusive guard conditions."

So you are right and I should handle them like any other event. OTOH,
the standard does not see them as a candidate for any event but as an
implicit event which I have to trigger after the target state entry
behavior. If a transition without an explicit trigger (event) is
defined, it fires.
And I should generate it only once, thus avoiding the overflow.
What you suggest is a kind of an "any" take-all event, which I also
find a good idea (I do not remember seeing it in the standard, but a
good idea should be implemented if possible).

The part of the standard which I find unpracticable is, if the guard
rejects the completion event, how do we move out of this case? If I
follow the standard, we would need to reenter a state, which means we
would need a dummy event (not nice). This is why I suggest a
process_completion() which would simply resend a completion event.
Ok?

Thanks for your (as usual) helpful insights,

Christophe

PS: reading again, I see that there is another implementation error in
the current implementation, completion events have a lower priority
than the event queue, I will change this on the way too.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net