ocl constraint with recursive class

214 Views Asked by At

For a little bit of context: a Class can have other Class as Requirement to be taken by a student. The Class is taken by a Student via a ClassGroup which can be ordered in time with its attribute sessionYear.

enter image description here

I want to put an OCL invariable constraint that will check if, for the sessionYear a ClassGroup, its Class Requierement were already taken before this sessionYear.

in other words: sessionYear for Requirement < sessionYear for Class

I tried a quite a few constaints and my closest attempt was this one:

context Etudiant inv C6: if ClassTaken->notEmpty then classTaken->forAll(ct|ct.class.Requirement.OfferedGroup->collect(sessionYear)->forAll(sy| sy < cs.sessionYear)) else true endif

But the problem is, in the forAll(sy| sy->sy < cs.sessionYear), sy won't be the Student required ClassTaken for a ClassGroup, but rather a Bag with every instances of OfferedGroup that are Requirement for it.

2

There are 2 best solutions below

0
On BEST ANSWER

I ended up doing this something like this:

context Student
 inv C6: inscription->forAll(insc|ClassTaken.class.Requirement->forAll(prer|inscription->exists(preIns|preIns.ClassTaken.class = prer 
 and if preIns.ClassTaken = insc.ClassTaken then true
  else preIns.ClassTaken.sessionYear < insc.ClassTaken.sessionYear endif)))
0
On

Trying quite a few constraints is hacking and does not always lead to a satisfactory result in a reasonable period of time.

OCL is a moderately readable formal language.

Once you express the intent of your constraint clearly in English (or French or ...) you should find that it can be transliterated relatively easily into OCL.

Think/design do not hack.