Mapping rules for predefined iterator expressions


This section contains the operations and well-formedness rules of the collection types.
 

Collection

exists

Results in true if body evaluates to true for at least one element in the source collection.

source->exists(iterators | body) =
    source->iterate(iterators; result : Boolean = false | result or body)

forAll

Results in true if the body expression evaluates to true for each element in the source collection; otherwise, result is false.

source->forAll(iterators | body ) =
    source->iterate(iterators; result : Boolean = true | result and body)

isUnique

Results in true if body evaluates to a different value for each element in the source collection; otherwise, result is false.

source->isUnique (iterators | body) =
    source->collect (iterators | Tuple{iter = Tuple{iterators}, value = body})
        ->forAll (x, y | (x.iter <> y.iter) implies (x.value <> y.value))

isUnique may have at most one iterator variable.

any

Returns any element in the source collection for which body evaluates to true. If there is more than one element for which body is true, one of them is returned. There must be at least one element fulfilling body, otherwise the result of this IteratorExp is OclUndefined.

source->any(iterator | body) =
    source->select(iterator | body)->asSequence()->first()

any may have at most one iterator variable.

one

Results in true if there is exactly one element in the source collection for which body is true.

source->one(iterator | body) =
    source->select(iterator | body)->size() = 1

one may have at most one iterator variable.

collect

The Collection of elements which results from applying body to every member of the source set. The result is flattened.

Notice that this is based on collectNested, which can be of different type depending on the type of source. collectNested is defined individually for each subclass of CollectionType.

source->collect (iterators | body) = source->collectNested (iterators | body)->flatten()

collect may have at most one iterator variable.
 

Set

The standard iterator expression with source of type Set(T) are:

select

The subset of set for which expr is true.

source->select(iterator | body) =
    source->iterate(iterator; result : Set(T) = Set{} |
        if body then result->including(iterator)
        else result
        endif)

select may have at most one iterator variable.

reject

The subset of the source set for which body is false.

source->reject(iterator | body) =
    source->select(iterator | not body)

reject may have at most one iterator variable.

collectNested

The Bag of elements which results from applying body to every member of the source set.

source->collect(iterators | body) =
    source->iterate(iterators; result : Bag(body.type) = Bag{} |
        result->including(body ) )

collectNested may have at most one iterator variable.

sortedBy

Results in the OrderedSet containing all elements of the source collection. The element for which body has the lowest value comes first, and so on. The type of the body expression must have the < operation defined. The < operation must return a Boolean value and must be transitive i.e. if a < b and b < c then a < c.

source->sortedBy(iterator | body) =
    iterate( iterator ; result : OrderedSet(T) : OrderedSet {} |
        if result->isEmpty() then
            result.append(iterator)
        else
            let position : Integer = result->indexOf (
                result->select (item | body (item) > body (iterator)) ->first() )
            in
                result.insertAt(position, iterator)
        endif

sortedBy may have at most one iterator variable.
 

Bag

The standard iterator expression with source of type Bag(T) are:

select

The sub-bag of the source bag for which body is true.

source->select(iterator | body) =
    source->iterate(iterator; result : Bag(T) = Bag{} |
        if body then result->including(iterator)
        else result
        endif)

select may have at most one iterator variable.

reject

The sub-bag of the source bag for which body is false.

source->reject(iterator | body) =
source->select(iterator | not body)

reject may have at most one iterator variable.

collectNested

The Bag of elements which results from applying body to every member of the source bag.

source->collect(iterators | body) =
    source->iterate(iterators; result : Bag(body.type) = Bag{} |
        result->including(body ) )

collectNested may have at most one iterator variable.

sortedBy

Results in the Sequence containing all elements of the source collection. The element for which body has the lowest value comes first, and so on. The type of the body expression must have the < operation defined. The < operation must return a Boolean value and must be transitive i.e. if a < b and b < c then a < c.

source->sortedBy(iterator | body) =
    iterate( iterator ; result : Sequence(T) : Sequence {} |
        if result->isEmpty() then
        result.append(iterator)
        else
            let position : Integer = result->indexOf (
                result->select (item | body (item) > body (iterator)) ->first() )
            in
                result.insertAt(position, iterator)
        endif

sortedBy may have at most one iterator variable.
 

Sequence

The standard iterator expressions with source of type Sequence(T) are:

select(expression : OclExpression) : Sequence(T)

The subsequence of the source sequence for which body is true.

source->select(iterator | body) =
    source->iterate(iterator; result : Sequence(T) = Sequence{} |
        if body then result->including(iterator)
        else result
        endif)

select may have at most one iterator variable.

reject

The subsequence of the source sequence for which body is false.

source->reject(iterator | body) =
    source->select(iterator | not body)

reject may have at most one iterator variable.

collectNested

The Sequence of elements which results from applying body to every member of the source sequence.

source->collect(iterators | body) =
    source->iterate(iterators; result : Sequence(body.type) = Sequence{} |
        result->append(body ) )

collectNested may have at most one iterator variable.

sortedBy

Results in the Sequence containing all elements of the source collection. The element for which body has the lowest value comes first, and so on. The type of the body expression must have the < operation defined. The < operation must return a Boolean value and must be transitive i.e. if a < b and b < c then a < c.

source->sortedBy(iterator | body) =
    iterate( iterator ; result : Sequence(T) : Sequence {} |
        if result->isEmpty() then
            result.append(iterator)
        else
            let position : Integer = result->indexOf (
                    result->select (item | body (item) > body (iterator)) ->first() )
            in
                    result.insertAt(position, iterator)
        endif

sortedBy may have at most one iterator variable.