Thanks for your help!

1) Doesn't the intersection "(any | anytime_events)* & talk_sm" (with all 
anytime_events removed from talk_sm's states) just effectively result in 
"talk_sm" with no anytime_events at all? Tried the example against graphviz 
output. It also sorta makes sense when thought of as sets being 
unioned/intersected: (any | anytime_events) & talk_sm -> any & talk_sm -> 
talk_sm. Or am I misunderstanding what you meant?

2) Nice! I had apparently forgotten that section of the PDF.

3) The tricky thing is allowing the "eating" submachine to exit to either of 
the parent states "hungry" or "not_hungry", depending on whether the "eating" 
machine was internally successful. Or another way of putting it is that the 
eating submachine effectively has multiple final states which each map to a 
different state in the parent machine. Having said it this way makes me think 
it may indeed be easiest to just move/merge the submachine into the parent 
machine.

On Sat, Oct 13, 2012 at 02:30:40PM -0400, Adrian Thurston wrote:
> 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

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

Reply via email to