Hi Nick,

1) You may consider unioning or intersecting talk_sm with a machine

( any | anytime_events )*

A union will prevent the talk_sm machine from ever failing, so intersection may be what you need.

2) The ragel equivalent is called conditions. Note I am currently re-implementing the condition feature for ragel 7. If you're using the master branch then conditions will be broken for a little while longer.

3) You can change the first transition of 'hungry' to

 put_food_in_mouth eating -> hungry |

where 'eating' is complete machine definition with start state and final states. The Final states of 'eating' will receive epsilon transitions to 'hungry'.

4) It's unimplemented. It requires passing any existing labels through the NFA -> DFA alg and adding them to the output.

Regards,
 Adrian

On 12-10-11 03:30 PM, Nick Parker wrote:
Hello, I'm on a project at work which has been using Boost's Meta State Machine 
(boost::msm) library in a couple places. A major downside for us is that our 
state machines are apparently quite large by boost::msm standards (on the order 
of 50-80 transitions), resulting in very resource intensive builds which need a 
couple minutes and several GB of ram to complete. Long story short, I figured 
this would be a good opportunity to learn Ragel. I've made pretty good progress 
in writing Ragelized versions of our current machines, but have encountered 
some corner cases where I wasn't able to think up an obvious Ragel equivalent 
to a boost::msm feature:


1) Let some events be considered valid during any state. In boost::msm, we've 
been handling this via a secondary orthogonal state[1] dedicated to handling 
those events, leaving the main state unchanged. The best Ragel equivalent I 
found was to do something like this, where a no-op submachine containing those 
events would be manually added to each state:

anytime_events = (
     e_sneeze @a_sneeze_from_any_to_same |
     e_laugh @a_laugh_from_any_to_same
);

talk_sm = (
     start: (
         e_hello @a_hello_from_start_to_hello             -> hello |
         e_goodbye @a_goodbye_from_start_to_final         -> final |
         anytime_events                                   -> start
     ),

     hello: (
         e_convo @a_convo_from_hello_to_conversation      -> conversation |
         e_nevermind @a_nevermind_from_hello_to_final     -> final |
         anytime_events                                   -> hello
     ),

     conversation: (
         e_talk @a_talk_from_conversation_to_conversation -> conversation |
         e_goodbye @a_goodbye_from_conversation_to_final  -> final |
         anytime_events                                   -> conversation
     )
);

This solution works fine and is also fairly intuitive, but it felt a little 
clunky adding this thing to every state. Is there a more direct alternative 
that I missed?


2) boost::msm has a feature called "Guards"[2], which are user-defined functions that get called 
before a transition completes and determine whether the transition should be aborted. Would a reasonable 
Ragel-based implementation of this be an action which calls "fgoto *fcurs" or similar when a 
condition fails? Assuming it's not too cumbersome to do so, it'd be nice if this could be done 
"natively" without the fgoto, if only so that the guard failure case appears as a transition in 
graphviz exports, but this isn't a big deal.


3) In one case, there's a heirarchical machine with submachines that 
effectively act as modes of operation within a larger state. The tricky part is 
that these submachines have multiple exit states into the parent machine, 
depending on what happened within the submachine. This feels like a common 
scenario, but I couldn't really think of a good equivalent in Ragel for this. 
Syntactically, I think it'd look something like this:

eat_sm = (
     start: (
         pick_up_fork -> hungry
     ),

     hungry: (
         put_food_in_mouth -> eating |
         die_of_starvation -> final
     ),

     not_hungry: (
         put_down_fork -> final
     ),

     eating: (
         start: [] -> chewing,

         chewing: (
             chew -> chewing |
             spit_out -> hungry | #exit to parent's "hungry" state
             swallow -> swallowing
         ),

         swallowing: (
             cough_up -> chewing |
             swallowed -> not_hungry #exit to parent's "not_hungry" state
         )
     )
)

The best solution I could think of was to move all the submachine content to 
the parent machine, which wouldn't be so bad in the above example. However, the 
real-world case I'm trying to solve has 4 of these submachines, each with 4-5 
states, so it'd start to look pretty messy if all of these were all merged into 
one big list, and the explicit partitioning of these modes into submachines 
would be nice to keep as well.


4) Unrelated to boost::msm: I've been making very good use of the graphviz 
export feature. One thing I've found to be missing is that the state circles 
are only labeled with a seemingly arbitrary integer (1,2,3,...) instead of the 
state label (state_x,state_y,state_z,...). As a result, I end up needing to go 
by the transition action labels to figure out which graphviz circles correspond 
to which states. This can rapidly get cumbersome when the machine is large. Is 
this a limitation of the dot file format itself or just an unimplemented 
feature in Ragel? I'm using Ragel 6.7 from Debian unstable, and xdot to view 
the graphviz output.


[1] "Submachines, orthogonal regions, pseudostates" 
http://www.boost.org/doc/libs/1_51_0/libs/msm/doc/HTML/ch02s02.html#d0e151
[2] "the guard is a Boolean operation executed [before the transition] which can 
prevent the transition from firing by returning false" 
www.boost.org/doc/libs/1_51_0/libs/msm/doc/HTML/ch02s02.html#d0e121

_______________________________________________
ragel-users mailing list
ragel-users@complang.org
http://www.complang.org/mailman/listinfo/ragel-users


_______________________________________________
ragel-users mailing list
ragel-users@complang.org
http://www.complang.org/mailman/listinfo/ragel-users

Reply via email to