Download presentation
Presentation is loading. Please wait.
1
Ontologies Reasoning Components Agents Simulations The Object Constraint Language (OCL) Jacques Robin
2
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 Packages OCL Constraints vs. UML Constraints OCL Formal Semantics OCL vs. Java
3
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
4
Uses of OCL for Model-Driven Development: 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
5
Uses of OCL for Model-Driven Development: Formalizing Behavior Specify query operation bodies Specify operation pre and post conditions for design by contract and automated test generation 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
6
OCL: 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
7
OCL: Motivating Examples 1 2 context Flight inv: passengers -> size() <= plane.numberOfSeats context Mortgage inv: security.owner = borrower inv: startDate < endDate context Person inv: Person::allInstances() -> isUnique(socSecNr) context Person::getMortgage(sum:Money,security:House) pre: self.mortgages.monthlyPayment -> sum() <= self.salary * 0.3
8
OCL Expression Context Operation
9
Specifying Initial Property Values and Query Operations Initial values: context LoyaltyAccount::points : integer init: 0 context LoyaltyAccount::transactions : Set(Transaction) init: Set{} Query operations: context LoyaltyAccount::getCustomerName() : String body: Membership.card.owner.name context LoyaltyProgram::getServices(): Set(Services) body: partner.deliveredServices -> asSet()
10
Defining New Attributes and 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()
11
Dot 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
12
Association 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’
13
Generalization 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,000 adds both Earning and Burning points Operator oclIsTypeOf allows hybrid navigation following associations and specialization links context ProgramPartner inv totalPoints: deliveredServices.transactions -> select(oclIsTypeOf(Earning)).points -> sum() < 10,000
14
Specifying 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)
15
Specifying Derivation Rules for 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)) ...
16
Design by Contract: Pre and Postconditions 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
17
Specifying Contractual Interfaces context LoyaltyAccount::isEmpty(): Boolean pre: -- none post: 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):Customer post: 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
18
Disambiguating Association Cycles, Optional Multiplicity and Or Constraints 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 Person inv: 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 Person inv: managedProject -> isEmpty() or performedProject -> isEmpty() context Project inv: projectLeader -> isEmpty() or projectMember -> isEmpty()
19
The OCL meta-model
20
OCL Types
21
Value Types: UML primitive types (including user-defined enumerations) OCL collection types (even of user-defined classifiers, since collections are never processed by changing their states, but only partially copied to create new one) 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
22
OCL Types Primitive data types from UML: boolean, string, integer, unlimitedNatural Reals Type conformance rules: t 1 conforms to t 2 if t 1 <= t 2 in type hierarchy t 1 = collection(t 2 ) conforms to t 3 = collection(t 4 ) if t 2 conforms to t 4 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
23
Links Between OCL and UML Meta-Models
24
Inheritance 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::off post: status = StoveState::off and isOpen context ElectricStove::open() pre: status = StoveState::off and temperature <= 100 post: isOpen
25
Local Variables Let constructor allows creation of aliases for recurring sub-expressions context CustomerCard inv: 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
26
Generic Operators Operators that apply to expressions of any type Defined at the top-level of OclAny
27
Primitive 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)
28
Collections 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
29
Specialized Collection Operators
30
Generic Collection Operators
31
Syntax 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
32
Example of OCL Expressions with 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)
33
Tuples Values can be composed in tuples of types fields of heterogeneous types Tuple { : =,...} 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 { :,...} TupleType {name: String, age = Integer} Convenient to express constraints on data layers using relational model
34
Messages 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
35
Packages 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
36
OCL Constraints vs. 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::plastic inv: type = GuitarType::classic implies strings -> forAll(type = StringType::plastic
37
OCL 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
38
OCL vs. 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;
Similar presentations
© 2024 SlidePlayer.com Inc.
All rights reserved.