OCL
The Object Constraint Language — a side-effect-free, declarative expression language for writing precise rules and queries over UML and MOF models.
Created by Jos Warmer (IBM), with contributors to the UML and OMG OCL specifications
OCL, the Object Constraint Language, is a declarative language for writing precise rules and queries about object-oriented models. Where a UML diagram shows the shape of a system — its classes, associations, and multiplicities — OCL captures the conditions that a diagram cannot: that a person’s age is never negative, that a manager earns more than their subordinates, that an account balance equals the sum of its transactions. It is a companion to UML rather than a programming language in the usual sense: OCL expressions are evaluated against a model but never change it.
OCL’s defining rule is that it has no side effects. Evaluating an OCL expression can query any part of a model, traverse its associations, and compute over collections, but it can never modify an object or alter program state. This purity is what lets OCL be embedded safely inside a specification — it describes what must be true without prescribing how to make it so.
History & Origins
OCL grew out of work on Syntropy, a second-generation object-oriented analysis and design method developed by Steve Cook and John Daniels in the mid-1990s. Syntropy included an expression language for stating precise properties of models, and that sublanguage became the seed of OCL.
Around 1995, Jos Warmer and colleagues at IBM refined these ideas into a language for business modeling — a way to write unambiguous business rules that non-programmers could read while remaining formal enough for tools to check. In January 1997, IBM and ObjecTime Limited submitted a joint proposal in response to the OMG’s call for a standard object-oriented analysis and design language. OCL was a centerpiece of that proposal.
That submission was merged with the broader Unified Modeling Language effort, and OCL became IBM’s primary contribution to UML 1.1, adopted by the Object Management Group (OMG) in 1997. From the start, OCL played a dual role: it gave UML users a way to express constraints too detailed for diagrams, and it gave the UML standard itself a rigorous way to state its own well-formedness rules.
Design Philosophy
OCL is built around a small set of commitments that distinguish it sharply from general-purpose programming languages.
- Declarative and side-effect-free. An OCL expression states a fact or asks a question; it never performs an action. This is the property that makes OCL suitable for embedding in specifications, contracts, and metamodels.
- A language of constraints, not computation. OCL’s natural unit is the invariant — a Boolean condition that must hold for all instances of a type — together with operation pre- and post-conditions. It is designed to specify what is true, leaving how to the implementation.
- Navigation over a model. Expressions move through a model by following associations and attributes, in the spirit of “from this object, reach those objects.” The model’s structure is the language’s data.
- Strongly typed. Every OCL expression has a type drawn from the model plus a library of predefined types (booleans, numbers, strings, and a rich family of collections), and expressions are type-checked before evaluation.
Key Features
- Invariants and contracts.
context Person inv: self.age >= 0constrains everyPerson;pre/postconditions on operations specify behavior without implementing it. - Collection types. OCL provides
Set,Bag,OrderedSet, andSequence, with higher-order operations —select,reject,collect,forAll,exists,isUnique,size,sum— that read much like set-builder notation. - Navigation expressions. Following an association yields the related objects; following a one-to-many association yields a collection, which can then be filtered or aggregated.
- A predefined standard library. Booleans, integers, reals, strings, enumerations, and the collection hierarchy come with a documented set of operations defined in the specification.
- Model independence (from OCL 2.0 on). Because OCL 2.0 is defined over MOF, the same language can constrain not just UML class models but any MOF-based metamodel — including domain-specific languages.
A small flavor of OCL, written against a simple model:
-- Invariant: no person may be their own parent
context Person
inv noSelfParent:
self.parents->excludes(self)
-- Invariant: every employee earns at least the minimum wage
context Employee
inv aboveMinimum:
self.salary >= 1500
-- A query over a collection: all adult customers
context Bank
inv:
self.customers->select(c | c.age >= 18)->forAll(c | c.hasAccount)
-- Operation contract using pre/post conditions
context Account::withdraw(amount: Real)
pre: amount > 0 and amount <= self.balance
post: self.balance = self.balance@pre - amount
The -> operator applies collection operations, self refers to the contextual instance, and @pre (in a post-condition) refers to a value as it was before the operation ran — a small but characteristic piece of OCL’s vocabulary for contracts.
Evolution
For its first several years OCL lived inside UML. It appeared in UML 1.1 (1997), and reached version 1.4 as part of UML 1.4 (adopted around 2001). In this era OCL was essentially an annotation layer on UML diagrams, and its semantics were specified informally enough that different tools sometimes disagreed about details.
The major turning point was OCL 2.0, published as a standalone OMG specification (formal/06-05-01, dated May 2006). OCL 2.0 gave the language its own metamodel, recast it as a general object query language in addition to a constraint language, and — crucially — defined it over the common core shared by UML and MOF. From that point OCL could be used to constrain any MOF metamodel, making it a building block of the OMG’s broader Model-Driven Architecture vision. The model-transformation standard QVT adopted OCL as its query and expression sublanguage, and OCL became the de facto query notation across OMG model-driven standards.
Subsequent maintenance releases tracked the evolving UML and MOF standards, culminating in OCL 2.4 (February 2014), aligned with UML 2.4.1 and MOF 2.4.1, which remains the latest formal version.
Current Relevance
OCL occupies a specialized but durable niche in model-driven engineering (MDE). It is rarely written by mainstream application developers, yet it is foundational to the tools and standards those developers’ modeling environments are built on. The Eclipse OCL project (part of the Eclipse Modeling ecosystem) provides a widely used implementation over EMF/Ecore models, and academic toolkits such as Dresden OCL and USE keep the language central to teaching and research in formal modeling and software specification.
Its influence also propagates indirectly. Languages in the Epsilon model-management family (for example, the Epsilon Object Language and its validation language) take clear inspiration from OCL’s navigation-and-collection style, and OCL-like query expressions appear throughout the metamodeling world. The language continues to attract research interest, including modern reimplementations and interpreters that bring OCL semantics to contemporary platforms.
Why It Matters
OCL answers a problem as old as modeling itself: diagrams are wonderful for showing structure and hopeless at expressing precise rules. Multiplicities and associations can say a person has parents; they cannot say a person is not their own ancestor. OCL fills exactly that gap, and it does so with a discipline — declarative, side-effect-free, strongly typed — that lets the same rule be read by a human, checked by a tool, and used to formalize a standard.
Its deepest impact may be reflexive. By being the language in which UML and MOF describe their own correctness, OCL helped move object-oriented modeling from informal pictures toward something with a checkable, machine-readable semantics. That idea — that a modeling language should be precise enough to constrain itself — is OCL’s lasting contribution to how software is specified.
Timeline
Notable Uses & Legacy
OMG UML and MOF specifications
OCL is used inside the standards that define modeling itself: the well-formedness rules (invariants) of the UML and MOF metamodels are written as OCL constraints, giving those standards a precise, machine-checkable semantics that diagrams alone cannot provide.
QVT (Query/View/Transformation)
The OMG's model-transformation standard, QVT, builds its query and expression layer directly on OCL. OCL expressions select and navigate source-model elements when defining how one model is transformed into another.
Eclipse OCL (MDT/OCL)
The Eclipse OCL project provides a reference-grade implementation of the OMG standard for EMF-based models, with APIs to parse and evaluate OCL constraints and queries over Ecore and UML models. It underpins validation in many Eclipse Modeling tools.
Dresden OCL
An academic toolkit from TU Dresden for parsing and evaluating OCL constraints over UML, Java, and SQL models, including type checking and Java/SQL code generation from constraints — widely used in research and teaching.
USE (UML-based Specification Environment)
A specification and validation environment (originating at the University of Bremen) in which a modeler builds system snapshots and the tool automatically checks OCL invariants and pre/post-conditions against each snapshot, surfacing violations graphically and textually.
UML CASE and modeling tools
Commercial and open-source modeling tools — such as Eclipse Papyrus and various UML CASE environments — let designers attach OCL invariants and operation contracts to class models and validate models against them.