ограничение ocl с рекурсивным классом

Для небольшого контекста: Class может иметь других Class как Requirement, которые должен взять студент. Class принимается Student через ClassGroup, который может быть упорядочен во времени с его атрибутом sessionYear.

введите здесь описание изображения

Я хочу поместить неизменное ограничение OCL, которое будет проверять, были ли для sessionYear a ClassGroup его Class Requierement уже приняты до этого sessionYear.

другими словами: sessionYear вместо RequirementsessionYear вместо Class

Я пробовал довольно много ограничений, и моей ближайшей попыткой был этот:

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

Но проблема в том, что в forAll(sy| sy->sy < cs.sessionYear), sy будет не Student требуемый ClassTaken для ClassGroup, а скорее Bag со всеми экземплярами OfferedGroup, которые Requirement для него.


person Takyon    schedule 12.11.2018    source источник


Ответы (2)


Попытка установить довольно много ограничений является взломом и не всегда приводит к удовлетворительному результату за разумный период времени.

OCL является умеренно читаемым формальным языком.

Как только вы ясно изложите цель ограничения на английском (или французском, или...), вы обнаружите, что его можно относительно легко транслитерировать в OCL.

Думай/конструируй, а не взламывай.

person Ed Willink    schedule 12.11.2018

Я закончил тем, что сделал что-то вроде этого:

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)))
person Takyon    schedule 20.11.2018