W3C home > Mailing lists > Public > www-voice@w3.org > April to June 2017

Re: Grandparent <state> for <final>

From: Gavin Kistner <phrogz@me.com>
Date: Fri, 30 Jun 2017 20:45:17 +0000 (GMT)
To: Jim Barnett <1jhbarnett@gmail.com>
Cc: Stefan Radomski <radomski@tk.tu-darmstadt.de>, "www-voice@w3.org (www-voice@w3.org)" <www-voice@w3.org>
Message-id: <ec07a508-2423-438f-bec8-775d30c782dc@me.com>
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> 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> 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 20:45:56 UTC

This archive was generated by hypermail 2.3.1 : Friday, 30 June 2017 20:46:04 UTC