Rank Restrict Action - modelint/shlaer-mellor-metamodel GitHub Wiki
Sometimes you need to select the tuple or instance with the greatest or least value of some Attribute.
For example, here is a Scrall statement that selects one instance of Aircraft at the lowest Altitude:
lowest flyer .= Aircraft(1, ^-Altitude)
The Scrall ^- symbol indicates that we want those instances of Aircraft (if any exist at all) flying at the lowest altitude. An the 1 cardinality indicates that we want only one of these. So the output of the selection is zero or one instance and we can use the .= assigner to clarify this intention. The assignment cardinality is redundant, but when we have more complex right hand side expressions, the assignment intention is a helpful safety check and expression of the modeler's intention.
If we wanted all Aircraft at the same lowest Altitude, can write:
lowest flyers ..= Aircraft(^-Altitude)
The default selection cardinality is always * (many) so we don't need to specify it.
Without our convenience action, we would need to break this statement down into the following data flow diagram:
images/relational-action-subsystem/rank-restrict-action-10.png
A Class Accessor flows all of the Aircraft instances into the RANK action which performs an implicit EXTEND adding a Table Attribute named _rank where all Aircraft tuples are ranked by increasing (ascending) Altitude. The resulting relation is fed into a RESTRICT action which grabs the _rank value 1 (there can be only one even if there are multiple Aircraft at the same lowest altitude since _rank is a key).
This single tuple flows into a PROJECT (Project Action) which passes all Attributes through except for _rank. This output is then assigned to lowest flyers after being cast back to an instance flow as directed by the ..= assignment operator.
Since accessing the greatest or least value(s) of an Attribute or Method output is a common operation, we abstract a convenient composite Relational Action.
It's data flow diagram looks like this:
images/relational-action-subsystem/rank-restrict-action-20.png
Here the RANK, RESTRICT, and PROJECT are condensed into the single RANK RESTRICT Relational Action. This is particularly helpful since the whole _rank addition, manipulation, and removal is now transparent so that the modeler can focus on the real goal which is simply to choose the greatest or least value or values.
To get our second statement,
lowest flyers ..= Aircraft(^-Altitude)
where we want potentially multiple instances, we just change the cardinality input to RANK RESTRICT from ONE to ALL. For now at least, the intermediate values (like the top or bottom two) are not supported.
Identifiers
- ID + Activity + Domain
Attributes
Extent
Here you ask for the greatest or least of the input values. This is not to be confused with the choice of ranking which will be either ascending (in the case of least) and descending to select the greatest value.
Type: Greatest Least :: [ greatest | least ]
Selection cardinality
When multiple matching input values at either extreme (many highest aircraft at the same altitude, or possibly all aircraft at the same altitude) the cardinality determines whether one or all instances with matching values are returned.
If the cardinality is one, the tuple selected among many matching values is indeterminate. If this matters, the modeler must supply further restriction criteria to the Restrict Action.
Type: Selection Cardinality :: [ one | all ]