RE: Preemption and test403c

Stefan,
  We have tweaked the definition since UML is quite clear that transitions in descendents preempt transitions in ancestors.  The updated language is:

In order to resovle conflicts between transitions, we assign priorities to transitions as follows: let transitions T1 and T2 conflict, where T1 is optimally enabled in atomic state S1, and T2 is optimally enabled in atomic state S2, where S1 and S2 are both active. We say that T1 has a higher priority than T2 if a) T1's source state is a descendent of T2's source state, or b) S1 precedes S2 in document order.

In the case you're referring to, the transition to s1 in p0s3 preempts the one that p0s2 inherits from S0, because S0 is an ancestor of p0s3.

There's also a practical reason for this change.  As Johan pointed out, if you're working on a large, complex state machine, you don't have to worry about a transition inherited from high up in the machine blocking a transition in the deeply nested parallel region you're working on.  It makes the state machine more locally intelligible, so to speak.


-          Jim

From: Stefan Radomski [mailto:radomski@tk.informatik.tu-darmstadt.de]
Sent: Thursday, April 04, 2013 11:16 AM
To: www-voice@w3.org (www-voice@w3.org)
Subject: Preemption and test403c

Hi there,

there has been much back and forth with regard to preemption, but as far as I understand it, if two transitions have conflicting exit sets, we basically take the first one in document order? If that's the case, then I cannot see how test403c is supposed to pass (excerpt):

<state id="s0" initial="p0">
<onentry>
<raise event="event1"/>
<send event="timeout" delay="100s"/>
</onentry>
<transition event="event2" target="fail"/>
<transition event="timeout" target="fail"/>

<parallel id="p0">
<state id="p0s1">
<transition event="event1"/>
<transition event="event2"/>
</state>
<state id="p0s2">
<transition event="event1" target="p0s1">
<raise event="event2"/>
</transition>
</state>
<state id="p0s3">
<!-- this transition should be blocked by the one in p0s2-->
<transition event="event1" target="fail"/>
<!-- this transition will preempt the one that p0s2 inherits from an ancestor  -->
<transition event="event2" target="s1"/>
</state>
<state id="p0s4">
<!-- this transition never gets preempted, should fire twice -->
<transition event="*">
<assign location="Var1" expr="Var1 + 1"/>
</transition>
</state>
</parallel>
</state>

At some point after event1 was processed and our configuration is {s0, p0 p0s1, p0s2, p0s3, p0s4} and event2 was raised. I cannot see how the transition to s1 in p0s3 is supposed to preempt the one to fail in s0.

<transition event="event2" target="fail"/> and <transition event="event2" target="s1"/> clearly have conflicting exit sets, but still the transition to fail comes first in document order. What am I missing here? I'd appreciate it, if it can be solved with the functionality described in the current draft 6 as I just want to get the tests working for now.

Relevant pseudocode is:

function selectTransitions(event):

    enabledTransitions = new OrderedSet()

    atomicStates = configuration.toList().filter(isAtomicState).sort(documentOrder)

    for state in atomicStates:

        loop: for s in [state].append(getProperAncestors(state, null)):

            for t in s.transition:

                if t.event and nameMatch(t.event, event.name) and conditionMatch(t):

                    enabledTransitions.add(t)

                    break loop

    enabledTransitions = filterPreempted(enabledTransitions)

    return enabledTransitions

This will iterate the basic configuration in document order and walk up each ancestor chain until there is a transition to add:

p0s1: already has a matching transition <transition event="event2"/>
p0s2: first matching transition is the one to fail in s0
p0s3: already has a matching transition to s1, which is the one we want
p0s4: already has a matching transition as well

So the enabledTransitions contains the following transitions before calling filterPreempted:
from p0s1: <transition event="event2"/> (type1)
from p0s2: <transition event="event2" target="fail"/> (type3)
from p0s3: <transition event="event2" target="s1"/> (type3)
from p0s4: <transition event="*"> (type1)

Document order is:
from p0s2: <transition event="event2" target="fail"/> (type3)
from p0s1: <transition event="event2"/> (type1)
from p0s3: <transition event="event2" target="s1"/> (type3)
from p0s4: <transition event="*"> (type1)

As the draft still specifies "Type 3 transitions preempt all other transitions" the transition to s1 will always get preempted by the transition to fail. What am I missing here?

Sorry for not referring to the latest proposals with regard to preemption, but the situation is still rather opaque and at this point I just want the tests to pass.
  Stefan

Received on Thursday, 4 April 2013 15:28:13 UTC