3
votes

I am trying to properly understand regions as well as fork and join pseudostates in UML State Machines. All examples I find are quite simple and I am not quite sure what is legal and what is not.

The UML Superstructure Specification (15.3.14 Transitions) states

The tail of a compound transition may have multiple transitions originating from a set of mutually orthogonal regions that are joined by a join point.

Does this mean, that a join may only be placed at the end of a compound transition?

Does this mean in consequence, that a join may only be followed by a state but not by a pseudostate?

It also states:

The head of a compound transition may have multiple transitions originating from a fork pseudostate targeted to a set of mutually orthogonal regions.

Does this mean, that a fork may only be placed at the beginning of a compound transitions (i.e. directly following a state but not after a pseudostate)?

Chapter 15.3.8 Pseudostate does not help me answering these questions. Neither the Constraints section nor the Semantics section make it any clearer to me.

join vertices serve to merge several transitions emanating from source vertices in different orthogonal regions. The transitions entering a join vertex cannot have guards or triggers."

If the incoming transitions don't have triggers: How do the transitions ever fire?

Example: Composite state S1: in region one S11 is active, in region two S12 is active. S11 and S12 have transitions leading to a join. How does the join ever get reached?

Edit: I stopped reading to soon. The answer to this one is "Through a completion event". These transitions are "completion transitions".

Also: When "mutually orthogonal regions" are mentioned: Do these regions have to be the children of the same composite states? More general: Can states only be concurrently active if they are placed in different regions of the same composite state or could - after a fork - multiple states be active that are located in totally different composite states?

1

1 Answers

4
votes

Fork and join stem from Petri nets. Along that net you have a virtual token that travels from node to node along the transitions. A fork will multiply an incoming token to as many outgoing transitions as there are. Only when all those tokens have reached the next join the machine will continue with a single token (unless this forks again with multiple transitions - but inside the fork line there will be one single token). You can imagine the line that represents a fork/join as a (1-dimension) box which momentarily holds a single token. This single token exists at the moment when all incoming transitions hold a token. This token is then multiplied for all outgoing transitions. Firing the new tokens takes no time. It happens instantly when the internal token has been created from the incoming tokens.

Unfortunately this concept is not well known and many modelers used it the wrong way. But I guess if you get the concept of the traveling (multiplied) tokens you will get the idea.