Skip to content

Action semantics

Leon Starr edited this page Nov 6, 2023 · 11 revisions

The following text is excerpted (and modified) from the book Models to Code:

Platform independent sequencing

To be truly platform independent, a model should not specify a particular sequence of computation unless that sequence must be enforced on every potential target platform. Here is an example of an arbitrary computation sequence:

y = scale(x)
z = filter(i1, i2, ... in)
result = y + z

Depending on the implementation, actions 1 and 2 could be reversed or executed concurrently. Action 3, on the other hand, must wait for both actions 1 and 2 to be complete. If the action sequence as written is intended to indicate a required sequence of computation, the model is unnecessarily limiting implementation choices. This breaks the principle that the model must specify only what is required on all potential platforms. By breaking that principle, the model loses a bit of credibility. “What else in the model might I ignore?” the implementor now begins to think!

Each action is represented as a circle, and we interpret each action to be runnable when all of its inputs are available. Action 3 must therefore wait until both actions 1 and 2 have produced output. This data-flow view of computation eliminates the statement of arbitrary sequencing. This is why the data flow is our fundamental view of algorithmic processing in xUML.

Unfortunately, text representations are faster and easier to edit than graphical representations of data flows. In Chapter 2 of Models to Code, we showed a data-flow diagram of the Logging In activity from the Air Traffic Control model. The difficulties of dealing with data-flow graphics and specification of the data-flow processes have meant that all translation schemes of which we are aware use a text-based language to specify activities.

The use of a text-based action language does not preclude having data flow semantics in the language.

The same data flow diagram in Scrall might like this:

y = Scale(^x) // ^ denotes that x is an input parameter
z = Filter(^ivalues)
result = y + z

Here we assume that Scale and Filter are methods of the local class. Both x and ivalues are passed into the activity as parameters. The ivalues could be either a scalar value typed to hold a set of values or it could be a set of instance references if the activity not a state activity. Since y and z are on the LHS of assignment expressions in this activity, we know that the third line cannot execute until the first two are complete. Since lines 1 and 2 have no data dependencies with one another, we know that they can be executed concurrently. In sort, we have enough information in the text to regenerate the essential data flow graph.

Expressing data and control flow dependencies in Scrall

Now let’s take a look at one of the activities defined in the Air Traffic Control example from the Models to Code book.

The activity must migrate an instance of Off Duty Controller to an instance of On Duty Controller.

From the DFD we can see that there are three things that can be accomplished concurrently within the activity. (Because they have no data or control dependencies)

A) Get the instance reference
B) Migrate the instance, linking it to the Duty Station
C) Signal the Duty Station
D) Signal the local instance (me)

(A & D) can both go first since each has all of its data available at the start

(B) can activate after (A) now that it has an instance reference to an On Duty Station (my station). The migrate >>, link & and write actions must be combined so that we don’t end up with any null attribute values.

(C) now the Duty Station instance can be signaled since it is now related to the local instance (dashed arrow from Link to Signal action)

We can express all this in Scrall as shown:

my station .= Duty Station( Number: ^station )

>>On Duty Controller(Time logged in: Date.HMS()) &R3 my station <1>

<1> In use -> my station

Logged in -> me

The first and last lines above can execute immediately since each has all of its data available at the start. The second line migrates the instance, sets the login time and links it to the Duty Station all in one expression. It can execute as soon as the my station variable is set. Once this expression completes it sets the named control token <1> fulfills the purpose of a dashed control flow in the diagram. With <1> set, the third line can execute and signal the In use event. The control token is named just like a variable, so it could have been something like or instead.

Regarding the expression in line 2, note that we have two ways of expressing a data flow. One way is through an assignment, as we do in line 1. The other is through nested expressions and compound actions. All attributes, including referential attributes, must be given legal values upon instance creation. Nulls are forbidden in xUML! Since the migrate action deletes an instance in one subclass (Off Duty Station) and creates one in another (On Duty Station), it must ensure that all attributes are set correctly. The action, therefore, includes both the attribute write and the On Duty Station link on R3. To prevent the newly linked station instance from peeking at incomplete data, we use a control token to sequence the In use event.

There’s no harm, by the way, in sending the Logged in event right away since it is directed to the local instance (me) where the dispatched event will be held until the entire activity is complete.

Introduction

Model semantics

Flows (as Variables)

Constants and literals

Structure of an activity

Accessing the class model

Data flow


Grammar and parsing notes

Components

Clone this wiki locally