readonly и derived - это свойства "раз и навсегда", frozen (unfrozen) - только на время.
Согласно. Выше, говоря о связке readOnly с frozen, имело в виду, что readOnly=frozenForever.
Кроме того, если атрибут readonly, то делать его frozen (unfrozen) не имеет смысла - от этого ничего не изменится. И еще, если атрибут derived, то какой смысл давать ему defaultValue, разве что считать это дополнительным ограничением на те атрибуты, по которым вычисляется этот атрибут.
Речь шла не о совместном применении readOnly и frozen, а об общности их смыслов.
Меня озарило, что авторы стандарта дали кучу примеров использования обсуждаемых нами тегов и слэшей. Они даны на диаграммах (и OCLях) описывающих метамодель UML. На 9.5.2 есть такое: Property::/isComposite:Boolean=false (также в 9.9.17.5). Авторы демонстрируют свой приём моделирования. Для каждого выводимого атрибута (полюса ассоциации) ими заводится одноимённая операция, возвращающая выведенное значение. Если OCL позволяет, то операции даётся тело (удивительно, что не derive!). См. Property::isComposite() в 9.9.17.7. Если убрать начальное значение в этом примере, смысл сохранится. Есть подозрение, что явное выписывание начального значения тут -- подсказка читателю диаграммы, чтобы ему не пришлось искать тело и в уме делать вывод. В схожей ситуации 12.3.2 (12.4.1.4, 12.4.1.6), Extension::/isRequired:Boolean вместо =false указано {readOnly}. Налицо "эффект дрожжей". Есть ещё одно подозрение, что завихрения относительно readOnly + derived рождались у авторов стандарта и обкатывались на метамодели UML. Т. е. это их реализаторская точка зрения, в которой они путают "не может меняться извне" с "не может меняться после инициализации". По каким-то причинам авторам эта путаница удобна. О том, как быть остальным, они не заботились. Щепотка "дрожжей" нашлась в описании Message::/messageKind {readOnly}. Для выводимого атрибута задана операция, тело которой состоит из возврата значения взятого у самого атрибута.
Например описание атрибутов "длина, ширина, /площадь=6 {derive: длина*ширина}" означает: "Сразу после инициализации длина и ширина могут быть любыми числами, но их произведение должно равняться 6. Потом на длину и ширину не накладывается никаких ограничений, но площадь всегда будет равна их произведению.".
Я бы такое описание прочло так: Длина и ширина не имеют значений по умолчанию. Площадь по умолчанию равна 6. В какие-то моменты времени значение площади вычисляется как произведение длины на ширину. Чтобы описать, в какие именно моменты, следует дать диаграмму состояний и/или дать реализации операций класса Прямоугольник.
Эти авторы когда-то впечатлили меня фразой: "существуют три уровня понимания обучающимся нового предмета, которые характеризуются следующими признаками: 1. Возникает приятное чувство понимания; 2. Может повторить своими словами; 3. Видит ошибки. Данная книга написана на третьем уровне и адресована обучающимся, ориентированным на третий уровень" - взято отсюда. Про derived ничего не говорят, только про derive.
Авторы захаживали/захаживают на эту планету, так что я остановлюсь на первом предложенном ими уровне.
Склеиваем и получаем: как получилось расчетное значение сразу после инициализации, так дальше и не меняется, хотя все время пересчитывается.
Я полагаю, что слэш не устанавливает явной директивы, что нужно всё время пересчитывать. Стандарт на этот счёт лишь замечает, что изменение значения nonReadOnly выводимого свойства должно подчиняться derive-ограничению.
Рассмотрим класс "меняющийся прямоугольник" с атрибутами: длина, ширина, площадь, первоначальная площадь. Правильным описанием двух последних атрибутов будет: /площадь {derive: длина*ширина}, первоначальная площадь=площадь {readonly} (если считать, что "=defaultValue" отражает постусловие конструктора). Делать первоначальную площадь derive нельзя - тогда надо указывать правило вычисления. Или считать, что для атрибута с derived наличие "=defaultValue" (может в сочетании с readonly) служит правилом вычисления.
С точки зрения написанного мной выше этот пример может быть разобран так:
Значение первоначальной площади зависит от других значений, значит этот атрибут можно пометить как выводимый.
Указание начального значения у первоначальной площади, которая является {readOnly}, играет ту же роль, что и правило вычисления. При инициализации объекта будет вычислено то, что справа от равенства, результат будет положен в первоначальную площадь, далее он меняться не будет.