[BOOST][MSM] ¿Puede Guard ser una condición posterior a la acción, en lugar de una condición previa?

I am new to MSM, and also UML state machine standards as well. I had some state machine design before, using State Design Pattern, but this time I want to learn to use BOOST MSM, instead of cooking things up again.

One thing that really confused me a lot is the Guard. I want to do this, in State S1, I receive a event E1, then perform some Action A1, based on the result of action A1, I should either transit to new State S2, or stay in same state S1.

Using MSM, I cannot specify Guard G1 to be the result of Action A1, as in MSM's concept, G1 is the precondition whether A1 should be executed or not, rather than a result of executing A1.

Dos soluciones en las que puedo pensar son:

  1. Introduce a pseudo choice state, post_S1, where in its on_entry I perform the Action A1, and have a guard G1 testing the result of this action, then either go back to S1, or proceed to S2.

// Start Event Action Next Guard

S1 E1 none post_S1 none
post_S1 none none S2 G1
post_S1 none none S1 G1'(which is reverse of G1)


Move Action A1 code to Guard G1 (Afterall, A1 is a function call, which I can make it return boolean). so basically my transition row would be

// Start Event Action Next Guard

S1 E1 none S2 G1=A1

Am I using MSM right? Is there any better practice for solving this problem? In my application, I would have A LOT of these pseudo choice states, which I really tries to avoid.

Thanks! Zongjun

preguntado el 27 de noviembre de 13 a las 01:11

2 Respuestas

This is what the UML Standard defines, guards are preconditions.

You have several ways to your goal, my personal taste in this case would be:

  • Within State S1, add an internal transition on event E1.
  • This transition would have A1 as an action. Within A1, execute the action, then check the result.
  • If result means "stay where you are", stop
  • Else call (still within A1) fsm.template process_event(E2); where E2 is a new event moving you to S2.

I suggest this way because it will save you some compile-time, states are expensive ;-)

This is the easiest way. Again, there are others, like using eUML to make A1 return a result, then adding a if_ in the transition table, but this is much more advanced.

HTH, Christophe

respondido 27 nov., 13:20

Thanks Chrisophe! This is a good solution in itself, where we are not sacrificing speed in the sense that a synchronous event E1 needs to be delayed. However in our overall architecture, we have a central dispatcher, and we don't want the dispatching (fsm.template process_event) to be spreaded everywhere. The solution I have is to have a Guard G1 be the result of Action A1, while leaving A1 to be "none" in the transition table.I posted the answer also. - Zongjun

// Start Event Action Next Guard
S1 E1 none S2 Result_of_A1
Inside the Guard function itself, we are performing the action A1, then returning True or False based on A1's result. This way, if guard is false, then stay in S1; otherwise, move to S2.

This saves the pseudo choice state, which is useful but if there are a lot of states where its transition to next state is a "post condition" rather than "pre condition", then there will be lots of these pseudo choice states inside the transition table. Compared to the above transition table, it is more messy.

Respondido el 04 de diciembre de 13 a las 20:12

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.