Boost logo

Boost :

Subject: Re: [boost] [MSM] Is there any interest in C++14 Boost.MSM-eUML like library which compiles up to 60x quicker whilst being a slightly faster too?
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2016-02-03 17:23:10


Le 03/02/2016 21:48, Kris a écrit :
> On Wed, Feb 3, 2016 at 6:48 PM, Vicente Botet [via Boost] <
> ml-node+s2283326n4683171h20_at_[hidden]> wrote:
>
>> Le 02/02/2016 22:12, Krzysztof Jusiak a écrit :
>>
>>> On Tue, Feb 2, 2016 at 6:19 PM, Vicente J. Botet Escriba <
>>> [hidden email] <http:///user/SendEmail.jtp?type=node&node=4683171&i=0>>
>>>> Well these are already quite a few features. I have not see local
>>>> transitions (different from internal transitions).
>>> Yea interna(local) transitions are supported. Example here ->
>>>
>> http://boost-experimental.github.io/msm-lite/examples/index.html#transitions
>> Internal and local transitions are not the same. How do you make
>> syntactically the difference. I've not see and reference to local
>> transitions.
>>
>> Actually, I'm not sure what the difference is, sorry. I checked the UML2
> spec and there is no much
> about local transitions there. Bascially that, 'internal is a special case
> of a local Transition that is a self-transition'.
> Can you explain how it supose to work, please and what syntax would be
> preferable?
>
A local transition
(https://en.wikipedia.org/wiki/UML_state_machine#Local_versus_external_transitions)
form an outer state to itself exists from the most inner state but don't
exit from the outer state. If in addition the local transition goes to a
history state the inner state in re-entered.

An internal transition don't exits at all.

I have no preference for the notation, but why not replace the + sign
with a ^

src ^ event [guard] / action = src

src ^ event [guard] / action = src(H)

>>> Please could you point me if you support choice points?
>>>
> Actually msm-lite, since today, supports almost this syntax. There are
> pre/post fix notations available.
> src_state + event [guard] / action = dst_state
> or
> dst_state <= src_state + event [guard] / action
I know.
>
>
>> make_transition_table(
>> s0 + e / action0 -> cp
>> cp [some_guard1] / action1 -> s1
>> cp [else] / action2 -> s2
>> );
>>
>>
>> With action-next-state transition could be
>>
>> s0 + e / action_nextstate
>>
>> where action_nextstate is
>>
>> auto action_nextstate = [](auto const& evt) {
>> action0;
>> if (some_guard1) {
>> action1;
>> next_state(s1); // You could also return a state if there is a
>> type that can store any state of the state machine.
>> } else {
>> action2;
>> next_state(s2);
>> }
>> }
>>
>> Note that these action-nextstate could define some local variables in
>> action0 that can be used in some_guard1 and in action1 and action2 .
>>
>> The uml transition schema forces to store these local variable on the
>> state machine context (or a state context if supported), which is less
>> than optimal. This is needed because there is no way to share variables
>> between the action0, some_guard1 and in action1 and action2. In addition
>> action1 and action2 have no access to the event e, as only the action0
>> has it as parameter.
>>
>> Do you think that this kind of transitions goes against the UML semantics?
>>
> Hmm, interesting idea. However, it seems to be against the transition table
> concept a bit
> as guards are hidden in the actions instead. I do understand the concept
> tho, it's more
> like custom_reaction in the Boost.Statechart.
I'll take a look at. Yes, this can be seen as a drawback as less
visible, but performances are important in C++.
> I would still model it using
> transition table
> because it makes it more visible/clear to understand what is going on. With
> action_nexstate approach
> you have to check all actions to verify whether they are not changing the
> state which might
> be tricky to do. Unless, you have a solution for that?
One possibility is to return the next-state.

You could also restrict the possible next states in the table.

       s0 + e / action_nextstate(s1, s2)

>
> BTW. msm-lite has a bit different approach than MSM to share the data
> because guards/actions
> may share data as objects are injected into them when they are required.
> For example,
>
> auto action = [] {}; // action, not data, no event
> auto action_with_some_data = [] (int i, data& d) {}
> auto action_with_some_data_and_event = [] (int i, const auto & event, data&
> d) {} // order doesn't matter
>
> auto guard_with_data = [] (data& d, const auto& event) { return true; }
>
> make_transition_table(
> *s1 + e1 [ guard_with_data ] / action = s2
> , s2 + e2 / (action_with_some_data, action_with_some_data_and_event)
> );
>
> data d;
> sm fsm{d, 42}; // order doesn't matter, this data will be injected into
> guards/actions
Hmm, this will not reduce the size of the shared data. What I want is to
be able to use local data shared between transition segments. This local
could be encoded in the transition table, but I'm not sure it is worth
the effort.
> It's a bit tedious to pass all required objects into state machine
> constructor and therefore depenendy injection framework
> may become handy here, for example experimental boost.di ->
> https://github.com/boost-experimental/di
>
> More examples:
> http://boost-experimental.github.io/msm-lite/examples/index.html#actions-guards
> http://boost-experimental.github.io/msm-lite/examples/index.html#dependency-injection
>
>
I don't understand how this helps in this context.

Vicente


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