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: Kris (krzysztof_at_[hidden])
Date: 2016-02-04 05:45:14


On Wed, Feb 3, 2016 at 9:59 PM, Vicente Botet [via Boost] <
ml-node+s2283326n4683180h99_at_[hidden]> wrote:

> Le 03/02/2016 21:48, Kris a écrit :
>
> > On Wed, Feb 3, 2016 at 6:48 PM, Vicente Botet [via Boost] <
> > [hidden email] <http:///user/SendEmail.jtp?type=node&node=4683180&i=0>>
> 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.
>

I have seen it, thanks. Yea, local transitions are not supported currently
by msm-lite.
Are they supported by MSM? I haven't seen support for it there too. Anyway,
they are
not hard to implement. Do you have any important use case for them?

>
> 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)
>
>
Well, I have just followed MSM approach and '+' was used there and I was
fine with it.
Is there any reason why '+' is wrong and it should be replaced with '^'
instead?

> >>> 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)
>

I implemented action_nextstate, so please take a look.
It might be checked online HERE ->
http://melpon.org/wandbox/permlink/IMZUWJpiHDP62WEO

It's really easy to implement it, the basic idea below.

auto action_nextstate = [](auto... s) {
  std::tuple<decltype(s)...> states{s...};
  return [=](msm::sm<auto>& sm, auto const& evt, bool external_value) {
    action0();
    if (some_guard1(external_value)) {
      action1();
      sm.change_state(std::get<0>(states));
    } else {
      action2(evt);
      sm.change_state(std::get<1>(states));
    }
  };
};

I had to add `change_state` to the msm-lite as it doesn't support changing
states unless in testing mode.

template <class... TStates>
void change_state(const detail::state<TStates> &...) noexcept {
  decltype(current_state_) new_states = {aux::get_id<states_ids_t, 0,
TStates>()...};
  *current_state_ = *new_states;
}

I hope that helps.I do understand your concept, however I'm not sure
whether such approach
is the best, but, at least, it's easy to implement. I guess if you can
prove that this is a common
case and that performance might be gained using it then it's worth to
consider such practice in general.

>
> > 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.

Me neither, so again, please take a look into the example and experiment
with it (http://melpon.org/wandbox/permlink/IMZUWJpiHDP62WEO). It's
defo worth trying it out.

> > 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.
>

Probably is not as your idea is based on local and not external data. I
misunderstood your concept at first.

>
> Vicente
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>
> ------------------------------
> If you reply to this email, your message will be added to the discussion
> below:
>
> http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683180.html
> To unsubscribe from [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?, click here
> <http://boost.2283326.n4.nabble.com/template/NamlServlet.jtp?macro=unsubscribe_by_code&node=4683016&code=a3J6eXN6dG9mQGp1c2lhay5uZXR8NDY4MzAxNnwtMTY0MTkzNTIwMA==>
> .
> NAML
> <http://boost.2283326.n4.nabble.com/template/NamlServlet.jtp?macro=macro_viewer&id=instant_html%21nabble%3Aemail.naml&base=nabble.naml.namespaces.BasicNamespace-nabble.view.web.template.NabbleNamespace-nabble.view.web.template.NodeNamespace&breadcrumbs=notify_subscribers%21nabble%3Aemail.naml-instant_emails%21nabble%3Aemail.naml-send_instant_email%21nabble%3Aemail.naml>
>

--
View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-MSM-eUML-like-library-which-compiles-up-to-60x-quicker-whils-tp4683016p4683203.html
Sent from the Boost - Dev mailing list archive at Nabble.com.

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