From: Darryl Green (darryl.green_at_[hidden])
Date: 2004-05-30 03:54:42
Andreas Huber <ah2003 <at> gmx.net> writes:
> Darryl Green wrote:
> > It seems that this whole business of having an FSM that has
> > meta-states in which no state exists (ok, you call them unstable
> > states and an outer state, or possibly the FSM itself, always exists,
> > but the outer state isn't really part of the simple state machine) is
> > a LEM violation that just makes things complicated.
> What does LEM stand for?
Law of Excluded Middle. A proposition must be true or false.
A FSM is always in exactly one state.
A FSM has a finite number of states.
If an FSM is not in some state A then it must be in some other state.
However, I've thought about this some more, and if we consider the simple,
formal state machine alone, your model doesn't have a problem - because the
transition is a transitory thing that makes no reference to the states
themselves. The "gap" where the machine is in no state doesn't matter if it
indivisible and unable to directly influence the fsm behaviour. The only
influence possible on the fsm behaviour is when an exception is thrown during
the transition, which destructs (if there is anything left to destruct) the
inner fsm, making this behaviour outside what can be modeled directly as a fsm,
and this reasoning irrelevant.
> Do you suggest that a state that has been left must somehow still
> exist? If so, why?
I was trying to say that there must be no period during which the FSM is in no
state. It depends what the definition of "left" is. Aside from my (misguided I
suspect) attempts at a theoretical argument, this is because I would like to
utilise the RAII aspects of your state model in a way that requires the
transition action to have access to the context of the state "in the process of
being left". I'm arguing for the following definition of left:
A state is considered left (and hence is destructed) only after exit and
transition actions have run.
That is, the previous state is destructed immediately before the new state is
constructed. For nested states, all exit actions would run, followed by the
transition action, followed by destruction of the states being left, followed
by construction of the new state(s).
> I don't see what that would buy you.
Well it buys access to the state being left from the transition action for a
start. In addition, if the exit action isn't the destructor, and it fails, you
are still in the original state. A state specific recovery action is possible,
using the state's own context. The state destructor still must not fail.
> > That said,
> > one suspects the "can't acquire resources to enter state" exception
> > is really one which dooms at least the inner fsm,
> Right, it does doom the inner FSM, but why should that be a problem?
It isn't. It is just a supporting argument for destructing the state being left
no later than immediately prior to destination state construction, and for
allowing construction/entry to fail.
> I often find myself needing to handle a failure that happens in a "bunch of
> states", no matter where the failure actually occurs (failing entry action,
> failing transition action). In such a situation I put all these states into
> an outer state and implement an exception_thrown transition from the outer
> state. This might seem like an arbitrary decision, but more often than not I
> discover that the "bunch of states" already resides in an outer state for
> logical reasons, so I just have to implement the exception_thrown transition
> from there.
> > This change would also allow an action's context be to be the source
> > state - or would there still be some problem with that? Does the
> > context really have to be an outer state of the destination as well
> > as the source?
I answered my own question in another post (thread got lost somehow though):
If transitions actually occur before destructors run as per my proposal, then
the source state itself, and all its outer state contexts exist so the
restriction of only common outer contexts being available is removed.
> Yes, I very much believe so. The UML standard and all the code generators
> I've seen define/implement it this way (i.e. all exit actions are executed
> before the transition action is executed).
I don't read the concepts of context and states with context/resources/state
local storage into the UML standard. I think these things are pure extensions,
and potentially quite valuable ones. They address practical implementation
issues for fsms in C++. I think they are separate, but interact with, the UML
concepts of exit, transition and entry actions, which I agree run in that order.
My specific concern is the use of the extended functionality to produce states
which have/build significant context that (should) only exist until a
transition action deals with it. I don't see that using this state context
after the exit action has run is a problem. The exit action may well have added
to or modified it to make the context complete, not damaged (and in particular
not destructed) it.
I'm also concerned that the current fsm destruction/exit action implementation
model results in an environment where I should avoid using exit actions that
have any significant external effects because I don't want/expect them to be
run when/if the fsm is destructed.
Both the above concerns can be addressed by using custom reactions to
implement "pre-exit" actions when/if this turns out to be necessary. I'll have
to use the fsm library some more to see if this turns out to be the case
regularly enough to make it a significant use case.
So, I now believe that the library has the necessary flexibility, and only
experience will tell how much and in what direction that flexibility gets
used/stretched. I'll keep you posted...
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk