Skip to content

OCL Feature Compatibility Matrix ​

This page provides a comprehensive overview of OCL (Object Constraint Language) features supported by ocl.js compared to the OMG OCL 2.4 specification.

Overall Coverage

OCL.js implements approximately 78% of common OCL operations, with excellent coverage of core functionality.

Legend ​

  • βœ… Implemented - Feature is fully implemented and tested
  • ❌ Not Implemented - Feature is not currently available
  • πŸ”§ Partial - Feature is partially implemented or has limitations

Collection Operations ​

Implemented βœ… ​

OperationSyntaxDescriptionExample
selectcollection->select(expr)Filters elements matching conditionpersons->select(age > 18)
rejectcollection->reject(expr)Filters elements not matching conditionpersons->reject(age < 18)
collectcollection->collect(expr)Maps/transforms each elementpersons->collect(name)
forAllcollection->forAll(expr)Universal quantifier - all must satisfypersons->forAll(age >= 0)
existscollection->exists(expr)Existential quantifier - at least one satisfiespersons->exists(age > 100)
anycollection->any(expr)Returns first element matching expressionpersons->any(name = 'John')
onecollection->one(expr)Exactly one element must satisfypersons->one(isAdmin = true)
isUniquecollection->isUnique(expr)Checks if all elements are uniquepersons->isUnique(email)
sizecollection->size()Returns number of elementspersons->size()
isEmptycollection->isEmpty()Returns true if emptypersons->isEmpty()
notEmptycollection->notEmpty()Returns true if not emptypersons->notEmpty()
sumcollection->sum()Sums numeric elementsprices->sum()
unioncollection->union(c)Combines two collectionsset1->union(set2)
appendcollection->append(element)Adds element to endlist->append(newItem)
asSetcollection->asSet()Converts to set (removes duplicates)collection->asSet()
atcollection->at(index)Returns element at index (1-based)list->at(1)
firstcollection->first()Returns first elementlist->first()
lastcollection->last()Returns last elementlist->last()
includescollection->includes(object)Tests if element exists in collectioncollection->includes(42)
includesAllcollection->includesAll(c)Tests if all elements from c exist in collectioncollection->includesAll(subset)
excludescollection->excludes(object)Tests if element does not exist in collectioncollection->excludes(99)
excludesAllcollection->excludesAll(c)Tests if no elements from c exist in collectioncollection->excludesAll(forbidden)

Not Implemented ❌ ​

OperationSyntaxDescription
includingcollection->including(object)Adds element (immutable)
excludingcollection->excluding(object)Removes element (immutable)
intersectioncollection->intersection(c)Set intersection
symmetricDifferencecollection->symmetricDifference(c)Elements in either but not both
flattencollection->flatten()Flattens nested collections
countcollection->count(object)Counts occurrences of object
sortedBycollection->sortedBy(expr)Sorts collection by expression
closurecollection->closure(expr)Transitive closure
iteratecollection->iterate(...)General-purpose iterator
collectNestedcollection->collectNested(expr)Collect without flattening
selectByKindcollection->selectByKind(Type)Filters by type with inheritance
selectByTypecollection->selectByType(Type)Filters by exact type
productcollection->product(c)Cartesian product

String Operations ​

Implemented βœ… ​

OperationSyntaxDescriptionExample
sizestring.size()Returns string length'hello'.size() = 5
concatstring.concat(s)Concatenates strings'hello'.concat(' world')
substringstring.substring(start, end)Extracts substring (1-based)'hello'.substring(2, 4) = 'ell'
toUpperCasestring.toUpperCase()Converts to uppercase'hello'.toUpperCase()
toLowerCasestring.toLowerCase()Converts to lowercase'HELLO'.toLowerCase()
indexOfstring.indexOf(s)Returns 1-based index or 0 if not found'hello'.indexOf('ll') = 3
toIntegerstring.toInteger()Converts to integer'42'.toInteger()
toRealstring.toReal()Converts to real number'3.14'.toReal()
charactersstring.characters()Returns sequence of characters'hello'.characters()
equalsIgnoreCasestring.equalsIgnoreCase(s)Case-insensitive comparison'Hello'.equalsIgnoreCase('hello')
toBooleanstring.toBoolean()String to boolean conversion'true'.toBoolean()
lastIndexOfstring.lastIndexOf(s)Last occurrence index'hello'.lastIndexOf('l')
replacestring.replace(old, new)Replaces first occurrence'hello world'.replace('world', 'OCL')
replaceAllstring.replaceAll(old, new)Replaces all occurrences'foo foo'.replaceAll('foo', 'bar')
matchesstring.matches(regex)Regular expression matching'hello123'.matches('[a-z]+')
trimstring.trim()Remove leading/trailing whitespace' hello '.trim()
startsWithstring.startsWith(s)Tests if string starts with prefix'hello'.startsWith('he')
endsWithstring.endsWith(s)Tests if string ends with suffix'hello'.endsWith('lo')
atstring.at(index)Returns character at 1-based index'hello'.at(1) = 'h'

Math / Numeric Operations ​

Implemented βœ… ​

OperationSyntaxDescriptionExample
Additiona + bAddition5 + 3 = 8
Subtractiona - bSubtraction5 - 3 = 2
Multiplicationa * bMultiplication5 * 3 = 15
Divisiona / bReal division5 / 2 = 2.5
Integer Divisiona div bInteger division (floor)5 div 2 = 2
Moduloa mod bRemainder5 mod 2 = 1
Powera ^ bExponentiation2 ^ 3 = 8
absnumber.abs()Absolute value(-5).abs() = 5
sqrtnumber.sqrt() or number.sqrt(n)Square root or nth root9.sqrt() = 3
roundnumber.round()Rounds to nearest integer3.7.round() = 4
maxa.max(b)Maximum of two numbers5.max(3) = 5
mina.min(b)Minimum of two numbers5.min(3) = 3
floornumber.floor()Floor function (largest integer ≀ self)3.7.floor() = 3
ceilnumber.ceil()Ceiling function (smallest integer β‰₯ self)3.2.ceil() = 4
toStringnumber.toString()Number to string conversion42.toString() = '42'

Not Implemented ❌ ​

OperationSyntaxDescription
oclAsTypeobject.oclAsType(Type)Type casting
oclIsInvalidobject.oclIsInvalid()Check for invalid value
oclIsNewobject.oclIsNew()Check if object is newly created
allInstancesType.allInstances()Get all instances of a type

All Implemented βœ… ​

OperationSyntaxDescriptionExample
Property Accessobject.propertyDirect property navigationself.name
Nested Navigationobject.a.b.cDeep property accessself.company.address.city
Collection Flatteningcollection.propertyAuto-flattens when navigating through collectionsself.employees.name
Array Indexingarray[index]Array element access (0-based)self.items[0]

Context & Constraint Operations ​

All Implemented βœ… ​

OperationSyntaxDescriptionExample
contextcontext TypeDefines constraint contextcontext Person
invinv: expressionInvariant constraintinv: age >= 0
inv (named)inv name: expressionNamed invariantinv positiveAge: age >= 0
prepre: expressionPreconditionpre: amount > 0
postpost: expressionPostconditionpost: balance = balance@pre - amount
initinit: expressionInitial value constraintinit: 0
derivederive: expressionDerived valuederive: firstName + ' ' + lastName
defdef: name = expressionHelper definitionsdef: isAdult = age >= 18
Classifier Contextcontext ClassNameClass-level contextcontext Person inv: ...
Operation Contextcontext Type::operation()Operation-level contextcontext Person::rename(n: String)
Property Contextcontext Type::propertyProperty-level contextcontext Person::age

Control Flow ​

All Implemented βœ… ​

OperationSyntaxDescriptionExample
if-then-elseif cond then expr1 else expr2 endifConditional expressionif age >= 18 then 'adult' else 'minor' endif
letlet var = expr in bodyLocal variable bindinglet discount = 0.1 in price * (1 - discount)

Literal Values ​

Implemented βœ… ​

TypeSyntaxExample
Booleantrue, falsetrue, false
Integer42, -542, -5, 0
Real3.14, -2.53.14, -2.5
String'text' or "text"'hello', "world"
Nullnullnull

Not Implemented ❌ ​

TypeSyntaxDescription
TupleTuple{a=1, b=2}Tuple literals
SetSet{1,2,3}Set literal
SequenceSequence{1,2,3}Ordered collection literal
BagBag{1,1,2}Bag (multiset) literal

Special Features ​

Implemented βœ… ​

FeatureDescriptionExample
Enumeration AccessAccess enum valuesColor::RED
Native JS Function CallsFallback to JavaScript methodsNative method invocation on JS objects
CommentsSingle and multi-line comments-- comment or /* comment */
Metamodel ProviderCustom type system integrationSee Metamodel Provider Guide
Package DeclarationsPackage namespacingpackage MyPackage
Multiple IteratorsMultiple variables in iteratorscollection->forAll(x, y | x <> y)

Usage Examples ​

Collection Operations ​

ocl
-- Filter adults
context Company inv:
  self.employees->select(age >= 18)->notEmpty()

-- Check all employees have unique emails
context Company inv:
  self.employees->isUnique(email)

-- Calculate total salary
context Company inv:
  self.employees->collect(salary)->sum() <= budget

-- Check if specific employee exists
context Company inv:
  self.employees->collect(id)->includes(self.managerId)

-- Validate required skills are present
context Developer inv:
  self.skills->includesAll(self.project.requiredSkills)

String Operations ​

ocl
-- Name validation
context Person inv:
  self.name.size() > 0 and
  self.name.toUpperCase() = self.name.toUpperCase()

-- Email format check
context Person inv:
  self.email.indexOf('@') > 0

Type Operations ​

ocl
-- Type checking with inheritance
context Employee inv:
  self.oclIsKindOf(Person)

-- Exact type check
context Manager inv:
  self.oclIsTypeOf(Manager)

Control Flow ​

ocl
-- Age-based discount
context Person def:
  discount: Real = if age >= 65 then 0.2 else 0.0 endif

-- Complex calculation with let
context Order def:
  totalPrice: Real = 
    let basePrice = items->collect(price)->sum() in
    let discount = if customer.isPremium then 0.1 else 0.0 endif in
    basePrice * (1 - discount)

Summary Statistics ​

CategoryImplementedNot ImplementedCoverage
Collection Operations221363%
String Operations190100%
Math Operations150100%
Comparison Operations60100%
Boolean Operations50100%
Type Operations3443%
Navigation40100%
Context/Constraints100100%
Control Flow20100%
Literals4267%
Overall9125~78%

Released under the MIT License.