I'm modelling a problem in which there are students and courses. Each courses have some other courses as prerequisites and I want to make an OCL constraint on the "joinCourse()" operation of students to allow them to join a courses if and only if they have finished required courses.
this is a draft of the UML class diagram I made:
now, my question is: is possible to make a collection operation, like "includeAll" on a "list attribute" like finishedCourses?
I made this ocl constraint:
context Student::joinCourse(c: Course)
pre: self.finishedCourses->includesAll(c.requiredCourses)
correct?
thanks in advance!
In short: yes, it's correct.
In the UML 2.5 specifications there is a clear link between multiplicity and collection:
7.5.3.2. A MultiplicityElement is an Element that may be instantiated in some way to represent a collection of values. (...)
The OCL specification explains how self relates to the context (clause 7.3.4):
The OCL expression can be part of a Precondition or Postcondition, corresponding to «precondition» and «postcondition» stereotypes of Constraint associated with an Operation or other behavioral feature. The contextual instance self then is an instance of the type that owns the operation or method as a feature.
So in your expression, self
refers to a Student
, and a dot allows to access its properties, such as self.finishedCourse refers to a collection property.
OCL defines collection types (clause 11.6) and general operations that are well formed for all collections (clause 11.7.1):
includesAll(c2 : Collection(T)) : Boolean
Does self contain all the elements ofc2
?
post:result = c2->forAll(elem | self->includes(elem))
So self.finishedCourses->includesAll(c.requiredCourses)
is a valid expression that is true or false exactly in the situation that you expect.
A property may represent an attribute of a classifier or a member end of an association. You could have represented finishedCourse
as the end of a second association between Student
and Course
(being understood that all courses taken are not necessarily finished).