
(OCL). OCL allows users to nav igate class diagrams,
to formulate queries, and to restrict class diagrams
with integrity constraints. From a practical perspective,
the OCL may be viewed as an object-oriented version
of the Structured Query Language (SQL) originally
developed for the relational data model. From a theo-
retical perspective, OCL may be viewed as a variant of
first-order predicate logic with quantifiers on finite
domains only. OCL has a well-defined syntax [1,3]
and semantics [2].
Key Points
The central language features in OCL are: naviga-
tion, logical connectives, collections and collection
operations.
Navigation: The navig ation features in OCL allow
users to determine connected objects in the class dia-
gram by using the dot operator ‘‘.’’. Starting with an
expression
expr of start class C, one can apply a
property
propC of class C returning, for example, a
collection of objects of class
D by using the dot opera-
tor:
expr.propC. The expression expr could be a
variable or a single object, for example. The navigation
process can be repeated by writing
expr.propC.
propD
,ifpropD is a propert y of class D.
Logical Connectives: OCL offers the usual logical
connectives for conjunction (
and), disjunction (or),
and negation (
not) as well as the implication
(
implies) and a binary exclusive (xor). An equality
check (=) and a conditional (
if then else endif)is
provided on all types.
Collections: In OCL there are three kinds of collec-
tions: sets, bags, and sequences. A possible collection
element can appear at most once in a set, and the
insertion order in the set does not matter. An element
can appear multiple times in a bag, and the order in
the bag collection does not matter. An element can
appear multiple times in a sequence in which the
order is significant. Bags and sequences can be con-
verted to sets with
->asSet(), sets and sequences to
bags with
->asBag(), and sets and bags to sequen-
ces with
->asSequence(). The conversion to
sequences assumes an order on the elements. The
arrow notation is explained in more detail below.
Collection Operations: There is a large number of
operations on collections in OCL. A lot of convenience
and expressibility is based upon them. The most
important operations on all collection types are the
following:
forAll realizes universal quantification,
exists is existential quantification, select filters
elements with a predicate,
collect applies a term
to each collection element,
size determines the num-
ber of collection elements,
isEmpty tests for empti-
ness,
includes checks whether a possible element is
included in the collection, and
including builds a
new collection
including a new element.
In addition to the central language features, OCL
also has special operations available only on particular
collection, e.g., the operation
at on sequences for
retrieving an element by its position. All collection
operations are applied with the arrow notation men-
tioned above. Roughly speaking, the dot notation
is used when a property follows, i.e., an attribute or a
role follows, and the arrow notation is employed when
a collection operation follows.
Variables in collection operations: Most collection
operations allow variables to be declared (possibly
including a type specification), but the variable may
be dropped if it is not needed.
Retrieving all Current Instances of a Class: Another
important possibility is a feature to retrieve the finite
set of all current instances of a class by appending
.allInstances to the class name. In order to guar-
antee finite results
.allInstances cannot be applied
to data types like
String or Integer.
Return types in collection operations: If the collection
operations are applied to an argument of type
Set/
Bag/Sequence(T)
, they behave as follows: forAll
and exists returns a Boolean, select yields Set/
Bag/Sequence(T)
, collect returns Bag/Bag/
Sequence(T’)
, size gives back Integer, isEmpty
yields Boolean, includes returns Boolean, and
including gives back Set/Bag/Sequence(T).
Most notably, the operation
collect(...)
changes the type of a Set(T) collection to a
Bag(T’) collection. The reason for thi s is that term
inside the
collect may evaluate to the same result for
two different collection elements. In order to reflect
that the result is captured for each collection element,
the result appears as often as a respective collection
element exists. This convention in OCL resembles the
same approach in SQL: SQL queries with the addition-
al keyword
distinct return a set; plain SQL queries
without
distinct return a bag. In OCL, the conven-
tion is similar: OCL expressions using the additional
conversion
asSet() as in collect(...)->asSet
()
return a set; plain collect(...) expressions
without
asSet() return a bag.
1928
O
Object Constraint Language