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(^-Altitude)
The Scrall ^+
symbol indicates that we want a single highest value of Altitude. If we wanted all Aircraft at the same greatest Altitude, we might have written:
lowest flyers ..= Aircraft(^^-Altitude)
(If you are familiar with the Scrall syntax it may seem that the ..=
select many assigner is redundant, but more than one ranked comparison may appear in the same select statement, so we still specify the distinct cardinalities, one for the overall selection and one per ordered attribute selection).
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 ]