Upload
others
View
28
Download
0
Embed Size (px)
Citation preview
Object Constraint Language (OCL)
• A UML diagram (e.g., a class diagram) does not provide all relevants aspects ofa specification
• It is necessary to describe additional constraints about the objects in the model
• Constraints specify invariant conditions that must hold for the system beingmodeled
• Constraints are often described in natural language and this always result inambiguities
• Traditional formal languages allow to write unambiguous constraints, but theyare difficult for the average system modeler
• OCL: Formal language used to express constraints, that remains easy to readand write
1
Object Constraint Language (OCL)
• Pure expression language: expressions do not have side effet
3 when an OCL expression is evaluated, it returns a value
3 its evaluation cannot alter the state of the corresponding executing system
3 an OCL expression can be used to specify a state change (e.g., in a post-condition)
• Not a programming language
3 it is not possible to write program logic or flow of control in OCL
3 cannot be used to invoke processes or activate non-query operations
• Typed language: each expression has a type
3 well-formed expressions must obey the type conformance rules of OCL
3 each classifier defined in a UML model represents a distinct OCL type
3 OCL includes a set of supplementary predefined types
• The evaluation of an OCL expression is instantaneous
3 the state of objects in a model cannot change during evaluation
2
Object Constraint Language, May 12, 2008 – 1
Where to Use OCL
• To specify invariants on classes and types in the class model
• To specify type invariants for stereotypes
• To describe pre- and post-conditions on operations and methods
• To describe guards
• As a navigation language
• To specify constraints on operations
• OCL is used to specify the well-formedness rules of the UML metamodel
3
Basic Values and Types
• A number of basic types are predefined in OCL
• Examples of basic types and their values
Type ValuesBoolean true, falseInteger 1, -5, 2564, ...Real 1.5, 3.14, ...String ‘To be or not to be’, ...
• A number of operations are defined on the predefined types
Type OperationsBoolean and, or , xor, not, implies, if-then-else-endifInteger +, -, *, /, abs, div, mod, max, minReal +, -, *, /, abs, floor, round, max, min, <, >, <=, >=String size, concat, substring, toInteger, toReal
4
Object Constraint Language, May 12, 2008 – 2
Collections
• Collection: an abstract type with four concrete collection types
3 Set: the mathematical set (without duplicate elements)Set {1 , 2 , 5} Set {‘apple’, ‘orange’, ‘strawberry’}
3 OrderedSet: a set in which the elements are ordered by their positionOrderedSet {5, 4, 3, 2, 1}
3 Bag: a set that may contain duplicate elementsBag {1, 2, 5, 2}
3 Sequence: a bag in which the elements are orderedSequence {1, 2, 5, 10} Sequence {‘ape’, ‘nut’}
• Notation ‘..’ used for a sequence of consecutive integers
3 Sequence {1..5} is the same as Sequence {1, 2, 3, 4, 5}
• Elements of collections may be collections themselvesSet { Sequence {1, 2, 3, 4}, Sequence {5, 6} }
• Collections have a set of predefined operations
3 They are accessed using the -> notation
5
Common Operations for All Collections
• C, C1, C2 are values of type Collection(t), v is a value of type t
Signature Semanticssize Collection(t)→ Integer | C |count Collection(t)× t→ Integer | C ∩ {v} |includes Collection(t)× t→ Boolean v ∈ C
excludes Collection(t)× t→ Boolean v 6∈ C
includesAll Collection(t)× Collection(t)→ Boolean C2 ⊆ C1
excludesAll Collection(t)× Collection(t)→ Boolean C2 ∩ C1 = ∅isEmpty Collection(t)→ Boolean C = ∅notEmpty Collection(t)→ Boolean C 6= ∅sum Collection(t)→ t
∑|C|i=1 vi
6
Object Constraint Language, May 12, 2008 – 3
Set Operations
• S, S1, S2 are values of type Set(t), B is a value of type Bag(t), v is a value oftype t
Signature Semanticsunion Set(t)× Set(t)→ Set(t) S1 ∪ S2
union Set(t)× Bag(t)→ Bag(t) S ∪B
intersection Set(t)× Set(t)→ Set(t) S1 ∩ S2
intersection Set(t)× Bag(t)→ Set(t) S ∩B
- Set(t)× Set(t)→ Set(t) S1 − S2
symmetricDifference Set(t)× Set(t)→ Set(t) (S1 − S2) ∪ (S2 − S1)including Set(t)× t→ Set(t) S ∪ {v}excluding Set(t)× t→ Set(t) S − {v}asSet Set(t)→ Set(t)asOrderedSet Set(t)→ OrderedSet(t)asBag Set(t)→ Bag(t)asSequence Set(t)→ Sequence(t)
• Operations asOrderedSet and asSequence are nondeterministic⇒ Result contains the elements of the source set in arbitrary order
7
Bag Operations
• B, B1, B2 are values of type Bag(t), S is a value of type Set(t), v is a value oftype t
Signature Semanticsunion Bag(t)× Bag(t)→ Bag(t) B1 ∪B2
union Bag(t)× Set(t)→ Bag(t) B ∪ S
intersection Bag(t)× Bag(t)→ Bag(t) B1 ∩B2
intersection Bag(t)× Set(t)→ Set(t) B ∩ S
including Bag(t)× t→ Bag(t) S ∪ {{v}}excluding Bag(t)× t→ Bag(t) S − {{v}}asSet Bag(t)→ Set(t)asOrderedSet Bag(t)→ OrderedSet(t)asBag Bag(t)→ Bag(t)asSequence Bag(t)→ Sequence(t)
8
Object Constraint Language, May 12, 2008 – 4
Sequence Operations
• S, S1, S2 are values of type Set(t), v is a value of type t, operator ◦ denotesthe concatenation of lists, πi(S) projects the ith element of a sequence S, πj
i (S)is the subsequence of S from the ith to the jth element
Signature Semanticsunion Sequence(t)× Sequence(t)→ Sequence(t) S1 ◦ S2
append Sequence(t)× t→ Sequence(t) S ◦ 〈v〉prepend Sequence(t)× t→ Sequence(t) 〈v〉 ◦ S
subSequence Sequence(t)× Integer× Integer→ Sequence(t)
πji (S)
at Sequence(t)× Integer→ Sequence(t) πi(S)first Sequence(t)→ t π1(S)last Sequence(t)→ t π|S|(S)including Sequence(t)× t→ Sequence(t) S ◦ 〈v〉excluding Sequence(t)× t→ Sequence(t) S − {v}asSet Sequence(t)→ Set(t)asOrderedSet Sequence(t)→ OrderedSet(t)asBag Sequence(t)→ Bag(t)asSequence Sequence(t)→ Sequence(t)
9
Type Conformance
• OCL is a typed language, the basic value types are organized in a type hierarchy
• The hierarchy determines conformance of the different types to each other
• Type type1 conforms with type type2 when an instance of type1 can besubstituted at each place where an instance of type2 is expected
• Valid expression: OCL expression in which all types conform
10
Object Constraint Language, May 12, 2008 – 5
Type Conformance Rules
• Type1 conforms to Type2 when they are identical
• Type1 conforms to Type2 when it is a subtype of Type2
• Collection(Type1) conforms to Collection(Type2) when Type1 conforms toType2
• Type conformance is transitive: if type1 conforms with type2 and type2 con-forms with type3, then type1 conforms with type3
• Example: If Bicycle and Car are subtypes of Transport
3 Set(Bicycle) conforms to Set(Transport)
3 Set(Bicycle) conforms to Collection(Bicycle)
3 Set(Bicycle) conforms to Collection(Transport)
3 Set(Bicycle) does not conform to Bag(Bicycle)
11
Class Diagram Example
Bank
accountNo: Integer
firstName: StringlastName: Stringgender: GenderbirthDate: Dateage: IntegerisMarried: BooleanmaidenName: String [0..1]isUnemployed: Boolean
Person
0..*
0..1customer
income(): IntegercurrentSpouse(): Persondescendants(): Set
husband
wife
0..*
0..*
name:String/noEmployees: Integer
Company
stockPrice(): RealhireEmployee(p: Person)
manager managedCompanies
0..*1
employee employer
0..*0..*
title: StringstartDate: Datesalary: Integer
Job
place: Stringdate: Dateended: Boolean
Marriage
malefemale
«enumeration»Gender
children
parents
0..1
0..*
12
Object Constraint Language, May 12, 2008 – 6
Comments, Infix Operators
Comments
• Denoted by --
-- this is a comment
Infix Operators
• Use of infix operators (e.g., +, -, =, <, . . .) is allowed
• Expression a + b is conceptually equivalent to a.+(b), i.e., invoking the + op-eration on a with b as parameter
• Infix operators defined for a type must have exactly one parameter
13
Context and Self
• All classifiers (types, classes, interfaces, associations, datatypes, . . .) from anUML model are types in the OCL expressions that are attached to the model
• Each OCL expression is written in the context of an instance of a specific typecontext Person...
• Reserved word self is used to refer to the contextual instance
• If the context is Person, self referes to an instance of Person
14
Object Constraint Language, May 12, 2008 – 7
Object and Properties
• All properties (attributes, association ends, methods and operations withoutside effects) defined on the types of a UML model can be used in OCL expressions
• The value of a property of an object defined in a class diagram is specified by adot followed by the name of the property
• If the context is Person, self.age denotes the value of attribute age on theinstance of Person identified by self
• The type of the expression is the type of attribute age, i.e., Integer
• If the context is Company, self.stockPrice() denotes the value of operationstockPrice on the instance identified by self
• Parentheses are mandatory for operations or methods, even if they do not haveparameters
15
Invariants
• Determine a constraint that must be true for all instances of a type
• Value of attribute noEmployees in instances of Company must be less than orequal to 50
context Company inv:self.noEmployees <= 50
• Equivalent formulation with a c playing the role of self, and a name for theconstraint
context c: Company inv SME:c.noEmployees <= 50
• The stock price of companies is greater than 0context Company inv:self.stockPrice() > 0
16
Object Constraint Language, May 12, 2008 – 8
Pre- and Post-conditions
• Constraints associated with an operation or other behavioral feature
• Pre-condition: Constraint assumed to be true before the operation is executed
• Post-condition: Constraint satisfied after the operation is executed
• Pre- and post-conditions associated to operation income in Person
context Person::income(): Integerpre: self.age >= 18post: result < 5000
• self is an instance of the type which owns the operation or method
• result denotes the result of the operation, if any
• Type of result is the result type of the operation (Integer in the example)
• A name can be given to the pre- and post-conditionscontext Person::income(): Integerpre adult: self.age >= 18post resultOK: result < 5000
17
Previous Values in Postconditions
• In a postcondition, the value of a property p is the value upon completion of theoperation
• The value of p at the start of the operation is referred to as p@precontext Person::birthDayHappens()post: age = age@pre + 1
• For operations, ‘@pre’ is postfixed to the name, before the parameterscontext Company::hireEmployee(p: Person)post: employee = employee@pre->including(p) and
stockPrice() = stockPrice@pre() + 10
• The ‘@pre’ postfix is allowed only in postconditions
• Accessing properties of previous object values
3 [email protected]: the new value of c of the old value of b of a
3 [email protected]@pre: the old value of c of the old value of b of a
18
Object Constraint Language, May 12, 2008 – 9
Body Expression
• Used to indicate the result of a query operation
• Income of a person is the sum of the salaries of her jobscontext Person::income(): Integerbody: self.job.salary->sum()
• Expression must conform to the result type of the operation
• Definition may be recursive: The right-hand side of the definition may refer tothe operation being defined
• A method that obtains the direct and indirect descendants of a personcontext Person::descendants(): Setbody: result = self.children->union(
self.children->collect(c | c.descendants()) )
• Pre-, and postconditions, and body expressions may be mixed together after oneoperation context
context Person::income(): Integerpre: self.age >= 18body: self.job.salary->sum()post: result < 5000
19
Let Expression
• Allows to define a variable that can be used in a constraintcontext Person inv:let numberJobs: Integer = self.job->count() inif isUnemployed then
numberJobs = 0else
numberJobs > 0endif
• A let expression is only known within its specific expression
20
Object Constraint Language, May 12, 2008 – 10
Definition Expressions
• Enable to reuse variables or operations over multiple expressions
• Must be attached to a classifier and may only contain variable and/or operationdefinitions
context Persondef: name: String = self.firstName.concat(‘ ’).concat(lastName)def: hasTitle(t: String): Boolean = self.job->exists(title = t)
• Names of the attributes/operations in a def expression must not conflict withthe names of attributes/association ends/operations of the classifier
21
Initial and Derived Values
• Used to indicate the initial or derived value of an attribute or association end
• Attribute isMarried in Person is initialized to false
context Person::isMarried: Booleaninit: self.isMarried = false
• Attribute noEmployees in Company is a derived attributecontext Company::noEmployees: Integerderive: self.employee->size()
• For an attribute: expression must conform to the attribute type
• For an association end: conformance depends on multiplicity
3 at most one: expression must conform to the classifier at that end
3 may be more than one: expression must conform to Set or OrderedSet
22
Object Constraint Language, May 12, 2008 – 11
Enumeration Types
malefemale
«enumeration»Gender
gender: GenderisMarried: BooleanmaidenName: String [0..1]...
Person
• Define a number of literals that are the possible values of the enumeration
• An enumeration value is referred as in Gender::female
• Only married women can have a maiden namecontext Person inv:self.maidenName <> ‘’ impliesself.gender = Gender::female and self.isMarried = true
23
Packages
• Within UML, types are organized in packages
• Previous examples supposed that the package in which the classifier belongs isclear from the environment
• The package and endpackage statements can be used to explicitly specify thispackage Package::SubPackage
context X inv:... some invariant ...
context X::operationName(...): ReturnTypepre: ... some precondition ...
endpackage
• For referring to types in other packages the following notations may be usedPackagename::TypenamePackagename1::Packagename2::Typename
24
Object Constraint Language, May 12, 2008 – 12
Undefined Values
• One or more subexpressions in an OCL expression may be undefined
• In this case, the complete expression will be undefined
• Exceptions for Boolean operators
3 true or anything is true
3 false and anything is false
3 false implies anything is true
3 anything implies true is true
• The first two rules are valid irrespective of the order of the arguments andwhether or not the value of the other sub-expression is known
• Exception for if-then-else expression: it will be valid as long as the chosenbranch is valid, irrespective of the value of the other branch
25
Navigating Associations (1)
isUnemployed: Boolean...
Person
noEmployees:Integer...
Companyemployer
0..*0..*
employee
manager managedCompanies
0..*1
• From an object, an association is navigated using the opposite role namecontext Companyinv: self.manager.isUnemployed = falseinv: self.employee->notEmpty()
• Value of expression depends on maximal multiplicity of the association end
3 1: value is an object
3 *: value is a Set of objects (an OrderedSet if association is {ordered})
• If role name is missing, the name of the type at the association end starting witha lowercase character is used (provided it is not ambiguous)
context Personinv: self.bank.balance >= 0
26
Object Constraint Language, May 12, 2008 – 13
Navigating Associations (2)
• When multiplicity is at most one, association can be used as a single object oras a set containing a single object
• self.manager is an object of type Person
context Company inv:self.manager.age > 40
• self.manager as a setcontext Company inv:self.manager->size() = 1
• For optional associations, it is useful to check whether there is an object or notwhen navigating the association
context Person inv:self.wife->notEmpty() implies self.gender = Gender::male andself.husband->notEmpty() implies self.gender = Gender::female
• OCL expressions are read and evaluated from left to right
27
Association Classes
isUnemployed: Booleanage: Integer...
Person
noEmployees:Integer...
Companyemployer
0..*0..*
title: String...
Job
employee
• For navigating to an association class: a dot and the name of the associationclass starting with a lowercase character is used
context Personinv: self.isUnemployed = false implies self.job->size() >= 1
• For navigating from an association class to the related objects: a dot and therole names at the association ends is used
context Jobinv: self.employer.noEmployees >= 1inv: self.employee.age >= 18
• This always results in exactly one object
28
Object Constraint Language, May 12, 2008 – 14
Recursive Association Classes (1)
gender: GenderisMarried: Boolean...
currentSpouse() : Person
husband
wife
0..*
0..*
place: Stringdate: Dateended: Boolean
Marriage
Person
• Direction in which a recursive association is navigated is required
• Specified by enclosing the corresponding role names in square brackets
• A person is currently married to at most one personcontext Person inv:self.marriage[wife]->select(m | m.ended = false)->size()=1 andself.marriage[husband]->select(m | m.ended = false)->size()=1
• May also be used for non-recursive associations, but it is not necessarycontext Person inv:self.job[employer] ...
29
Recursive Association Classes (2)
gender: GenderisMarried: Boolean...
currentSpouse() : Person
husband
wife
0..*
0..*
place: Stringdate: Dateended: Boolean
Marriage
Person
• Operation that selects the current spouse of a personcontext Person::currentSpouse() : Personpre: self.isMarried = truebody:if gender = Gender::male
self.marriage[wife]->select(m | m.ended = false).wifeelse
self.marriage[husband]->select(m | m.ended = false).husbandend
30
Object Constraint Language, May 12, 2008 – 15
Qualified Associations
Bank
accountNo: Integer
Person0..1
customer
*
• Qualified associations use one or more qualifier attributes to select the objectsat the other end of the association
• A bank can use the accountNumber attribute to select a particular customer
• Using qualifier values when navigating through qualified associationscontext Bankinv: self.customer[12345] ...-- results in one Person, having account number 12345
• Leaving out the qualifier valuescontext Bankinv: self.customer ...-- results in a Set(Person) with all customers of the bank
31
Re-typing or Casting
• Allows an object to be re-typed as another type
• Expression o.oclAsType(Type2) re-types an object o of type Type1 into a an-other type Type2
• Suppose Super is a supertype of type Sub
• Allows one to use a property of an object defined on a subtype of the currentlyknown type of the object
context Super inv:self.oclAsType(Sub).p -- accesses the p property defined in Sub
• Can be used to access a property of a superclass that has been overridencontext Sub inv:self.p-- accesses the p property defined in Subself.oclAsType(Super).p-- accesses the p property defined in Super
32
Object Constraint Language, May 12, 2008 – 16
Predefined Properties on All Objects
• Several properties apply to all objects
3 oclIsTypeOf(t: Type): Boolean is true if the type of self and t are thesame
3 oclIsKindOf(t: Type): Boolean is true if t is a direct/indirect type ofself
3 oclInState(s: State): Boolean is true if self is in the state s
3 oclIsNew: Boolean, in a postcondition, is true if self has been createdwhile performing the operation
• Examplecontext Personinv: self.oclIsTypeOf(Person) -- is trueinv: self.oclIsTypeOf(Company) -- is false
33
Class Features
• Features of a class, not of its instances
• They are either used-defined or predefined
• Predefined feature allInstances holds on all types
• There are at most 100 personscontext Person inv:Person.allInstances()->size() <= 100
• A user-defined feature averageAge of class Personcontext Person inv:Person.averageAge =
Person.allInstances()->collect(age)->sum()/Person.allInstances()->size()
34
Object Constraint Language, May 12, 2008 – 17
Select Operation on a Collection
• Obtains the subset of elements of a collection satisfying a Boolean expression
• Alternative expressions for the select operation
3 collection->select(Boolean-expression)
3 collection->select(v | Boolean-expression-with-v)
3 collection->select(v: Type | Boolean-expression-with-v)
• A company has at least one employee older than 50context Company inv:
self.employee->select(age > 50)->notEmpty()context Company inv:
self.employee->select(p | p.age > 50)->notEmpty()context Company inv:
self.employee->select(p: Person | p.age > 50)->notEmpty()
35
Reject Operation on a Collection
• Obtains the subset of all elements of the collection for which a Boolean expressionevalutes to False
• Alternative expressions for the reject operation
3 collection->reject(Boolean-expression)
3 collection->reject(v | Boolean-expression-with-v)
3 collection->reject(v: Type | Boolean-expression-with-v)
• The collection of employees of a company who have not at least 18 years old isempty
context Company inv:self.employee->reject(age>=18)->isEmpty()
• A reject expression can always be restated as a select with the negated ex-pression
36
Object Constraint Language, May 12, 2008 – 18
Collect Operation on a Collection
• Derives a collection from another collection, but which contains different objectsfrom the original collection
• Alternative expressions for the collect operation
3 collection->collect(expression)
3 collection->collect(v | expression-with-v)
3 collection->collect(v: Type | expression-with-v)
• Collect of birth dates for all employees in the context of a Company object
3 self.employee->collect(birthDate)
3 self.employee->collect(p | p.birthDate)
3 self.employee->collect(p:Person | p.birthDate)
• Resulting collection above is a Bag: some employees may have the same birthdate
37
ForAll Operation on a Collection
• Specifies a Boolean expression that must be true for all elements in a collection
• Alternative expressions for the forall operation
3 collection->forAll(Boolean-expression)
3 collection->forAll(v | Boolean-expression-with-v)
3 collection->forAll(v: Type | Boolean-expression-with-v)
• The age of each employee is less than or equal to 65
context Companyinv: self.employee->forAll(age <= 65)inv: self.employee->forAll(p | p.age <= 65)inv: self.employee->forAll(p: Person | p.age <= 65)
• More than one iterator can be used in the forAll operation
• All instances of persons have unique namescontext Person inv:Person.allInstances()->forAll(p1, p2 |
p1 <> p2 implies p1.name <> p2.name )
38
Object Constraint Language, May 12, 2008 – 19
Exists Operation on a Collection
• Specifies a Boolean expression that must be true for at least one element ina collection
• Alternative expressions for the exists operation
3 collection->exists(Boolean-expression)
3 collection->exists(v | Boolean-expression-with-v)
3 collection->exists(v: Type | Boolean-expression-with-v)
• The firstName of at least one employee is equal to ‘Jack’
context Companyinv: self.employee->exists(firstName = ‘Jack’)inv: self.employee->exists(p | p.firstName = ‘Jack’)inv: self.employee->exists(p: Person | p.firstName = ‘Jack’)
39
Iterate Operation on a Collection
• Provides a generic mechanism to iterate over a collection
• Syntaxcollection->iterate(elem: Type; acc: Type = <expression> |
expression-with-elem-and-acc)
3 elem: the iterator as in select, forAll, etc.
3 acc: the accumulator with an initial value <expression>
3 expression-with-elem-and-acc: is evaluated for each elem and its value isassigned to acc
• The operations select, reject, forAll, exists, collect, can all be describedin terms of iterate
• For example, collection->collect(x: T | x.property) is identical tocollection->iterate(x: T; acc: T2 = Bag{} |
acc->including(x.property))
40
Object Constraint Language, May 12, 2008 – 20
Company Example: Class Diagram
1
4..*
Employee
SSN
firstName
lastName
birthDate
sex
salary
address
hireDate
Department
number
name
locations [1..*]
/nbrEmployees
Project
number
name
location
hours
1..*
1..*
1
0..10..*
supervisor
subordinates
startDate
0..*
1
Manages
WorksFor
Supervision
ControlsWorksOn
0..1
Dependent
name
relationship
sex
birthDate
1..*
1
dependents
age()
41
Company Example: Integrity Constraints (1)
• The age of employees must be greater than or equal to 18context Employee inv:self.age() >= 18
• The supervisor of an employee must be older than the employeecontext Employee inv:self.supervisor->notEmpty() implies
self.age() > self.supervisor.age()
The condition notEmpty must be tested since the multiplicity of the role is notmandatory
• The salary of an employee cannot be greater than the salary of his/her supervisorcontext Employee inv:self.supervisor->notEmpty() implies
self.salary < self.supervisor.salary
• The hire date of employees must be greater than their birth datecontext Employee inv:self.hireDate > self.birthDate
42
Object Constraint Language, May 12, 2008 – 21
Company Example: Integrity Constraints (2)
• The start date of an employe as manager of a department must be greater thanhis/her hire date
context Employee inv:self.manages->notEmpty() impliesself.manages.startDate > self.hireDate
• A supervisor must be hired before every employee s/he supervisescontext Employee inv:self.subordinates->notEmpty() impliesself.subordinates->forall( e | e.hireDate > self.hireDate )
• The manager of a department must be an employee of the departmentcontext Department inv:self.worksFor->includes(self.manages.employee)
• The SSN of employees is an identifier (or a key)context Employee inv:Employee.allInstances->forAll( e1, e2 |
e1 <> e2 implies e1.SSN <> e2.SSN )
43
Company Example: Integrity Constraints (3)
• The name and relationship of dependents is a partial identifier: they are uniqueamong all dependents of an employee
context Employee inv:self.dependents->notEmpty() impliesself.dependents->forAll( e1, e2 | e1 <> e2 implies
( e1.name <> e2.name or e1.relationship <> e2.relationship ))
• The location of a project must be one of the locations of its departmentcontext Project inv:self.controls.locations->includes(self.location)
• The attribute nbrEmployees in Department keeps the number of employees thatworks for the department
context Department inv:self.nbrEmployees = self.worksFor->size()
• An employee works at most in 4 projectscontext Employee inv:self.worksOn->size() <= 4
44
Object Constraint Language, May 12, 2008 – 22
Company Example: Integrity Constraints (4)
• An employee may only work on projects controlled by the department in whichs/he works
context Employee inv:self.worksFor.controls->includesAll(self.worksOn.project)
• An employee works at least 30h/week and at most 50 h/week on all its projectscontext Employee inv:let totHours: Integer = self.worksOn->collect(hours)->sum() intotHours >= 30 and totHours <=50
• A project can have at most 2 employees working on the project less than 10hours
context Project inv:self.worksOn->select( hours < 10 )->size() <= 2
45
Company Example: Integrity Constraints (5)
• Only department managers can work less than 5 hours on a projectcontext Employee inv:self.worksOn->select( hours < 5 )->notEmpty() impliesDepartment.allInstances()->collect(manages.employee)->
includes(self)
If the manager of a department must be an employee of the department (previouscontraint), this constraint can be specified as follows
context Employee inv:self.worksOn->select( hours < 5 )->notEmpty() impliesself.worksFor.manages.employee=self
• Employees without subordinates must work at least 10 hours on every projectthey work
context Employee inv:self.subordinates->isEmpty() impliesself.worksOn->forAll( hours >=10 )
46
Object Constraint Language, May 12, 2008 – 23
Company Example: Integrity Constraints (6)
• The manager of a department must work at least 5 hours on all projects con-trolled by the department
context Department inv:self.controls->forall( p:Project | self.manages.
employee.worksOn->select(hours >= 5)->contains(p) )
• An employee cannot supervise him/herselfcontext Employee inv:self.subordinates->excludes(self)
• The supervision relationship must not be cycliccontext Employeedef: allSubordinates = self.subordinates->union(
self->subordinates->collect(e:Employee | e.allSubordinates))inv: self.allSubordinates->exludes(self)
47
Object Constraint Language, May 12, 2008 – 24