Re: Grandparent <state> for <final>

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