
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.
Ok.
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... Regards Darryl.