According to my girlfriend, my last blog post was rather boring. So I had to remind her that she is not my audience. I am writing for an elite group of software PROFESSIONALS who are fascinated by intricate detail. Then I went back to read the first paragraph and fell asleep into my bowl of cereal.
Well, today’s post will be a bit more exciting with much hopping around. In a good way.
Today’s topics:
- The hop symbol for relationship navigation
- Specifying default paths for terse, easy hopping
- Refining with selection criteria along the way
- Hopping in place, better reflexive navigation
- A 20:1 reduction in lines of action language
From one object to more objects
Last week we selected objects directly without traversing any of the relationships (associations and generalizations) on the class model. You want direct selection when you have access to data values that you need to convert to object references. But once you have one or more objects in hand, it is generally more efficient1 to trace relationships on the class model to find what you need.
Starting with a simple example from the Elevator Case Study, an instance of Door needs to jump across R4 to grab its associated Cabin object.

In Scrall we use the /
hop symbol. Easy to type and intuitive for us Linux/Mac folks2.
my cabin .= /R7/Cabin
or use the verb phrase3
my cabin .= /is passenger entry for/Cabin
So you can freely mix relationship names, verb phrases (role names) and class names in a hop expression without any special distinguishing notation or quote marks. The Scrall language analyzer has access to the class model so it can connect the dots and figure out what you mean.
Note the boldface text in the verb phrases on the class diagram. miUML lets you specify optional verb phrase abbreviations4 to trim down your action language text. (Proper UML would use a tag, of course). So you could type:
my cabin .= /entry/Cabin
But, that’s STILL too much to type as far as I’m concerned…
Short hops
What is the point of restating what is already on the class diagram? One fact in one place, right? From a given object, it is frequently the case that you are hopping across just one association where there is only one possible destination class.
The Scrall language analyzer knows what you want.
So just type this:
my cabin .= /Cabin
The language analyzer has access to the class model and can see that there there is only one path from Door to Cabin. But not always.

If you have two or more associations between the same two classes you will need to be specific. So, from the Vehicle’s perspective, you might write:
my driver .= /driven by
my owner .= /owned by
Here are some other legal variations:
my driver .= /R1
my owner .= /R2/Person
You don’t need the class name at the end to resolve ambiguity, but you might put it in for clarity. Whatever you do, keep your style consistent. A configurable autofill feature can help with that.
This may seem like a lot of fuss for such a tiny bit of text. But we want to keep our building blocks small and readable so that we get a payoff hopping across multiple relationships, nesting expressions and doing other awesome s^%t.
A long jump
Now let’s try a longer jump.

In the Elevator Case Study all Shafts in the same Bank (think Express Bank, Freight Bank, Lower Floors Bank as examples) provide identical service. Cabin speed, door open delay and all other behavior is uniform by policy for all Shafts in the same Bank.
Upon opening at a Floor, the Door object needs to retrieve, from its associated Bank object, the amount of time it should remain open before automatically closing. Scrall let’s you say this:
open delay = /Bank.Door open delay
Just because it lets you say that, doesn’t mean you should. If we zoom out, we see that there are multiple paths between Door and Bank.

There are many loops of relationships to confuse the Scrall language analyzer. Which path to take?
R4/R2/R1 – The path we want, obvious choice… right?
R4/R53/R38/R29 – Not that one
R4/R43/R28/R1 – Nope
R4/R43/R28/R29 – Are you insane, language analyzer? No!
And so many other crazy possibilities.
The language analyzer takes the shortest path to the target if no other cues are provided. And we just happen to be lucky that there is only one shortest path. We will not always be so fortunate, however. Also, it would suck if a slight edit to the class model opened up multiple shortest paths and hosed our actions.
So, unless you are pretty sure that this is not going to happen (single or double hops are relatively safe), you may want to provide the whole path anyway.
Oh, come on! Let’s not give up that easy. You could just provide a few cues to resolve potential ambiguity:
open delay = /Shaft/Bank.Door open delay
(Shortest path to Shaft is /R4/R2 and then the hop to Bank is a single hop)
Also good:
open delay = /Cabin/Bank.Door open delay
(One hop to Cabin and then shortest path to Bank)
So you could combine the shortest path rule with just enough clues to head in the right direction. But, really, there’s so little gain in this case, that you might as well just spell the whole path out.
Grrr.
We want a more satisfying solution with less potential for confusion.
Default path names
If the metamodel is modified to support path naming on the class model, you could provide this information:
[<path name>] = <full relationship path>
This is not action language, but using the above syntax as part of the Elevator class model, you could specify this:
my = Door/R2/R4/R1
Now the name my
(local to the origin class, Door) can be used in a hop expression like so:
open delay = /my/Bank.Door open delay
Here the action language is easy to read and all ambiguity is removed. The fact is, there are only a tiny subset of possible paths on a class model that are ever used. So why not name some of the longer ones and keep them all in one place?5
Notice, however, that the path name is optional! If no name is provided, the path is effectively declared as the default. That being the case, you could write our original concise statement without fear of ambiguity:
open delay = /Bank.Door open delay
To offer a comparison, in xtUML’s OAL (Object Action Language), you would have needed to write all this:
select one my_Bank related by self->Cabin[R4]->Shaft[R2]->Bank[R1];
open_delay = my_Bank.Door_open_delay;
Bonus points to anyone who demonstrates the best way to do this in ALF, TextUML or any other action language in the comments below.
Selection criteria
The selection expression discussed in my previous post may be included at the end of a hop expression to narrow down your choice of objects.
In some activity in the Bank class, you can apply selection criteria to grab all related Cabins going up (if any).
up cabins ..= /Cabin( Travel direction: .up )
Traversal via /Cabin
follows the shortest path R1/R2 rule and .up
is an enumerated value defined on the Direction type seen on the class diagram. So the grammatical pattern here is…
<object set>( <selection expr> )
… where the object set could be produced by an object variable, direct selection or hop expression.
Oh, but it gets better
Selection criteria may include relationship as well as attribute comparisons.
So, a Bank can select all Cabins whose doors are unlocked (open and not moving) at some Floor.
stationary cabins ..= /Cabin( Current floor: some floor,
Door.Unlocked )
The first part of the selection criteria is a simple attribute-value comparison with the previously defined data variable some floor
. The second part traverses to the related Door instance and returns true/false on the boolean attribute with the comma filling in the implicit AND.
You cannot easily assemble the stationary cabins
set in OAL. Instead you would probably write one of these dreaded for-each loops which Scrall discourages:
select many my_Cabins related by self->Shaft[R1]->Cabin[R2]
where selected.Current_floor == some_floor;
for each this_Cabin in my_Cabins
select one its_Door related by this_Cabin->Door[R4];
if its_Door.Unlocked
// Do something with c here in the loop
// (Quick, before it goes out of scope!)
end if;
end for;
Well, that was a whole lot of ugly.6 How do you do it in your favorite action language?
Hopping along reflexive associations
Reflexive associations get special support in Scrall as we’ll see using this example:

On a reflexive association, you must specify the verb phrase in the desired selection direction.
follow ac .= /following/Aircraft
Now let’s mix in some criteria. We want the next Aircraft in the flight pattern order at the same altitude that is cleared to land.
follow ac at my level .= /following( (its.Altitude - my.Altitude)
< same level height, /will land on/Runway )
Again, the comma serves as an implicit AND, eliminating the need for another level of parentheses. The first criteria in the selection expression compares the altitude differential to some height in a predefined variable. Note the introduction of Scrall’s my
and its
keywords. You rarely need them, but we are comparing the same attribute on two different objects. Even though my.
is always assumed for local attributes and methods, it helps to improve readability in this particular context.
The second criteria is the relationship to Runway. If it yields the empty set, it evaluates to false, otherwise true.
Therefore, you grab all Aircraft at roughly the same altitude that are assigned to some Runway.
Repeated reflexive hopping
An interesting characteristic of reflexive associations is that they give you the opportunity to hop multiple times. With a linear sequence of objects in the same class, you often want to start at one object and keep hopping on the same reflexive association until you find another matching the desired criteria.
Rather than do this with an awkward for-loop construction that needlessly specifies a procedural sequence, we can just specify it inline with the /~/
hippity-hop symbol.
next ac with assigned runway .= /will land after/~/( /is assigned to land at )
The criteria consist of a single relationship comparison. It yields true for an Aircraft with an assigned Runway. So you’ll either get the empty set or the first Aircraft in sequence with an assigned Runway.
And don’t worry. The hippity-hop symbol knows to stop before it revisits the starting object in a potential link cycle. Yeah, I thought of that.
A 20:1 reduction in action language
I will leave you today with one last action language comparison. Here is some OAL from my Elevator Case Study that I have converted to Scrall. First, here is the original OAL:
// Bank Level
// Choose_shaft( Direction:Dir, Short_name:OUT_Shaft ) : Boolean
//
// Sets the best inservice Shaft to service a floor call
// as OUT_Shaft and returns false if none are found
// Initialize and establish outer scope
shortest_delay = 0.0; // seconds
first_cabin = true;
param.OUT_Shaft = "";
// Select one of the cabins with the shortest delay
select many bank_Cabins related by my_Bank->Shaft[R1]->Cabin[R2];
for each this_Cabin in bank_Cabins
select one its_Shaft related by this_Cabin->Shaft[R2];
if ( its_Shaft.In_service )
cab_delay = this_Cabin.Estimate_travel_delay(
Floor:my_Floor.Name, Calling_dir:param.Dir );
if ( (cab_delay < shortest_delay) or (first_cabin) )
shortest_delay = cab_delay;
param.OUT_Shaft = its_Shaft.ID;
end if;
end if; // in service
first_cabin = false;
end for;
if ( param.OUT_Shaft != "" )
return true;
else
return false;
end if; // False only if all Shafts are out of service
// ===
Here is the one line of Scrall (not counting comments) that gets the job done:
// Bank Level
// Choose shaft( Dir : Direction ) : Shaft
return( /Shaft( In service )/Cabin( ^-Estimate travel
delay( Floor : /Floor.Name, Calling dir: in.Dir ) )/Shaft )
Let’s break it down.
// Choose shaft( Dir : Direction ) : Shaft
We’ve redefined the method signature a bit. There is no need for the awkward OUT_Shaft
parameter since Scrall methods can return any type, be it a relation, object set, or data value. Since the type of this function corresponds to the class name Shaft7, we know it returns an object set. And since the empty set evaluates as false in Scrall, the calling activity can still test the return value as a boolean.
/Shaft( In service)/Cabin
Traverse (shortest path) to Shaft, checking the Shaft.In service boolean to narrow the selection and then continue the hop to the associated Cabins.
Now we have the working Cabins.
Cabin( ^-Estimate travel delay(
Floor : /Floor.Name, Calling dir: in.Dir ) )
In my previous post, Aircraft( ^-Altitude )
returned all lowest flying Aircraft. We’re using the same min operator here, but applying it to a value returned by a method instead of an attribute. The method takes a destination floor and calling up/down direction and estimates, based on its current work load, how long it should take the Cabin to arrive at the Floor.
/Shaft
And then we just hop from the one8 or more Cabins with the least value back to their associated Shafts.
return( /Shaft( In service )/Cabin( ^-Estimate travel
delay( Floor : /Floor.Name, Calling dir: in.Dir ) )/Shaft )
Whereas the OAL returns the ID of a selected Shaft, (requiring an extra unnecessary object selection by the calling function) an miUML method can return an object set. So the calling activity can do this:
best shaft .=. Choose shaft( in.calling dir )
if best shaft {
// do stuff
}
Once again, feel free to post counter examples in your favorite action language. Though, if I see something I like, I will probably steal it.
Next post: Signals, relation variables and set operations
- For both platform independent modeling and implementation reasons. ↩
- And possibly annoying to Windows folks. ↩
- sm UMLs use verb phrases in place of role names for more clarity and precision. See my article on Articulate UML for more about that ↩
- It’s not in the metamodel yet, but it will be when I push the next update. ↩
- An miUML class diagram editor could provide a view layer that highlights all of the named relationship paths. ↩
- Actually, it occurs to me that in OAL maybe you could define a
Door_unlocked::boolean
method on Cabin and invoke it in the select criteria, but that’s still ridiculous. ↩ - In the rare case where you have a type with the same name as one of your classes in the same modeled domain, you will need to clarify with something like
Class::Shaft
. ↩ - If the model is populated with at least one Bank, and it must be to work, you will always select at least one Cabin and possibly all of them. ↩
I help agile software teams succeed with requirements analysis, domain definition, platform independent, executable modeling and high quality code generation. Other websites: executableuml.org, modelstocode.com
I will try again, comments do not honor pre blocks…
Hey Leon,
Scrall:
OAL:
TextUML (with class-owned association ends, which syntactically looks like attribute access):
TextUML (with association-owned association ends, which requires specifying the association using the end1 end2 syntax):
or if we had given somewhat descriptive names to the associations:
(the names I chose are still not great, as I am not familiar with the domain at hand)
Let’s not forget OCL (for all the query/navigation part)!
Gaah, wordpress ate the angle brackets in the 2nd and 3rd examples… my last attempt (2nd example only, asssociation owned ends with your association names):
I concede defeat.
It seems like the model should have enough information for a compiler to determine when two possible paths can result in different sets. That would be an error; otherwise, the compiler could pick the “best” way to obtain the desired set. The generated program might use mechanism to instantiate the set that don’t even resemble the navigarion spec in the action language.
Does the automatic path choice take conditional path ends into account? It seems that a longer path with no conditional path ends would be preferable over a shorter path with conditionals. It’s the only correct way to read the model and expect a selection not to fail.
Hi everyone, I’m enjoying the quality questions and insightful observations. Will do my best to respond to ALL of them. A combination of my California timezone offset from the rest of the world and a crazy weekend may slow me down a bit, but keep’em coming.
Regarding Dan’s comment about the model compiler having enough information:
Hmm, after re-reading a couple of times I realize that I don’t understand the comment. An ambiguous comment about the danger of ambiguity? How ironic 😉 But mis-understanding something has never stopped me from charging full speed ahead before, so why start now? First of all, it is absolutely critical that the action language, and entire model set be unambiguous. The model compiler should NOT be making choices about which way to travel around the model. It can only choose HOW to do it. The whole path choosing thing is supposed to be an aid to the model developer and model reviewer to simplify away obvious details. It is a shorthand, if you will. The tool editor should be smart enough to show you, as an option, all fully qualified paths if you want to see them.
I was probably overthinking the “Just because it lets you say that, doesn’t mean you should” statement. I was just thinking a compiler or model verifier could flag ambigous hop expressions. I also had the idea that multiple navigation paths could *possibly* result result in the same selection. If so, the ambiguous spec is harmless because the result is the same for each path. The case of multiple equivalent paths may never actually happen in practice.
Now on to Lee’s comment about conditional vs. unconditional (zero vs. non-zero multiplicities) on association paths:
If the path preference shorthand rules get tricky there will be too much confusion when reading someone else’s model. (Or your own the next morning after you stayed out too late at the tequila bar). I really just wanted to cover the cases where there was a painfully obvious path, either a long one that is used frequently, or a single-hop which is probably the most common case. As soon as you have a situation where the path is not so obvious, you should either spell it out with a fully qualified path OR, my preference, mark the path as default or name it if necessary as described in my post.
And it’s not just about being lazy. I like the idea of not having to restate something lengthy over and over again, scattered throughout the activities. By naming common paths right on the class model you 1) take away the guesswork and 2) keep one fact in one place.
Oh, right, and the answer to your question is, ‘No’. In fact, I don’t consider the selection of an empty set to be a ‘failure’. It is just an empty set. So, given two paths of equal length, one with a zero in it and the other without… I couldn’t be sure which one was best on that information alone. So, the modeler should specify his or her intentions in that case.
Nope. I don’t buy it. When trying to get from Bank to Door, there are only two paths in your diagram that will always result in finding Door. If not, then you’ve got bigger issues, because that’s the way it was modeled. Why should the selection algorithm choose a path that might fail? Would it then try a different one, and why would that be preferable?
Okay, now I have to be CAREFUL with Jordi’s comment on OCL since he runs the site 😉
Forget about OCL? Jamais! I want to explore the differences in depth and, to be honest, I am not anywhere near an expert that maybe I should be on OCL. Though I think we all agree that the expression of constraints is absolutely essential, however you do it. And too few modelers do, in my experience.
Regarding the ‘/’ hop symbol, as opposed do just using ‘.’ everywhere. If you want, and I think at least sm UML modelers do, to distinguish between relationship and attribute accesses, having two distinct symbols is visually helpful. Also/the/slash/symbol is, visually, a.less.subtle.separator. (In my opinion, anyway).
Guess what? I just discovered that there is a REPLY button under each comment. Oops. Somehow, I just scrolled right to the bottom of the page and started typing like an idiot. And here I was thinking I was clever putting your names and topics at the top of each response. Time to upgrade my eyewear!