The purported nondeterminism is actually due to the way the procedure was presented, namely that the action that sends the signal from A to B gets executed before the action that looks at B's current state.Suppose you have a PIM expressed in Executable UML comprising two objects, A and B.Suppose A sends a signal X to B, andthen (as the next action) executes a synchronous query Q on B whichreturns true if B has received X, and false if B has not received X.
Suppose we made a rule that said, "no matter how the procedure is written, all 'send signal' actions occur at the end of the procedure's execution." This sort of refactoring of the procedure is very easy to see if you convert the procedural action language to ADFDs (action dataflow diagrams) like the ones in Modeling the World in States. Since "send signal" actions don't produce any data to be consumed by any other actions, they can wait to be executed until there are no other actions left to execute in the procedure.
In the case of this example, it would mean that even if the procedure was written as
send signal X to B;it would be executed as
if B.CurrentState == NewState then print "true" else print "false";
if B.CurrentState == NewState then print "true" else print "false";The result would be a deterministic behavior regardless of the implementation architecture.
send signal X to B;