[msm]entry point pseudo states and events (Re: [msm] orthogonal region and event consume)

Hi Christophe, I changed the subject. Current topic isn't concerned with orthogonal region directly. On Thu, May 31, 2012 at 5:43 AM, Christophe Henry <christophe.j.henry@googlemail.com> wrote:
Hi Takatoshi,
I read your ticket. Note that it's not UML-conform to have 2 transitions originating from Entry1 (11-08-06.pdf §15.3.8 page 551). After reading the Standard again twice, I realized that no example provided there displays any event on both transitions, which is really bad if it's what they mean. I need to have a look at other literature.
I read the section that you mentioned carefully. My interpretation of UML specification is different from yours. It's really difficult to explain my interpretation. So, I draw the diagram. See the attached file. Am I misunderstanding?
I will not pretend I have the perfect understanding of the Standard. Here's my take. I also saw the sentence on top of your diagram and didn't fully understand it when reading the Standard. There is also the following sentence in the Standard:
"An entry pseudostate is used to join an external transition terminating on that entry point to an internal transition emanating from that entry point".
Which sounds logical because on your diagram the regions would not be orthogonal.
This means you cannot have transitions triggered by different events leading to the entry point, not can you have different transitions leaving it. You will need more entry points.
Caution: I am far from being sure I got it right. That's why I precised my definition of it in the doc. The implemented solution has the advantage that you have the normal transition handling, including multiple transitions and guards, events with data, base events, etc. What you don't have is entry in multiple regions, which only the fork currently provides, at the cost of lesser encapsulation. Correct or not, this is the part of the Standard I chose to implement pseudo entries.
To be honest, I'm not of fan of pseudo entries. I prefer the vastly superior solution of entering a submachine the "normal" way, then letting a templatized, enable_if'd on_entry of the submachine do something clever with the event at compile-time.
Aha! I completely overlooked such approach. For example, we can choose the initial state in submachine using mpl and initial_state typedef instead of using entry_pseudo_state. I believe that I've understood your design decisions. I also think that following the UML standard blindly is not essential.
My goal is to improve sub-machines' re-usability. If we want to reuse sub-machines in another state machines, sub-machines shouldn't know the outside information.
I agree but is it the case? I mean, if you send normal events to your submachine through your outer machine, it also needs to know them, right? I understand this as: "hi, I'm a submachine and I provide the following entry points: Entry1 requires Event1, Entry2 requires Event2, etc.". A bit like function parameters.
I wanted to explain that as follows: "hi, I'm a submachine and I provide the following entry points: Entry1 accepts any events. Because I don't care that. " Let me introduce more practical example that requires entry_pseudo_state. ScanFinger.png is a sub-machine. This sub-machine's primary purpose is to scan fingerprint. Before scanning, the sub-machine checks that finger is alive or not. But it's optional. To skip this check procedure, the entry point pseudo state ScanOnly is provided. FingerPrintRegister.png is the parent state machine. It uses ScanFinger as a sub-machine twice. In this scenario, alive checking is not required. So, the parent machine uses ScanOnly enty_pt. In another scenario, not mentioned here, might require the normal entry into ScanFinger to check the finger is alive. ScanFinger machine doesn't care about outer event. In FingerPrintRegister, the states RightScnning and LeftScanning have different incoming events for ScanOnly entry points. But any events are accepted. And then, it's not referred. Based on your suggestion, I introduce the base event class. As long as the incoming event of entry point is not "none", this approach works good. struct AnyEvent {}; struct Completed: public AnyEvent {}; struct StartButtonPressed: public AnyEvent {}; (See 39_FingerPrintExampleBaseEvent.cpp) If the incoming event is "none", the transition is stopped. Sometimes I want to use "none" as incoming event for entry point in the same sub-machine. And it is impossible that msm::front::none inherits user event classes such as AnyEvent. I'm trying to find better approach to solve the above problem. Thanks, Takatoshi
See my second mail in this thread. My solution using templates (entry_pseudo_event_template.cpp) requires the template parameters same as the number of entry point pseudo states in sub-machine. It's acceptable but if outgoing transition would be able to use none, I would remove the template parameters.
In the above case, it is not required to support multiple incoming transitions to one entry pseudo state. Because the instances of sub-machine are different.
In this case, maybe I could interest you in defining a base event class for Event1 and Event2, then making this base event the event triggering the inside transition. Your first example would be changed this way:
struct BaseEvent {}; struct Event1: public BaseEvent {}; ... msmf::Row < Entry1, BaseEvent, State2_2, msmf::none, msmf::none >
Regards, Christophe
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Hello Christophe, On Thu, May 31, 2012 at 3:44 PM, Takatoshi Kondo <redboltz@gmail.com> wrote:
Hi Christophe,
I changed the subject. Current topic isn't concerned with orthogonal region directly.
On Thu, May 31, 2012 at 5:43 AM, Christophe Henry <christophe.j.henry@googlemail.com> wrote:
Hi Takatoshi,
I read your ticket. Note that it's not UML-conform to have 2 transitions originating from Entry1 (11-08-06.pdf §15.3.8 page 551). After reading the Standard again twice, I realized that no example provided there displays any event on both transitions, which is really bad if it's what they mean. I need to have a look at other literature.
I read the section that you mentioned carefully. My interpretation of UML specification is different from yours. It's really difficult to explain my interpretation. So, I draw the diagram. See the attached file. Am I misunderstanding?
I will not pretend I have the perfect understanding of the Standard. Here's my take. I also saw the sentence on top of your diagram and didn't fully understand it when reading the Standard. There is also the following sentence in the Standard:
"An entry pseudostate is used to join an external transition terminating on that entry point to an internal transition emanating from that entry point".
Which sounds logical because on your diagram the regions would not be orthogonal.
This means you cannot have transitions triggered by different events leading to the entry point, not can you have different transitions leaving it. You will need more entry points.
Caution: I am far from being sure I got it right. That's why I precised my definition of it in the doc. The implemented solution has the advantage that you have the normal transition handling, including multiple transitions and guards, events with data, base events, etc. What you don't have is entry in multiple regions, which only the fork currently provides, at the cost of lesser encapsulation. Correct or not, this is the part of the Standard I chose to implement pseudo entries.
To be honest, I'm not of fan of pseudo entries. I prefer the vastly superior solution of entering a submachine the "normal" way, then letting a templatized, enable_if'd on_entry of the submachine do something clever with the event at compile-time.
Aha! I completely overlooked such approach. For example, we can choose the initial state in submachine using mpl and initial_state typedef instead of using entry_pseudo_state. I believe that I've understood your design decisions. I also think that following the UML standard blindly is not essential.
My goal is to improve sub-machines' re-usability. If we want to reuse sub-machines in another state machines, sub-machines shouldn't know the outside information.
I agree but is it the case? I mean, if you send normal events to your submachine through your outer machine, it also needs to know them, right? I understand this as: "hi, I'm a submachine and I provide the following entry points: Entry1 requires Event1, Entry2 requires Event2, etc.". A bit like function parameters.
I wanted to explain that as follows: "hi, I'm a submachine and I provide the following entry points: Entry1 accepts any events. Because I don't care that. "
Let me introduce more practical example that requires entry_pseudo_state. ScanFinger.png is a sub-machine. This sub-machine's primary purpose is to scan fingerprint. Before scanning, the sub-machine checks that finger is alive or not. But it's optional. To skip this check procedure, the entry point pseudo state ScanOnly is provided.
FingerPrintRegister.png is the parent state machine. It uses ScanFinger as a sub-machine twice. In this scenario, alive checking is not required. So, the parent machine uses ScanOnly enty_pt. In another scenario, not mentioned here, might require the normal entry into ScanFinger to check the finger is alive.
ScanFinger machine doesn't care about outer event. In FingerPrintRegister, the states RightScnning and LeftScanning have different incoming events for ScanOnly entry points. But any events are accepted. And then, it's not referred.
Based on your suggestion, I introduce the base event class. As long as the incoming event of entry point is not "none", this approach works good.
struct AnyEvent {}; struct Completed: public AnyEvent {}; struct StartButtonPressed: public AnyEvent {}; (See 39_FingerPrintExampleBaseEvent.cpp)
If the incoming event is "none", the transition is stopped. Sometimes I want to use "none" as incoming event for entry point in the same sub-machine. And it is impossible that msm::front::none inherits user event classes such as AnyEvent.
I'm trying to find better approach to solve the above problem.
I realized that I should use explicit_entry instead of entry_pseudo_state. UML's entry point pseudo states should be mapped into msm::front::explicit_entry. For example, entry point pseudo state Entry1 in ScanFinger should be mapped struct Entry1:msmf::state<>, msmf::explicit_entry<> {}; not struct Entry1:msmf::entry_pseudo_state<> {}; There is no restriction that relates to Entry1's outgoing event :) I forgot to rename Entry1 to ScanOnly. Please consider that they are same. IMHO, the semantics of UML's entry point pseudo state look more like Boost.Msm's explicit_entry than entry_pseudo_state. I believe that I found the best solution of my problem. Thanks, Takatoshi
Thanks, Takatoshi
See my second mail in this thread. My solution using templates (entry_pseudo_event_template.cpp) requires the template parameters same as the number of entry point pseudo states in sub-machine. It's acceptable but if outgoing transition would be able to use none, I would remove the template parameters.
In the above case, it is not required to support multiple incoming transitions to one entry pseudo state. Because the instances of sub-machine are different.
In this case, maybe I could interest you in defining a base event class for Event1 and Event2, then making this base event the event triggering the inside transition. Your first example would be changed this way:
struct BaseEvent {}; struct Event1: public BaseEvent {}; ... msmf::Row < Entry1, BaseEvent, State2_2, msmf::none, msmf::none >
Regards, Christophe
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Hi Takatoshi,
I wanted to explain that as follows: "hi, I'm a submachine and I provide the following entry points: Entry1 accepts any events. Because I don't care that. "
Let me introduce more practical example that requires entry_pseudo_state. ScanFinger.png is a sub-machine. This sub-machine's primary purpose is to scan fingerprint. Before scanning, the sub-machine checks that finger is alive or not. But it's optional. To skip this check procedure, the entry point pseudo state ScanOnly is provided.
FingerPrintRegister.png is the parent state machine. It uses ScanFinger as a sub-machine twice. In this scenario, alive checking is not required. So, the parent machine uses ScanOnly enty_pt. In another scenario, not mentioned here, might require the normal entry into ScanFinger to check the finger is alive.
ScanFinger machine doesn't care about outer event. In FingerPrintRegister, the states RightScnning and LeftScanning have different incoming events for ScanOnly entry points. But any events are accepted. And then, it's not referred.
Based on your suggestion, I introduce the base event class. As long as the incoming event of entry point is not "none", this approach works good.
struct AnyEvent {}; struct Completed: public AnyEvent {}; struct StartButtonPressed: public AnyEvent {}; (See 39_FingerPrintExampleBaseEvent.cpp)
If the incoming event is "none", the transition is stopped. Sometimes I want to use "none" as incoming event for entry point in the same sub-machine. And it is impossible that msm::front::none inherits user event classes such as AnyEvent.
I'm trying to find better approach to solve the above problem.
I realized that I should use explicit_entry instead of entry_pseudo_state. UML's entry point pseudo states should be mapped into msm::front::explicit_entry.
For example, entry point pseudo state Entry1 in ScanFinger should be mapped struct Entry1:msmf::state<>, msmf::explicit_entry<> {}; not struct Entry1:msmf::entry_pseudo_state<> {};
There is no restriction that relates to Entry1's outgoing event :)
I forgot to rename Entry1 to ScanOnly. Please consider that they are same.
IMHO, the semantics of UML's entry point pseudo state look more like Boost.Msm's explicit_entry than entry_pseudo_state.
I believe that I found the best solution of my problem.
Thanks, Takatoshi
Please, no! Not the explicit entry ;-) This is the feature I'm the least proud of... Actually, it's funny, we got the same idea. We need the concept of an "any" event. Some people called it kleen during the review. I have a solution which looks very promising, I need to polish it before I can commit. There will now be an any event, which will match whatever event is processed. Note that this is not "none", which has a different behavior. I thought a bit last night after our last discussion and I come to such a transition in your first example: ====> msmf::Row < Entry1 , boost::any, State2_2 , ExecuteEntry, msmf::none > Not that the event now is boost::any. And it matches your Event1 of course. This way you get the same effect as your none and I keep my event data as I can any_cast (note to self, also plan to support Steven's new pimped any. Name suggestion: boost::pimped_any :) ). The added advantage is that this will apply to all of MSM's transitions, not just pseudo entries. Would this be an agreeable solution to you? Regards, Christophe

Hi Takatoshi,
I thought a bit last night after our last discussion and I come to such a transition in your first example:
====> msmf::Row < Entry1 , boost::any, State2_2 , ExecuteEntry, msmf::none >
Not that the event now is boost::any. And it matches your Event1 of course. This way you get the same effect as your none and I keep my event data as I can any_cast (note to self, also plan to support Steven's new pimped any. Name suggestion: boost::pimped_any :) ).
The added advantage is that this will apply to all of MSM's transitions, not just pseudo entries.
I just committed a version where this is implemented (trunk rev. 78785). You can play with it and see if it solves your problem. I'm pretty confident it will work, but I need to make more tests and update the doc (but it's getting late). For non-eUML front-ends, boost::any is now an acceptable event, for eUML I added an event named "kleene" behaving like a boost::any. With both, the original event is saved in the boost::any, which allows you some more entertaining guards or actions ;-) HTH, Christophe

Hi Christophe, Thank you for your effort and commit. I am really impressed at your brilliant solution! I modified my example using the new any supports. See 41_FingerPrintExampleAnyEvent.cpp It works perfectly. As you mentioned, your solution not only improves the sub-machines' reusability but also provides access to events. This is something that I really want to. Let me clarify my understanding. msm::front::none is a completion_event. A transition that corresponds to completion_event can be processed without trigger events. Kleene event is not a completion_event. Therefore, it is not invoked without trigger events, but any events are accepted as a trigger. Furthermore, the trigger event is preserved as boost::any. By the way, I'm writing the guideline for UML modelers. My goal is to describe how to implement Each UML element into Boost.Msm. Maybe I talked about it last year. And it is coming along some extent now. http://redboltz.wikidot.com/boost-msm-guide Thanks, Takatoshi On Fri, Jun 1, 2012 at 6:17 AM, Christophe Henry <christophe.j.henry@googlemail.com> wrote:
Hi Takatoshi,
I thought a bit last night after our last discussion and I come to such a transition in your first example:
====> msmf::Row < Entry1 , boost::any, State2_2 , ExecuteEntry, msmf::none >
Not that the event now is boost::any. And it matches your Event1 of course. This way you get the same effect as your none and I keep my event data as I can any_cast (note to self, also plan to support Steven's new pimped any. Name suggestion: boost::pimped_any :) ).
The added advantage is that this will apply to all of MSM's transitions, not just pseudo entries.
I just committed a version where this is implemented (trunk rev. 78785). You can play with it and see if it solves your problem. I'm pretty confident it will work, but I need to make more tests and update the doc (but it's getting late).
For non-eUML front-ends, boost::any is now an acceptable event, for eUML I added an event named "kleene" behaving like a boost::any. With both, the original event is saved in the boost::any, which allows you some more entertaining guards or actions ;-)
HTH,
Christophe
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Hi Takatoshi,
Thank you for your effort and commit. I am really impressed at your brilliant solution! I modified my example using the new any supports. See 41_FingerPrintExampleAnyEvent.cpp
Ah yes, there is even some enable_if! Now this looks like C++ ;-)
It works perfectly.
Good! :)
As you mentioned, your solution not only improves the sub-machines' reusability but also provides access to events. This is something that I really want to.
And can be used in every context, not just with submachines. Furthermore, the mechanism is easily extendable to be used with another any than Boost.Any (like, say, TypeErasure). Looks like our discussion was useful :)
Let me clarify my understanding. msm::front::none is a completion_event. A transition that corresponds to completion_event can be processed without trigger events. Kleene event is not a completion_event. Therefore, it is not invoked without trigger events, but any events are accepted as a trigger. Furthermore, the trigger event is preserved as boost::any.
Yes you got it. A completion event happens immediately, without a call to process_event. A Kleene is an event which matches any event. So, without a call to process_event, nothing happens. I named it kleene so that people familiar with regex see more easily what it is.
By the way, I'm writing the guideline for UML modelers. My goal is to describe how to implement Each UML element into Boost.Msm. Maybe I talked about it last year. And it is coming along some extent now. http://redboltz.wikidot.com/boost-msm-guide
Ah yes, I saw it some time ago, but now it's much more complete. Do you mind if I point to it in the doc? Do you plan to do the same with eUML? Regards, Christophe

Hi Christophe, On Sat, Jun 2, 2012 at 4:17 AM, Christophe Henry <christophe.j.henry@googlemail.com> wrote:
Hi Takatoshi,
Thank you for your effort and commit. I am really impressed at your brilliant solution! I modified my example using the new any supports. See 41_FingerPrintExampleAnyEvent.cpp
Ah yes, there is even some enable_if! Now this looks like C++ ;-)
It works perfectly.
Good! :)
As you mentioned, your solution not only improves the sub-machines' reusability but also provides access to events. This is something that I really want to.
And can be used in every context, not just with submachines. Furthermore, the mechanism is easily extendable to be used with another any than Boost.Any (like, say, TypeErasure). Looks like our discussion was useful :)
Exactly. I think that Boost.Msm and type erasure mechanism are good combination.
Let me clarify my understanding. msm::front::none is a completion_event. A transition that corresponds to completion_event can be processed without trigger events. Kleene event is not a completion_event. Therefore, it is not invoked without trigger events, but any events are accepted as a trigger. Furthermore, the trigger event is preserved as boost::any.
Yes you got it. A completion event happens immediately, without a call to process_event. A Kleene is an event which matches any event. So, without a call to process_event, nothing happens. I named it kleene so that people familiar with regex see more easily what it is.
By the way, I'm writing the guideline for UML modelers. My goal is to describe how to implement Each UML element into Boost.Msm. Maybe I talked about it last year. And it is coming along some extent now. http://redboltz.wikidot.com/boost-msm-guide
Ah yes, I saw it some time ago, but now it's much more complete. Do you mind if I point to it in the doc?
Of course not. I would appreciate it, if you would do that.
Do you plan to do the same with eUML?
Yes. But first, I will write about several topics such as orthogonal regions and information propagation approach between sub-machine and parent machine on functor front-end. And then I will start to write about eUML. Thanks, Takatoshi
Regards,
Christophe
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (2)
-
Christophe Henry
-
Takatoshi Kondo