The Object Constraint Language: Getting Your Models Ready for MDA (2nd Edition)

All collection types have the operations shown in Table 9-1 in common. These operations are defined by the abstract supertype Collection . Following are examples of the use of the includes and includesAll operations. In the invariant, you specify that the actual service level of a membership must be one of the service levels of the program to which the membership belongs:

context Membership inv : programs.levels ->includes(currentLevel)

Table 9-1. Standard operations on all collection types

Operation

Description

count( object )

The number of occurrences of the object in the collection

excludes( object )

True if the object is not an element of the collection

excludesAll( collection)

True if all elements of the parameter collection are not present in the current collection

includes( object )

True if the object is an element of the collection

includesAll( collection)

True if all elements of the parameter collection are present in the current collection

isEmpty()

True if the collection contains no elements

notEmpty()

True if the collection contains one or more elements

size()

The number of elements in the collection

sum()

The addition of all elements in the collection. The elements must be of a type supporting addition (such as Real or Integer ).

The following invariant specifies that the available services for a service level must be offered by a partner of the loyalty program to which the service level belongs:

context ServiceLevel inv : program.partners ->includesAll(self.availableServices.partner)

9.2.1 Operations with Variant Meaning

Some operations are defined for all collection types but have a slightly different, specialized meaning when applied to one type or another. Table 9-2 shows an overview of the operations with variant meaning defined on the four collection types. An X mark indicates that the operation is defined for the given type; a hyphen (-) mark indicates that the operation is not defined for that type.

Table 9-2. Collection operations with variant meaning

Operation

Set

OrderedSet

Bag

Sequence

=

X

X

X

X

<>

X

X

X

X

-

X

X

-

-

append( object )

-

X

-

X

asBag()

X

X

X

X

asOrderedSet()

X

X

X

X

asSequence()

X

X

X

X

asSet()

X

X

X

X

at(index)

-

X

-

X

excluding( object )

X

X

X

X

first()

-

X

-

X

flatten()

X

X

X

X

including( object )

X

X

X

X

indexOf(object)

-

X

-

X

insertAt( index, object )

-

X

-

X

intersection( coll )

X

-

X

-

last()

-

X

-

X

prepend( object )

-

X

-

X

subOrderedSet(lower, upper)

-

X

-

-

subSequence(lower, upper)

-

-

-

X

symmetricDifference( coll )

X

-

-

-

union( coll)

X

X

X

X

The equals and notEquals Operations

The equals operator (denoted by = ) evaluates to true if all elements in two collections are the same. For sets, this means that all elements present in the first set must be present in the second set and vice versa. For ordered sets, an extra restriction specifies that the order in which the elements appear must also be the same. For two bags to be equal, not only must all elements be present in both, but the number of times an element is present must also be the same. For two sequences, the rules for bags apply, plus the extra restriction that the order of elements must be equal.

The notEquals operator (denoted by <> ) evaluates to true if all elements in two collections are not the same. The opposite rules as for the equals operator apply. Both operations use the infix notation.

The including and excluding Operations

The including operation results in a new collection with one element added to the original collection. For a bag, this description is completely true. If the collection is a set or ordered set, then the element is added only if it is not already present in the set; otherwise , the result is equal to the original collection. If the collection is a sequence or an ordered set, the element is added after all elements in the original collection.

The excluding operation results in a new collection with an element removed from the original collection. From a set or ordered set, it removes only one element. From a bag or sequence, it removes all occurrences of the given object.

The flatten Operation

The flatten operation changes a collection of collections into a collection of single objects. When applied to a bag, the result is also a bag. This means that when a certain object is in more than one subcollection, that object will be included in the resulting bag more than once. When applied to a set, the result is also a set. Thus, when the object is in more than one subcollection, it is included in the result only once. For example, if the original collection is the one in the first line in the following example, then the result of the flatten operation would be the collection in the second line.

Set { Set { 1, 2 }, Set { 2, 3 }, Set { 4, 5, 6 } } Set { 1, 2, 3, 4, 5, 6 }

The result of the flatten operation executed on a bag instead of a set, is shown in the following example:

Bag { Set { 1, 2 }, Set { 1, 2 }, Set { 4, 5, 6 } } Bag { 1, 1, 2, 2, 4, 5, 6 }

When the flatten operation is applied to a sequence or ordered set, the result is a sequence or ordered set (respectively). However, when the subcollections are either bags or sets, the order of the elements cannot be determined precisely. In that case, the only thing that can be assured is that the elements in a subset that comes before another subset in the original also come before the elements of the second subset in the result. For example, if the original sequence is the one in the first line of the following example, then one of the possible results of the flatten operation could be the one in the second line:

Sequence { Set { 1, 2 }, Set { 2, 3 }, Set { 4, 5, 6 } } Sequence { 2, 1, 2, 3, 5, 6, 4 }

The elements of the subsets are randomly placed in the resulting sequence. There is no garantee that a second application of the flatten operation to the same sequence of sets will have the same result. Note that the flatten operation is defined as a recursive operation, therefore, its result is always a collection of values of one of the basic types or one of the user -defined types.

The asSet, asSequence, asBag , and asOrderedSet Operations

Instances of all four concrete collection types can be transformed into instances of another concrete collection type. This can be done using one of the asSet, asSequence, asBag , or asOrderedSet operations. Applying asSet on a bag or asOrderedSet on a sequence means that of any duplicate elements, only one remains in the result. Applying asBag on a sequence or asSet on an ordered set means that the ordering is lost. Applying asOrderedSet or asSequence on a set or bag means that the elements are placed randomly in some order in the result. Applying the operation on the same original twice does not guarantee that both results will be equal.

The union Operation

The union operation combines two collections into a new one. The union of a set with a set will result in a set; any duplicate elements are added to the result only once. Combining a set with a bag (and vice versa) results in a bag. A sequence or ordered set may not be combined with either a set or a bag, only with another ordered collection. In the result, all elements of the collection on which the operation is called go before the elements of the parameter collection.

The intersection Operation

The intersection operation results in another collection containing the elements in both collections. This operation is valid for combinations of two sets, a set and a bag, or two bags, but not for combinations involving a sequence or ordered set.

The minus Operation

The minus operation (denoted by - ) results in a new set containing all the elements in the set on which the operation is called, but not in the parameter set. This operation is defined for sets and ordered sets. When applied to an ordered set, the ordering remains. The minus operation uses an infix notation. Here are some examples:

Set{1,4,7,10} - Set{4,7} = Set{1,10} OrderedSet{12,9,6,3} - Set{1,3,2} = OrderedSet{12,9,6}

The symmetricDifference Operation

The symmetricDifference operation results in a set containing all elements in the set on which the operation is called, or in the parameter set, but not in both. This operation is defined on sets only. Here is an example:

Set{1,4,7,10}.symmetricDifference(Set{4,5,7}) = Set{1,5,10}

9.2.2 Operations on OrderedSets and Sequences Only

All the operations defined only for the OrderedSet and Sequence types involve the ordering of the elements. There are nine such operations:

  • The first and last operations result in the first and the last elements of the collection, respectively.

  • The at operation results in the element at the given position.

  • The indexOf operation results in an integer value that indicates the position of the element in the collection. When the element is present more than once in the collection, the result is the position of the first element. Note that the index numbers start with one, not zero, as is often the case in programming languages.

  • The insertAt operation results in a sequence or ordered set that has an extra element inserted at the given position.

  • The subSequence operation may be applied to sequences only, and results in a sequence that contains the elements from the lower index to the upper index, inclusive, in the original order.

  • The subOrderedSet operation may be applied to ordered sets only. Its result is equal to the subSequence operation, although it results in an ordered set instead of a sequence.

  • The append and prepend operations add an element to a sequence as the last or first element, respectively.

Here are some examples:

Sequence{'a','b','c','c','d','e'}->first() = 'a' OrderedSet{'a','b','c','d'}->last() = 'd' Sequence{'a','b','c','c','d','e'}->at( 3 ) = 'c' Sequence{'a','b','c','c','d','e'}->indexOf( 'c' ) = 3 OrderedSet{'a','b','c','d'}->insertAt( 3, 'X' ) = OrderedSet{'a','b','X','c','d'} Sequence{'a','b','c','c','d','e'}->subSequence( 3, 5 ) = Sequence{'c','c','d'} OrderedSet{'a','b','c','d'}->subOrderedSet( 2, 3 ) = OrderedSet{'b','c'} Sequence{'a','b','c','c','d','e'}->append( 'X' ) = Sequence{'a','b','c','c','d','e','X'} Sequence{'a','b','c','c','d','e'}->prepend( 'X' ) = Sequence{'X','a','b','c','c','d','e'}

Категории