- From: Jim Barnett <1jhbarnett@gmail.com>
- Date: Fri, 30 Jun 2017 17:22:19 -0400
- To: Gavin Kistner <phrogz@me.com>
- Cc: Stefan Radomski <radomski@tk.tu-darmstadt.de>, "www-voice@w3.org (www-voice@w3.org)" <www-voice@w3.org>
- Message-ID: <17931d80-95cb-8de2-d68f-3168652aaf6d@gmail.com>
I don't think that the behavior you describe is a bug. The domain of a transition is the compound state that is the least common ancestor of the transition's source state (p0_s0 in this case) and the set of its target states, and we exit all of the domain's active descendents. (See computeExitSet, getTransitionDomain, and findLCCA in the pseudo-code.) The parallel state p0 is a common ancestor of the source and target states of your transition, but it doesn't count as the domain because it is not a compound state (or the <scxml> element.) So taking an external transition whose source state is a child of <parallel> will cause the <parallel> element to be exited and re-entered. We reached this conclusion after a lot of discussion, so it really is the behavior that the group wanted. - Jim On 6/30/2017 4:45 PM, Gavin Kistner wrote: > FWIW, the state machine as I wrote it does not work in LXSC, as the > transitions default to "external", and exiting and re-entering causes > the compound states to reset, which causes an unending chain of fun > events and transitions. > > (It smells like this may be a bug in LXSC...should an 'external' > transition that is a child of p0_s0 with a target that is also a child > of p0_s0 cause the state machine to exit and re-enter not only p0_s0, > but the entire parallel p0? I think no?) > > Regardless, either of the following work as intended in LXSC, > finishing in the 'pass' state. > > <scxml xmlns="http://www.w3.org/2005/07/scxml"> > <parallel id="p0"> > <transition event="done.state.p0" target="pass" /> > <state id="p0_s0"> > <state id="p0_s0_s0"> > <final id="p0_s0_s0_f0"/> > <transition event="done.state.p0_s0_s0" target="p0_s0_f0"/> > </state> > <final id="p0_s0_f0"/> > </state> > <state id="p0_s1"> > <state id="p0_s1_s0"> > <final id="p0_s1_s0_f0"/> > <transition event="done.state.p0_s1_s0" target="p0_s1_f0"/> > </state> > <final id="p0_s1_f0"/> > </state> > </parallel> > <final id="pass"/> > </scxml> > > <scxml xmlns="http://www.w3.org/2005/07/scxml"> > <parallel id="p0"> > <transition event="done.state.p0" target="pass" /> > <state id="p0_s0"> > <state id="p0_s0_s0"><final id="p0_s0_s0_f0"/></state> > <final id="p0_s0_f0"/> > <transition event="done.state.p0_s0_s0" target="p0_s0_f0" > type="internal"/> > </state> > <state id="p0_s1"> > <state id="p0_s1_s0"><final id="p0_s1_s0_f0"/></state> > <final id="p0_s1_f0"/> > <transition event="done.state.p0_s1_s0" target="p0_s1_f0" > type="internal"/> > </state> > </parallel> > <final id="pass"/> > </scxml> > > -- > (-, /\ \/ / /\/ > > On Jun 30, 2017, at 01:25 PM, Jim Barnett <1jhbarnett@gmail.com> wrote: > >> Yes. You must have <final> substates in all the child states. >> >> >> On 6/30/2017 2:29 PM, Gavin Kistner wrote: >>>> Our users employ the extended semantic to transition into a >>>> "joined" state when all compounds in a parallel are finished. How >>>> would I express a corresponding semantic then? >>> >>> I would think they would need to add additional <final> states to >>> the children of the parallel, and be sure to transition to them when >>> the grandchild states completed. Like so: >>> >>> <scxml> >>> <parallel id="p0"> >>> <transition event="done.state.p0" target="p0_all_joined" /> >>> <state id="p0_s0"> >>> <state id="p0_s0_s0"><final id="p0_s0_s0_f0"/></state> >>> <final id="p0_s0_f0"/> >>> <transition event="done.state.p0_s0_s0" target="p0_s0_f0"/> >>> </state> >>> <state id="p0_s1"> >>> <state id="p0_s1_s0"><final id="p0_s1_s0_f0"/></state> >>> <final id="p0_s1_f0"/> >>> <transition event="done.state.p0_s1_s0" target="p0_s1_f0"/> >>> </state> >>> </parallel> >>> <state id="p0_all_joined"> >>> <onentry><log expr="'all compound childs of p0 are >>> finished'"/></onentry> >>> </state> >>> </scxml> >>> -- >>> (-, /\ \/ / /\/ >>> >>> On Jun 30, 2017, at 02:09 AM, Stefan Radomski >>> <radomski@tk.tu-darmstadt.de> wrote: >>> >>>> >>>>> On Jun 29, 2017, at 15:25, Jim Barnett <1jhbarnett@gmail.com >>>>> <mailto:1jhbarnett@gmail.com>> wrote: >>>>> >>>>> Stefan, >>>>> >>>>> What you are proposing is simply a different definition of being >>>>> in a final state than the one the group used. Your definition is >>>>> a reasonable alternative, and if there ever is another version of >>>>> SCXML we will consider it. However this is not an erratum. >>>>> Specifically: >>>>> >>>>> 1) The current definition is the one the group explicitly >>>>> chose/voted for. >>>>> >>>>> 2) The current definition does not cause any inconsistencies in >>>>> the spec. >>>>> >>>>> When the group was still working, we kept an issues list for >>>>> proposals to be considered in a future version of the spec. >>>>> That's where your definition would go. Now that the Voice Browser >>>>> Group is closed, I don't know if there will ever be another >>>>> version, but it is too late to make changes to SCXML 1.0. >>>>> >>>> That's ok, it just seems strangely specific that a grandchildren >>>> final state of a parallel should have a different semantic with >>>> regard to "done.state.p" than any other descendant final state. I >>>> mean, what if the other compound children are not yet in a finished >>>> state? Allowing one compound to cause the parent parallel to >>>> trigger "done.state.p" seems premature with regard to the intuition >>>> of the parallel "being done". >>>> >>>> Our users employ the extended semantic to transition into a >>>> "joined" state when all compounds in a parallel are finished. How >>>> would I express a corresponding semantic then? I could go for a >>>> bunch of "In()" predicate calls but that would require awareness of >>>> all other compound children of the parallel state. >>>> >>>> <scxml> >>>> <parallel id="p0"> >>>> <transition event="done.state.p0" target="p0_all_joined" /> >>>> <state id="p0_s0"> >>>> <state id="p0_s0_s0"><final id="p0_s0_s0_f0"/></state> >>>> </state> >>>> <state id="p0_s1"> >>>> <state id="p0_s1_s0"><final id="p0_s1_s0_f0"/></state> >>>> </state> >>>> </parallel> >>>> <state id="p0_all_joined"> >>>> <onentry><log expr="'all compound childs of p0 are >>>> finished'"/></onentry> >>>> </state> >>>> </scxml> >>>> >>>> >>>> But I agree that it is obviously too late to complain. >>>> Stefan >>>>> >>>>> - Jim >>>>> >>>>> >>>>> On 6/29/2017 3:29 AM, Stefan Radomski wrote: >>>>>> >>>>>>> On Jun 29, 2017, at 01:05, Jim Barnett <1jhbarnett@gmail.com >>>>>>> <mailto:1jhbarnett@gmail.com>> wrote: >>>>>>> >>>>>>> Interesting case. I'm pretty sure that: >>>>>>> >>>>>>> 1) The current language was what the group wanted (i.e., it's >>>>>>> not an error) >>>>>>> >>>>>>> 2) We never discussed this case. >>>>>>> >>>>>>> However, to expand a bit further: suppose we add a <final> >>>>>>> child to state p0_s0 (i.e. a sibling state to p0_s0_s0). In >>>>>>> that case we wouldn't want entering p0_s0_s0_f0 to put the >>>>>>> parent p0_s0 in a final state - only entering its direct <final> >>>>>>> child should do that. >>>>>>> >>>>>> Is that so? I'd say if every active atomic state in the children >>>>>> of a parallel is final, then the parallel is done. Regardless of >>>>>> where those final states are in the hierarchy. >>>>>>> >>>>>>> The current language forces authors to be explicit about final >>>>>>> states, and is easy to understand, but in examples like yours it >>>>>>> can lead to somewhat counter-intuitive results. >>>>>>> >>>>>> In my opinion, it breaks encapsulation as you need to be aware of >>>>>> structures higher up the ancestry chain. >>>>>>> >>>>>>> If we try to get 'final-hood' to be inherited upward, but for >>>>>>> the inheritance to be blocked by the presence explicit >>>>>>> higher-level <final> states, the definition gets very complicated. >>>>>>> >>>>>> "After an interpreter enters a final state s, it checks whether >>>>>> any ancestor parallel state p of s has only final states left in >>>>>> the intersection between its atomic children and the active >>>>>> states. It raises `done.state.[p@id]` if that is the case." I >>>>>> don't see why a higher level <final> state should block the >>>>>> semantic at all - could you elaborate on that? >>>>>> >>>>>> Stefan >>>>>>> >>>>>>> - Jim >>>>>>> >>>>>>> >>>>>>> On 6/28/2017 6:10 PM, Gavin Kistner wrote: >>>>>>>> A couple years ago I wrote a Lua interpreter for SCXML[1]. >>>>>>>> Stefan R. just filed a bug with it[2]. At the core of the issue >>>>>>>> is whether the following SCXML parallel should be 'in a >>>>>>>> final/done state' after being entered: >>>>>>>> >>>>>>>> <parallel id="p0"> >>>>>>>> <state id="p0_s0"> >>>>>>>> <state id="p0_s0_s0"><final id="p0_s0_s0_f0"/></state> >>>>>>>> </state> >>>>>>>> <state id="p0_s1"> >>>>>>>> <state id="p0_s1_s0"><final id="p0_s1_s0_f0"/></state> >>>>>>>> </state> >>>>>>>> </parallel> >>>>>>>> >>>>>>>> My interpreter fires "done.state.p0_s0_s0" and >>>>>>>> "done.state.p0_s1_s0". However, it does not cause "p0_s0" or >>>>>>>> "p0_s1" to be considered in a final state, and therefore does >>>>>>>> not consider the parallel to be in a final state. >>>>>>>> >>>>>>>> On the one hand, this clearly looks like a bug in my >>>>>>>> interpreter against how I would *expect* the specifications to >>>>>>>> handle this situation. On the other hand, the >>>>>>>> specifications+errata only appear to cover situations where a >>>>>>>> <parallel> is exactly a *grandparent* of the <final>, not any >>>>>>>> further ancestor. >>>>>>>> >>>>>>>> Section 3.7 of the spec says: >>>>>>>> >>>>>>>> "When the state machine enters the <final> child of a <state> >>>>>>>> element […] generate the event done.state.id [...] where id is >>>>>>>> the id of the parent state. Immediately thereafter, if the >>>>>>>> parent <state> is a child of a <parallel> element, and all […] >>>>>>>> other children are also in final states […] generate the event >>>>>>>> done.state.id where id is the id of the <parallel> element." >>>>>>>> >>>>>>>> This only covers exactly the parent of the <final>, not any >>>>>>>> grandparent <state> or great-grandparent <parallel>. >>>>>>>> >>>>>>>> Further, the pseudo-code for Appendix D explicitly only handles >>>>>>>> one level at the end of enterStates(), and also only handles >>>>>>>> one level for the definition of isInFinalState(). >>>>>>>> >>>>>>>> >>>>>>>> If Stefan (and my) belief about how this should behave is >>>>>>>> correct, then (a) the prose in 3.7 needs to be modified via >>>>>>>> errata, and (b) the isInFinalState() pseudo-code should be >>>>>>>> modified to recurse, and (c) we need to discuss whether >>>>>>>> grandparent <state> also fire "done.state.xxx" events when >>>>>>>> their child state becomes in a final state, and if so, modify >>>>>>>> the pseudo-code in enterStates() to do so. >>>>>>>> >>>>>>>> If we're wrong—if grandparent states do not get this event >>>>>>>> fired, are not considered in a final state, and if the parallel >>>>>>>> in the example above should also not be in a final state—I'd be >>>>>>>> very interested to hear some arguments for this. >>>>>>>> >>>>>>>> [1] https://github.com/Phrogz/LXSC >>>>>>>> [2] https://github.com/Phrogz/LXSC/issues/1 >>>>>>>> >>>>>>>> -- >>>>>>>> (-, /\ \/ / /\/ >>>>>>> >>>>>> >>>>> >>>> >>
Received on Friday, 30 June 2017 21:22:56 UTC