Disclaimer -- Opinions expressed here may be Out of Date
This page documents my understanding of the syntax and some of the
semantics of the OCL.
This description is based on the 1997 version 1.1 and certain 1999 version
1.3 updates. The latest version is
2.0 (2006/05/01, 232 pages of PDF)
and is under revision by the OMG (see below).
See Also
The Object Management Group (OMG)
[ OCL in modeling_spec_catalog ]
maintains the standard.
The Wikipedia [ Object_Constraint_Language ] has a very short introduction to the OCL. The WikiWikiWeb [ wiki?ObjectConstraintLanguage ] has a short discussion and some links.
IBM holds a useful page [ ocl.html ] about the OCL which includes links to a parser(Java in a .zip file) and a specification of the language in Adobe PDF format. More information can be found at [ index.htm ] the Klasse Objecten Home.
score > 88.33 and score <= 93.33
gender = #female or gender = #male
p implies q
left xor right
next->isEmpty or value <= next.value
self.grading and self.questions->size<10
p1 <> p2 implies p1.name <> p2.name
Student.allInstances->forAll( p1, p2 | p1 <> p2 implies p1.name <> p2.name )
score > 88.33
value <= next.value
self.questions->size<10
golgafrensham + 42
golgafrensham - 42
self.questions->size+1
2 * head
22 / 7
20*self.questions->size
- prefect
not ford
not self.questions->isEmpty
self.questions
employees->includes(#dent)
self.questions->size
self.employer->size
self.employer->includes(self)
self.employee->select (v | v.wages>10000 )->size
Student.allInstances->forAll( p1, p2 | p1 <> p2 implies p1.name <> p2.name )
42
self
#dent
employer@pre
MyClass::myMethod(myArgument)
self.employee->exists (v | v = self )
Student.allInstances
if name = 'beeblebrox' then body->count(head) = 2 endif
( 42, #dent, x, self, 'beeblebrox')
( v:people | v.height < 6 )
( p1, p2 | p1 <> p2 implies p1.name <> p2.name )
'beeblebrox'
42
#dent
enum{ #female, #male }
Set { 1 , 2 , 5 , 88 }
Set { 'apple' , 'orange', 'strawberry' }
Sequence { 1, 3, 45, 2, 3 }
Sequence { 'ape', 'nut' }
Sequence{ 10..24 }
Bag {1 , 3 , 4, 3, 5 }
12,13,15
12..15
MyClass::myAttribute
@pre
1+1, 2, 3
. . . . . . . . . ( end of section Syntax) <<Contents | End>>
Notes
-- this is a comment
context Student
inv: self.age >= 0
context Typename::operationName(parameter1 : Type1, ... ): ReturnType
pre : parameter1 > ...
post: result = ...(In an early version the context was underlined and the word "context" not used).
In a post condition use "@pre" to indicate the value before the operation and "result" is the value returned.
Operation Bodies
These can be specified like this
context Typename::operationName(parameter1 : Type1, ... ): ReturnType
pre: some precondition
body: expression representing the body of the operation
context Typename::propertyName: Type
init: expression representing the initial value
context Typename::propertyName: Type
derive: expression representing the initial value
. . . . . . . . . ( end of section Using the OCL) <<Contents | End>>
Special Symbols
self.numberOfEmployeesIn most cases, self can be left out, because the context is clear, as in the above examples.
let variable : type = expression.
OCL Types
Each class in a model that uses the UML defines a new type. There are
other predefined types:
OCL Types have the following features:
Navigation
Starting from a specific object (or a path_name), we can navigate an association on the
class diagram to refer to other objects and their properties. To do so, we
navigate the association by using the opposite association-end:
object.rolename[ primary_expression ]
The value of this expression is the set of objects on the other side of the role name association. If the multiplicity of the association-end has a maximum of one ("0..1" or "1"), then the value of this expression is an object. If the multiplicity is "0..1" then the result is an empty set if there is no object, otherwise it is the unique objet.
Navigation expression generate Collections of objects. By default, navigation will result in a Set. When the association on the Class Diagram is adorned with {ordered}, the navigation results in a Sequence. Collections, like Sets, Bags and Sequences, are predefined types in OCL. They have a large number of predefined operations on them.
collection->operation(arguments)
An object can occur at most once in a Set but many times in a Bag. It occurs at a particular position in Sequence. See literal_collection in the grammar above.
Given a typename T then T.allInstances is the Set of all objects of type T.
Operations on Collections
Collections have many useful properties. These are added to the OCL
to give it the power of symbolic logic (LPC) and naive set theory.
Properties of collections are accessed by using an arrow '->' followed by the name of the property. There are many of these. They seem to have been borrowed from Smalltalk [Smalltalk_methods].
Many of the properties of collections result in collections. This means that they can be chained together:
self.employee->select (v | v.wages>10000 )->sizeSee postfix_expression in the grammar above.
The following is a list of some of the commonest ones.
(filters): select, reject, collect, etc
(sets): includes, excludes, union, intersection, including, and
excluding. Compare with set_theory. Plus (new in 1.3) unique, excludes, excludesAll
Two exceptions are the boolean operators and + or:
Notice, that if-then-else-endif does not evaulate all its arguments and so can be used to avoid an undefined object. In later OCL versions
oclUndefined()will recognize an undefined object and return True otherwise it returns False.
self.employee->collect(birthdate)is normally written
self.employee.birthdateand it means all the employee's birthdates.
. . . . . . . . . ( end of section Notes) <<Contents | End>>
. . . . . . . . . ( end of section The Object Constraint Language) <<Contents | End>>