In this second post (read the first one here ), Ed Seidewitz talks about the new executable UML standards: fUML and Alf. As editor of the fUML specification and primary author of the Alf specification (apart from Vice President of Model Driven Architecture Services at Model Driven Solutions ) who better than him to describe these new standards?. Hope you enjoy his post!

An “executable” UML model is one with a behavioral specification detailed enough that it can effectively be “run” as a program. This can be extremely valuable in order to test and validate the model, independently of the one or more implementation platforms to which the system being modeled will ultimately be deployed. Or, in some cases, the model itself can actually be run as the production implementation, given an appropriate execution environment.

There have been model execution tools and environments for years, even before UML. However, each tool defined its own semantics for model execution, often including a proprietary action language, and models developed in one tool could not be interchanged with or interoperate with models developed in another tool. A previous post described Stephen Mellor’s quest of more than a decade to change this through OMG standards for precise UML model execution semantics and a UML action language.

In 2008, this led to the adoption of the Foundational UML (fUML) specification, providing the first precise operational and base semantics for a subset of UML encompassing most object-oriented and activity modeling. The fUML specification still did not provide any new concrete surface syntax, however, tying the precise semantics solely to the existing abstract syntax model of UML. This meant that, in order to fully specify a detailed behavior in a UML model – say the effect behavior of a transition on a state machine or the method of an operation of a class – one still had to draw a very detailed, graphical activity diagram.

Now, anyone who has ever tried to create and activity diagram down at this level of detail (I have personally done several!) knows that it is a frustrating, time-consuming and error-prone thing to do. The graphical UML activity notation was just not meant to be used at such a level of detail – and, in fact, for most people, trying to do such “graphical programming” is just not intuitive or effective. This is why almost all existing commercial model execution tools provide some sort of action language for detailed behavioral specification.

The adoption of executable semantics for UML finally made painfully clear to everyone the need for a textual alternative to specifying detailed computations using the graphical activity diagram notation. The Concrete Syntax for a UML Action Language RFP, issued by OMG in 2008, asked for exactly such an alternative. The final submission to this RFP was adopted by OMG in 2010 and is currently in finalization.

The adopted action language is known as the Action Language for fUML, or “Alf”. Alf is basically a textual notation for UML behaviors that can be attached to a UML model any place that a UML behavior can be. For example, Alf text can be used directly to specify the behaviors of a state on a state machine, the method of an operation or the classifier behavior of an active class. Further, the “extended” Alf notation actually includes some basic structural modeling constructs, so it is also possible to do entire models textually in Alf.

Semantically, Alf maps to the fUML subset. In this regard, one can think of fUML as effectively providing the “virtual machine” for the execution of the Alf language. However, this grounding in fUML also provides for seamless semantic integration with larger graphical UML models in which Alf text may be embedded. For example, there are “medium grained” processes that can be effectively specified using graphical activity diagrams with precise fUML execution semantics. One can then use Alf to specify the behavior of specific finer-grained actions within such processes – but based on the same underlying fUML semantics. This avoids the semantic dissonance and non-standard conventions required if one where to instead, say, use a programming language like Java or C++ as a detailed action language within the context of an overall UML model.

Let me elaborate a bit on the importance of semantic integration. Suppose we have a UML class model that has an association between a Customer class and an Account class and we want to navigate across the association to the Account side and sum up all the balances of all the accounts of a certain customer. Now, the UML concepts of “association” and “navigation” do not exist as such in most programming languages. So, if we were to use, say, Java as an action language, such concepts have to be semantically “mapped” to constructs that exist within Java. One approach would be to treat the “accounts” end of the association as a Java collection, in which case the desired behavior could be coded as:

Integer totalBalance = 0;
for (Account account: myCustomer.accounts) {
  for (Integer balance: account.balance) {
    totalBalance += balance;
  }
}

But association ends are not really semantically collection objects in UML—rather, they are multi-valued properties with specified multiplicities. The fact that myCustomer.accounts actually returns an object in the Java is dissonant with the UML semantics, and any code that relies on this mapping needs to be specifically avoided. Further, there is the question, during execution, of what kind of concrete collection should actually be instantiated—A Vector? An ArrayList? A HashSet? And why not map to Java arrays rather than collection objects?

The problem is that the semantic mapping to a programming language requires the introduction of exactly the kinds of implementation decisions that one wants to avoid in model execution. Moreover, suppose one wants to deploy to, say, both Java EE and C#.NET platforms—why use Java as the action language and not C#? In general, one would like to keep the model independent of the implementation platform (a well-known tenet of OMG’s Model Driven Architecture approach), specifying precise system behavior in the model without committing to the non-essential details of a specific target platform.

Hence the need for an action language that is at the same semantic level as the rest of the UML model. Several existing executable modeling tools already provide such an action language. Alf is also such a language, but one that is an OMG standard that can be consistently implemented across a number of tools, promoting the same sort of interoperability for textual behavioral specification that the UML standard already does for graphical modeling.

Syntactically, Alf looks at first much like a typical C/C++/Java legacy language. This is the result of a conscious compromise on the part of the submission team. Since, despite the issues mentioned above, it is currently not uncommon practice to use Java or C++ as a UML action language, there was a strong desire to have a subset of Alf that would be familiar to such practitioners, to ease their transition to the new action language. Indeed, the Java code example given above is actually syntactically valid in Alf, too, with no change at all.

However, in addition to semantic integration with UML, Alf also provides some convenient syntactic shorthands. For instance, the balance summation loop can be written in Alf as

totalBalance = 0;
for (balance in myCustomer.accounts.balance) {
    totalBalance += balance;
}

First, note that while “myCustomer.account.balance” may look like a regular Java field access expression, what it really does is navigate from myCustomer, across the association to the opposite “accounts” end, return all the Account objects at that end, and get the balance of each one. Alf adopts the notational convenience introduced in the already standard Object Constraint Language (OCL) that navigation across an association to a multi-valued end automatically collects all the values at that end, so it is not necessary to have an explicit for loop to do this.

Second, note that it is not necessary to explicitly declare the type of totalBalance or balance. The types of these local names are inferred from the result types of the expressions assigned to them—a convenience familiar to users of any modern scripting language.

Further, beyond simple syntactic conveniences, Alf also includes constructs that leverage the inherently concurrent, flow-oriented nature of the underlying fUML activity semantics. These include very powerful capabilities like filtering and mapping similar to those seen in many of the recently popular functional languages. So, for example, the above loop can be more compactly written:

myCustomer.accounts.balance -> reduce ‘+’;

And, in this case, the expression maps to a single UML reduce action, which, on an appropriate platform, could be implemented as a highly concurrent operation, rather than as a sequential loop. Further, suppose that myCustomer was to be selected based on email address from the extent of existing customers. This can be simply written (presumably before the statement above!):

 
myCustomer = Customer -> select c (c.email == myCustomerEmail);

The “select” notation here maps to a fUML parallel expansion region that, again, could be implemented as a highly concurrent search – or even translated into a database query. And, while the “=” looks like a traditional variable assignment, what it really maps to is a data flow in the underlying fUML activity – so local assignments do not actually introduce mutable state, which again allows much greater flexibility in the translation to implementation.

The key, here, is that the Alf action language allows even detailed behavior to be specified at the higher level of abstraction provided by the underlying fUML activity semantics. Such behaviors are specified more at the level of what is to be done, rather than how it is to be done – allowing for greater freedom in implementing the behavior on different implementation platforms – especially the new and innovative concurrent platforms appearing today. Indeed, the real power of executable modeling going forward relies on keeping the entire behavioral specification at such a higher level of abstraction.

But does this just turn executable modeling into “programming in UML”? Well, as both a practicing software architect and a practicing software developer, I can honestly say I am OK with that. No, wait. What I really want to say is “It’s about time!”

More information on fUML and Alf can be found at the following locations:

  • fUML 1.0 Specification: http://www.omg.org/spec/FUML/Current
  • Alf 1.0 Specification: http://www.omg.org/spec/ALF/Current
  • fUML Open Source (Reference) Implementation: http://fuml.modeldriven.org
  • Complete Alf Parser: http://lib.modeldriven.org/MDLibrary/trunk/Applications/Alf-Reference-Implementation/dist/ (Further language implementation is still in progress.)
  • Presentations on executable UML and SysML: http://www.slideshare.net/seidewitz
Want to build better software faster?

Want to build better software faster?

Read about the latest trends on software modeling and low-code development

You have Successfully Subscribed!

Pin It on Pinterest

Share This