38
Ontologi es Reasonin g Component s Agents Simulatio ns The Object Constraint Language The Object Constraint Language (OCL) (OCL) Jacques Robin

The Object Constraint Language (OCL)

  • Upload
    tosca

  • View
    38

  • Download
    0

Embed Size (px)

DESCRIPTION

The Object Constraint Language (OCL). Jacques Robin. Outline. What is OCL? Uses of OCL for Model-Driven Development Motivating examples The OCL meta-model OCL Types OCL Expression Context OCL and Inheritance Primitive Type Operators Local Variables Collections and Tuples Messages - PowerPoint PPT Presentation

Citation preview

Page 1: The Object Constraint Language (OCL)

OntologiesReasoningComponentsAgentsSimulations

The Object Constraint Language The Object Constraint Language (OCL)(OCL)

Jacques Robin

Page 2: The Object Constraint Language (OCL)

OutlineOutline

What is OCL? Uses of OCL for Model-Driven Development Motivating examples The OCL meta-model OCL Types OCL Expression Context OCL and Inheritance Primitive Type Operators Local Variables Collections and Tuples Messages Packages OCL Constraints vs. UML Constraints OCL Formal Semantics OCL vs. Java

Page 3: The Object Constraint Language (OCL)

What is OCL?What is OCL?

A textual specification language to adorn UML diagrams and make a UML model far more semantically precise, detailed and thus productive (i.e., subject to automated processing leading to code).

Characteristics: Formal language with well-defined semantics based on set theory and first-

order predicate logic, yet free of mathematical notation and thus friendly to mainstream programmers

Object-oriented functional language: constructors syntactically combined using functional nesting and object-oriented navigation in expressions that take objects and/or object collections as parameters and evaluates to an object and/or an object collection as return value

Strongly typed language where all expression and sub-expression has a well-defined type that can be an UML primitive data type, a UML model classifier or a collection of these

Semantics of an expression defined by its type mapping Declarative language that specifies what properties the software under

construction must satisfy, not how it shall satisfy them Side effect free language that cannot alter model elements, but only specify

relations between them (some possibly new but not created by OCL expressions)

Pure specification language that cannot alone execute nor program models but only describe them

Both a constraint and query language for UML models

Page 4: The Object Constraint Language (OCL)

Uses of OCL for Model-Driven Uses of OCL for Model-Driven Development: Formalizing StructureDevelopment: Formalizing Structure

Adorn a class diagram in UML structural models or MOF meta-models to make them formally precise

Specify complex constraints (value, multiplicity, type, etc) between multiple attributes and associations

Disambiguate association cycles Specifying rules that define derived attributes, associations and

classes Specify query operation bodies Specify operation pre and post conditions for design by

contract and automated test generation

Page 5: The Object Constraint Language (OCL)

Uses of OCL for Model-Driven Uses of OCL for Model-Driven Development: Formalizing BehaviorDevelopment: Formalizing Behavior

Adorn an interaction diagrams (associated to a class diagram) Specify objects Specify message expressions including guards, iteration and condition

clauses, return value signature Specify guards on lifelines of alternates fragments

Adorn a state machine (associated to a class diagram): Specify trigger and deferred events, guards, state activities Specify object target and parameter values of transition action, state entry

action, state exit action Specify constraints between the state of an object and its other features

(attributes, association ends) Adorn an activity diagram (associated to a class diagram):

Specify transition guards Specify object host and parameter values of actions Specify objects in object flows and their states

Adorn a use case diagram (associated to a class diagram): Specify the pre and post conditions of each use case

Page 6: The Object Constraint Language (OCL)

OCL: Motivating ExamplesOCL: Motivating Examples

Diagram 1 allows Flight with unlimited number of passengers

No way using UML only to express restriction that the number of passengers is limited to the number of seats of the Airplane used for the Flight

Similarly, diagram 2 allows: A Person to Mortgage the house of

another Person A Mortgage start date to be after

its end date Two Persons to share same social

security number A Person with insufficient income to

Mortgage a house

1

2

Page 7: The Object Constraint Language (OCL)

OCL: Motivating ExamplesOCL: Motivating Examples

1

2

context Flightinv: passengers -> size() <= plane.numberOfSeats

context Mortgage inv: security.owner = borrowerinv: startDate < endDate

context Personinv: Person::allInstances() -> isUnique(socSecNr)

context Person::getMortgage(sum:Money,security:House)pre: self.mortgages.monthlyPayment -> sum() <= self.salary * 0.3

Page 8: The Object Constraint Language (OCL)

OCL Expression ContextOCL Expression Context

Operation

Page 9: The Object Constraint Language (OCL)

Specifying Initial Property ValuesSpecifying Initial Property Valuesand Query Operationsand Query Operations

Initial values: context LoyaltyAccount::points : integer

init: 0 context LoyaltyAccount::transactions

: Set(Transaction) init: Set{}

Query operations: context

LoyaltyAccount::getCustomerName() : Stringbody: Membership.card.owner.name

context LoyaltyProgram::getServices(): Set(Services)body: partner.deliveredServices -> asSet()

Page 10: The Object Constraint Language (OCL)

Defining New AttributesDefining New Attributesand Operationsand Operations

New attribute: context Customer

def: initial:String = name.substring(1.1)

New operation: context CustomerCard

def: getTotalPoints(d:Date):Integer = transactions -> select(date.isAfter(d)) .points -> sum()

Page 11: The Object Constraint Language (OCL)

Dot operatorDot operator

Association navigation: context Transaction

def getCustomer():Customer = self.card.owner

Attribute access: context Transaction

def getCustomerName():String = self.card.owner.name

Abbreviation of collect operator that creates new collection from existing one, for example result of navigating association with plural multiplicity:

context LoyaltyAccount inv: transactions -> collect(points) -> exists(p:Integer | p=500)

context LoyaltyAccount inv: transactions.points -> exists(p:Integer | p=500)

Call UML model and OCL built-in operations

Page 12: The Object Constraint Language (OCL)

Association NavigationAssociation Navigation

Use target class name to navigate roleless association: context LoyaltyProgram inv: levels -> includesAll(Membership.currentLevel)

Identify navigation qualifier between []: context LoyaltyProgram inv: self.levels[1].name = ‘basic’

Page 13: The Object Constraint Language (OCL)

Generalization NavigationGeneralization Navigation

OCL constraint to limit points earned from single service to 10,000 Cannot be correctly specified using association navigation: context ProgramPartner inv totalPoints: deliveredServices.transactions .points -> sum() < 10,000adds both Earning and Burning points Operator oclIsTypeOf allows hybrid navigation following associations and specialization linkscontext ProgramPartner inv totalPoints: deliveredServices.transactions -> select(oclIsTypeOf(Earning)) .points -> sum() < 10,000

Page 14: The Object Constraint Language (OCL)

Specifying Invariants on AttributesSpecifying Invariants on Attributes

The context of an invariant constraint is a class

When it occurs as navigation path prefix, the self keyword can be omitted:

context Customer inv: self.name = ‘Edward’

context Customer inv: name = ‘Edward’

Invariants can be named: context Customer inv myInvariant23:

self.name = ‘Edward’ context LoyaltyAccount

inv oneOwner: transaction.card.owner -> asSet() -> size() = 1

In some context self keyword is required: context Membership

inv: participants.cards.Membership.includes(self)

Page 15: The Object Constraint Language (OCL)

Specifying Derivation Rules Specifying Derivation Rules for Attributesfor Attributes

context CustomerCard::printedName derive: owner.title.concat(‘

‘).concat(owner.name) context TransactionReportLine: String

derive self.date = transaction.date ... context TransactionReport

inv dates: lines.date -> forAll(d | d.isBefore(until) and d.isAfter(from))

...

Page 16: The Object Constraint Language (OCL)

Design by Contract: Pre and Design by Contract: Pre and Postconditions on OperationsPostconditions on Operations

A class or interface offers services to other classes through a set of typed public operations

This service can be designed by contract through the specification of the pre-condition and post-condition of each operation

The contract states that: Whenever a client class invokes an operation in way that satisfies

its specified preconditions The server class or interface guarantees that the execution of the

operation will result in the satisfaction of its specified post-conditions

The preconditions thus specify the rights of the server while the post-conditions specify its obligations

Page 17: The Object Constraint Language (OCL)

Specifying Contractual InterfacesSpecifying Contractual Interfaces

context LoyaltyAccount::isEmpty(): Booleanpre: -- nonepost: result = (points = 0)

Keyword @pre used to refer in post-condition to the value of a property before the execution of the operation:

context LoyaltyProgram::enroll(c:Customer)pre: c.name <> ‘ ‘post: participants = participants@pre -> including(c)

Keyword oclIsNew used to specify creation of a new instance (objects or primitive data):

context LoyaltyProgram::enrollAndCreateCustomer(n:String,d:Date):Customerpost: result.oclIsNew() and result.name = n and result.dateOfBirth = d and participant -> includes(result)

oclIsNew only specifies that the operation created the new instance, but not how it did it which cannot be expressed in OCL

Page 18: The Object Constraint Language (OCL)

Disambiguating Association Cycles, Disambiguating Association Cycles, Optional Multiplicity and Or Optional Multiplicity and Or

ConstraintsConstraints Cycles of association with plural multiplicity are

often underconstrained by class diagrams, thus not reflecting actual modeled domain semantics

In the real world a person cannot use the house of another person as security for a mortgage

context Personinv: mortgages.security.owner -> forall(onwner:Person | owner = self)

UML ‘or’ constraint can mean: either that a Person can either manage a Project or

perform a Project but not both or that a Project is managed by one Person or

performed by one Person but not both

OCL invariant disambiguating between these two interpretations:

context Personinv: managedProject -> isEmpty() or performedProject -> isEmpty()

context Projectinv: projectLeader -> isEmpty() or projectMember -> isEmpty()

Page 19: The Object Constraint Language (OCL)

The OCL meta-modelThe OCL meta-model

Page 20: The Object Constraint Language (OCL)

OCL TypesOCL TypesStructuralFeature Classifier

OclMessageType OclModelElementType DataType VoidType

TupleType Primitive CollectionType

SetType SequenceType BagType

OrderedSetType

OperationSignal

+elementType

1

+collectionTypes

0..4

0..*

+type

1

+referredSignal0..1 +referredOperation0..1

Page 21: The Object Constraint Language (OCL)

OCL TypesOCL Types

Value Types: UML primitive types (including user-defined enumerations) OCL collection types (even of user-defined classifiers ?) Their instances never change value

ex, Integer instance 1 cannot be changed to instance 2, nor can string instance “Lew Alcindor” be changed to string instance “Kareem Abdul-Jabbar”, nor can enumeration Grade instance A can be changed to enumeration instance C.

Object types: UML classifiers Their instances can change value, i.e., the Person instance p1 can

have its name attribute “Lew Alcindor” changed to “Kareem Abdul-Jabbar” yet remain the same instance p1

OclAny: Most generic OCL type, subsuming all others General reflective operations are defined for this type and

inherited by all other OCL types

Page 22: The Object Constraint Language (OCL)

OCL TypesOCL Types

Primitive data types (from UML): boolean, string, integer

Type conformance rules: t1 conforms to t2 if t1 <= t2 in type hierarchy

t1 = collection(t2) conforms to t3 = collection(t4) if t2 conforms to t4

integer <= real

Type casting: Operation oclAsType(s) can be invoked on an expression of type g

to recast it as a type s s must conform to g

OclVoid: Undefined value (similar to null values of SQL) Tested by oclIsUndefined operation of OclAny type

Page 23: The Object Constraint Language (OCL)

Links BetweenLinks BetweenOCL and UML Meta-ModelsOCL and UML Meta-Models

ModelElement

Classifier

Constraint

Expression

ExpressionInOcl OclExpression

0..1

+body1

+bodyExpression

1

+constrainedElement

0..*

+constraint

0..*

Page 24: The Object Constraint Language (OCL)

Inheritance and EncapsulationInheritance and Encapsulation

By default, OCL expressions ignore attribute visibility i.e., an expression that access a

private attribute from another class is not syntactically rejected

OCL constraints are inherited down the classifier hierarchy

OCL constraints redefined down the classifier hierarchy must follow substituability principle Invariants and post-condition

can only become more restrictive

Preconditions can only become less restrictive

context Stove inv: temperature <= 200

context ElectricStove inv: temperature <= 300

context Stove::open()pre: status = StoveState::offpost: status = StoveState::off and

isOpen

context ElectricStove::open()pre: status = StoveState::off and

temperature <= 100post: isOpen

Page 25: The Object Constraint Language (OCL)

Local VariablesLocal Variables

Let constructor allows creation of aliases for recurring sub-expressions

context CustomerCardinv: let correctDate : Boolean =

validFrom.isBefore(Date::now) and goodThru.isAfter(Date::now)

in if correctDate then valid = true else valid = false endif

Syntactic sugar that improves constraint legibility

Page 26: The Object Constraint Language (OCL)

Generic OperatorsGeneric Operators

Operators that apply to expressions of any type

Defined at the top-level of OclAny

Page 27: The Object Constraint Language (OCL)

Primitive Type OperatorsPrimitive Type Operators

Boolean: host, parameter and return type boolean Unary: not Binary: or, and, xor, =, <>, implies Ternary: if-then-else

Arithmetic: host and parameters integer or real Comparison (return type boolean): =, <>, <, > <=, >=, Operations (return type integer or real): +, -, *, /, mod, div, abs,

max, min, round, floor

String: host string Comparison (return type boolean): =, <> Operation: concat(String), size(), toLower(), toUpper(),

substring(n:integer,m:integer)

Page 28: The Object Constraint Language (OCL)

CollectionsCollections

Collection constants can be specified in extension: Set{1, 2, 5, 88}, Set{‘apple’, ‘orange’, ‘strawberry’} OrderedSet{‘black’, ‘brown’, ‘red’, ‘orange’, ‘yellow’, ‘green’, ‘blue’,

‘purple’} Sequence{1, 3, 45, 2, 3}, Bag{1, 3, 4, 3, 5}

Sequence of consecutive integers can be specified in intension: Sequence{1..4} = Sequence{1,2,3,4}

Collection operations are called using -> instead of . Collection operations have value types:

They do not alter their input only output a new collection which may contain copies of some input elements

Most collections operations return flattened collections ex, flatten{Set{1,2},Set{3,Set{4,5}}} = Set{1,2,3,4,5}

Operation collectNested must be used to preserve embedded sub-structures

Navigating through several associations with plural multiplicity results in a bag

Page 29: The Object Constraint Language (OCL)

Specialized Collection OperatorsSpecialized Collection Operators

Page 30: The Object Constraint Language (OCL)

Generic Collection OperatorsGeneric Collection Operators

Page 31: The Object Constraint Language (OCL)

Syntax of Loop OperatorsSyntax of Loop Operators

Loop operators (aka. iterator operations, aka. iterators) Common characteristics:

They are all hosted by an OCL expression of type collection They all take an OCL expression as input parameter (called the

body of the loop) They optionally take as second parameter an iterator variable The return type of the body expression and the type of the iterator

variable must conform to the type of the host collection’s elements Loop operators iterate over the elements of the host collection,

applying the body expression to each one of them Distinguishing characteristics:

How they combine the body expression application into a new result collection

Page 32: The Object Constraint Language (OCL)

Example of OCL Expressions Example of OCL Expressions with Loop Operatorswith Loop Operators

context LoyaltyProgram inv self.Membership.account -> isUnique(acc: LoyaltyAccount | acc.number) context LoyaltyProgram inv Membership.account -> isUnique(acc | acc.number) context LoyaltyProgram inv Membership.account -> isUnique(number) Iterator variable clarifies that number refers to the number attribute of each collection element and not to the number of elements in the collection Loop expressions with reference to the iterator requires an iterator variable: context ProgramPartner inv: self.programs.partners -> select(p:ProgramPartner | p.self)

Page 33: The Object Constraint Language (OCL)

TuplesTuples

Values can be composed in tuples of types fields of heterogeneous types

Tuple {<fieldName>: <TypeExpression> = <ValueExpression>, ...}

Tuple {name: String = ‘John’, age: Integer = 10} Tuple {a: Collection(Integer) = Set{1,2,7}, b: String = ‘foo’}

Tuple types can be specified using same syntax without value expression:

TupleType {<fieldName>: <TypeExpression>, ...} TupleType {name: String, age = Integer} Convenient to express constraints on data layers using

relational model

Page 34: The Object Constraint Language (OCL)

MessagesMessages

isSent ^ operator in an operation post-condition, specifies which messages (operation calls or signals) must be sent by the execution of the operation

context Subject::hasChanged() post: observer^update(12,14) ? can be used to specify unknown messages of a given type context Subject::hasChanged()

post: observer^update(? :integer, ? :integer) In addition to their base types, all messages sent are also instances of

the special type OclMessage Message operator ^^ allows performing pattern matching on sent

messages context Subject::hasChanged()

post: let messages: Sequence(OclMessage) = observers -> collect(o | o^^update(? :integer, ? :integer)) in messages -> notEmpty()

Other message operators: Booleans isSignalSent(), isOperationCall(), hasReturned() result() returns type of called operation

Page 35: The Object Constraint Language (OCL)

PackagesPackages

OCL expressions can be structured in packages and sub-packages

Package can be specified inside a context specification: context P::S::C inv ... context P::S::C::op() pre: ... post: ...

Or with keyword pair package, endpackage surrounding set of expressions: package P::S context X inv: ... context X::op pre: ... post: ... endpackage

Page 36: The Object Constraint Language (OCL)

OCL Constraints OCL Constraints vs.vs. UML Constraints UML Constraints

context ElectricGuitar inv: strings -> forAll(s \ s.oclIsType(MetalStrings))

context: ClassicalGuitar inv: strings-> forAll(s | s.oclIsType(plasticStrings))

context ElectricGuitar inv: strings -> forAll(type = StringType::metal)

context ClassicGuitar inv: strings -> forAll(type = StringType::plastic)

context Guitar inv: type = GuitarType::classic implies strings -> forAll(type = StringType::plasticinv: type = GuitarType::classic implies strings -> forAll(type = StringType::plastic

Page 37: The Object Constraint Language (OCL)

OCL Formal SemanticsOCL Formal Semantics

Set theoretic Semantic domain for each OCL type defined by its set of

possible values Semantics of an OCL expression defined by the mathematical

function mapping the semantic domains of its host and input parameters to its return value

Page 38: The Object Constraint Language (OCL)

OCL OCL vs.vs. Java Java Declarative specification of operation post-conditions in OCL is far more concise

than corresponding implementation in mainstream imperative OO language such as Java

This is due mainly to OCL’s powerful collection operators Example: OCL expression

self.partners -> select(deliveredServices -> forAll(pointsEarned = 0)) Corresponding Java code:1. Iterator it = this.getPartners().iterator();2. Set selectResult = new HashSet(); 3. while( it.hasNext() ){ 4. ProgramPartner p = (ProgramPartner) it.next(); 5. Iterator services = p.getDeliveredServices().iterator(); 6. boolean forAllresult = true; 7. while( services.hasNext() ){ 8. Service s = (Service) services.next(); 9. forAllResult = forAllResult && (s.getPointsEarned() == 0); 10. } 11. if ( forAllResult ){ 12. selectResult.add(p); 13. } 14. } 15. return result;