Форум Сообщества Аналитиков
Общий раздел => Теория моделирования и нотации => UML SysML и пр. => Тема начата: Vadim от 30 Марта 2016, 15:56:33
-
Есть известная диаграмма (во вложении).
Если в состоянии DisplayAlarmTime & PlayingCD происходит событие Radio, то в какое наступит состояние:
- DisplayAlarmTime & PlayingRadio (правило: если во внутреннем переходе для региона нет никаких указаний, то текущее состояние в регионе не изменяется)
- DisplayCurrentTime & PlayingRadio (правило: если в переходе в параллельное композитное состояние для региона нет никаких указаний, то текущее состояние в регионе определяется начальным псевдосостоянием)?
-
Наверно, что-то не так сделал - ни одного ответа. А как правильно - не знаю...
-
Наверно, что-то не так сделал - ни одного ответа.
Лично я ничё не понял. Можно по-русски все это повторить?
-
Есть диаграмма автомата (в стартовом сообщении).
Необходимо разобраться:
- что произойдет (в соответствии с диаграммой), если в состоянии (композитном) DisplayAlarmTime & PlayingCD наступит событие Radio;
- почему произойдет именно так (какое состояние станет активным и по какому правилу).
-
Прекрасная иллюстрация случая, когда от диаграммы больше вреда, чем пользы.
-
Прекрасная иллюстрация случая, когда от диаграммы больше вреда, чем пользы.
Мне понравилась там метка от CUSTIS :)
Ну, в определенных условиях эта диаграмма вполне себе хороша. Хотя изобразить ее можно было бы более понятно.
Для меня очевидно, что при переходе из выключенного во включенное состояние
1. загорается и отображается текущее время - это начальное состояние в композите
2. не совсем ясно, но возможно (на что указывает неглубокая история) включается и играет радио
Если же устройство на момент вопроса отображало время будильника и проигрывало музыку CD и возникло событие Radio - включена кнопка - то вероятно CD отключается, начинает играть Радио, а система отображает время будильника.
Впрочем, признаюсь, такие сложные автоматы не моделировал, но можно попробовать в спарксе проиграть эту диаграммку
-
Здесь нет внутренних переходов. Переходы, начинающиеся с границы состояния On являются не внутренними, а локальными (и групповыми).
По стандарту владельцем перехода является регион. Может быть, этим и руководился Мартин Фаулер, приведший в своём "дистиллированном UML" эту диаграмму. Предположительно, он посчитал, что локальный переход по событию Radio относится только к его владельцу (нижнему региону) и подсостояниям, заключённым в нём. По этой трактовке выходит, что DisplayAlarmTime & PlayingCD --Radio--> DisplayAlarmTime & PlayingRadio. Но в стандарте при описании групповых переходов ничего не говорится о регионах, а подчёркивается, что групповой переход исходит из (всего) композитного состояния. Поэтому возможна другая трактовка, по которой происходит выход из DisplayAlarmTime, т. е. групповой переход действует на все подсостояния из обоих регионов On. И получается, что эта диаграмма ill formed.
Замечу, что попадается более прозрачная версия той же диаграммы, лишённая к тому же недостатка, из-за которого из PlayingRadio по событию Radio приходится выходить и тут же возвращаться обратно.
-
Можно прибавить, что в книге Блахи и Рамбо есть пример другой диаграммы с такими же групповыми локальными переходами (стр. 151, рис. 6.11). Пример трактуется так же как у Фаулера.
P. S. Если бы на диаграмме Фауле переход был бы не локальным, а внешним, то после него была бы активной конфигурация состояний DisplayCurrentTime & PlayingRadio.
-
Дефектом обоих вариантов диаграммы является отсутствие в нижнем регионе начального состояния и перехода из него в историческое псевдосостояние. Т. о. в любом случае диаграмма ill formed.
-
Читаем книгу UML. Основы, 3-е издание, М. Фаулера стр. 134, рис. 10.5. Текст
" Состояния могут быть разбиты на несколько параллельных состояний, запускаемых одновременно. На рис. 10.5 показан трогательно простой будильник, который может включать либо CD, либо радио и показывать либо текущее время, либо время сигнала. "
Хотелось бы остановиться на этой части. Как из представленной диаграммы следует, что будильник включается через CD или радио.
Правильно ли я понимаю, что это показывается тем фактом, что переход ON - вызывает включение или радио, или СД, И отображения времени? Как можно вообще понять что нижний регион это ИЛИ, а не И например?
Перевод текст отдельная тема для дискуссии, но
"Рис. 10.5 включает также состояние предыстории (history pseudostate). Это означает, что когда включены часы, опция радио/CD переходит в состояние, в котором находились часы, когда они были выключены. Стрелка, выходящая из предыстории, показывает, какое состояние существовало изначально, когда отсутствовала предыстория."
Разве из диаграммы следует что часы буду проигрывать или СД, или радио при включении.
И вновь - это небрежность Фаулера? Его ассистентов? Это не знание нотации Фаулером? Или это ошибка переводчика?
-
В исходном тексте:"Figure 10.5 shows a pathetically simple alarm clock that can play either CDs or the radio and show either the current time or the alarm time." То есть, имелось в виду, что когда будильник срабатывает (событие on), то может либо заиграть CD, либо заработать радио.
Второй фрагмент: "Figure 10.5 also includes a history pseudostate. This indicates that when the clock is switched on, the radio/CD choice goes back to the state the clock was in when it was turned off. The arrow from the history pseudostate indicates what state to be in on the first time when there is no history." То есть, переводчик снова отличился.
Пусть текущее состояние Off и происходит событие on. Совершается переход в композитное состояние с 2-мя ортогональными регионами. В этом переходе неявный fork, то есть, текущим станет сочетание из двух подсостояний, взятых из разных регионов. В верхнем регионе есть начальное псевдосостояние, следовательно, можно определить, что текущим станет DisplayTime. В нижнем регионе начального состояния нет. Значит, диаграмма ill formed. То, о чём пишет Фаулер, было бы справедливо, если бы нижний регион содержал начальное состояние. См. приложенный вариант. Подобные ошибки (псевдосостояние истории есть, а переходов в него нет) содержатся в книге Леоненкова.
На счёт И и ИЛИ стандарт указывает, что составные диаграммы как бы порождают И-ИЛИ дерево, описывающее какие конфигурации состояний допустимы. Для рассматриваемого примера дерево будет:
OR
Off
On
AND
OR
DisplayTime
DisplayAlarmTime
OR
PlayCD
PlayRadio
Отдельно замечу, что на диаграмме отсутствуют действия и деятельности. То есть, работа радио, CD, отображение времени -- всё это в воображении. Автомат лишь переключается между состояниями, и больше ничего не делает. Тут было бы уместно вспомнить тему про то, чему не следует учить.
-
Супер! Обсуждение стало конструктивным и результативным.
Переходы, начинающиеся с границы состояния On являются не внутренними, а локальными
Мой косяк :'(
Замечу, что попадается более прозрачная версия той же диаграммы, лишённая к тому же недостатка, из-за которого из PlayingRadio по событию Radio приходится выходить и тут же возвращаться обратно.
Эти диаграммы эквивалентны только тогда, когда нет действий (по терминологии Рамбо и Блаха) или активностей (по терминологии Фаулера) ни при выходе из состояния, ни при входе в состояние, ни при переходе. Например: пусть при входе в состояние Play(ing)Radio происходит настройка на "любимую" станцию. В одной диаграмме настройка будет происходить при любом событии Radio, а в другой - только если состояние Play(ing)CD.
В нижнем регионе начального состояния нет. Значит, диаграмма ill formed. То, о чём пишет Фаулер, было бы справедливо, если бы нижний регион содержал начальное состояние. См. приложенный вариант. Подобные ошибки (псевдосостояние истории есть, а переходов в него нет) содержатся в книге Леоненкова.
Многие источники (не только Фаулер) считают, что историческое псевдосостояние без входящего перехода, но с исходящим переходом заменяет начальное псевдосостояние, когда происходит первый вход. То есть, при первом входе в состояние On текущим состоянием в нижнем регионе становится Play(ing)Radio.
Интересная тема: возможные варианты сочетания начального и исторического псевдосостояний в одном регионе и наличия (отсутствия) исходящих (входящих) переходов исторического псевдосостояния (с начальным всё ясно: не более одного, никаких входящих и ровно один исходящий)!
-
А если, например, включение радио или CD происходит в зависимости от истории. Как это показать? Да, и все-таки, радио или CD включается всегда при включение будильника, или в момент возникновения события будильника? На диаграмме, например можно предположить отражение текущего времени, включения сигнала будильника (т.е. радио или плеера :)
-
радио или CD включается всегда при включение будильника
Когда текущим является композитное состояние с ортогональными регионами (On), тогда в каждом из регионов (верхний и нижний) текущим будет ровно одно из состояний региона (для верхнего: DisplayCurrentTime или DisplayAlarmTime, для нижнего: PlayRadio или PlayCD). А конкретный выбор в каждом случае и определяется наличием в регионах начальных и исторических псевдосостояний и переходами из них. То есть если будильник включен, то либо включено радио, либо включено CD.
А если, например, включение радио или CD происходит в зависимости от истории. Как это показать?
На диаграмме(ах) показано, что выбор, радио или CD будет включено при включении будильника, зависит от того, что было включено при выключении будильника (наличие исторического псевдосостояния). А то, что включается радио, если выключений будильника пока не было, показывает исходящий из исторического псевдосостояния переход. Такая на диаграмме(ах) зависимость от истории. Если нужна другая, то надо разобрать какая,
-
Эти диаграммы эквивалентны только тогда, когда нет действий (по терминологии Рамбо и Блаха) или активностей (по терминологии Фаулера) ни при выходе из состояния, ни при входе в состояние, ни при переходе. Например: пусть при входе в состояние Play(ing)Radio происходит настройка на "любимую" станцию. В одной диаграмме настройка будет происходить при любом событии Radio, а в другой - только если состояние Play(ing)CD.
Точно замечено.
Поэтому разумнее рассматривать примеры с действиями, что, возможно, расходилось с целью книги Фаулера -- дать беглый обзор языка.
Многие источники (не только Фаулер) считают, что историческое псевдосостояние без входящего перехода, но с исходящим переходом заменяет начальное псевдосостояние, когда происходит первый вход. То есть, при первом входе в состояние On текущим состоянием в нижнем регионе становится Play(ing)Radio.
Интересная тема: возможные варианты сочетания начального и исторического псевдосостояний в одном регионе и наличия (отсутствия) исходящих (входящих) переходов исторического псевдосостояния (с начальным всё ясно: не более одного, никаких входящих и ровно один исходящий)!
Если опираться на стандарт, то такие трактовки следует отвести. Псевдосостояние истории сродни начальному состоянию в том смысле, что это специальные обозначения, что (непосредственно) внутри региона их не может быть больше одного. Но назначения у них разные. Если нет входящих переходов в историческое псевдосостояние, то оно лишь указывает, что автомат запоминает историю, но воспользоваться этой историей в своём поведении он не может.
Вокруг начального много накручено. Несколько исходящих, случай, когда допускается триггер...
-
А если, например, включение радио или CD происходит в зависимости от истории. Как это показать? Да, и все-таки, радио или CD включается всегда при включение будильника, или в момент возникновения события будильника? На диаграмме, например можно предположить отражение текущего времени, включения сигнала будильника (т.е. радио или плеера :)
Vadim дельно описал, для чего Фаулер помещал на диаграмму историческое псевдосостояние. Поясню, почему событие on я связываю со срабатыванием будильника. Других кандидатов на срабатывание нет, а будильник должен когда-то срабатывать.
-
Поясню, почему событие on я связываю со срабатыванием будильника. Других кандидатов на срабатывание нет, а будильник должен когда-то срабатывать.
А я думаю, что от будильника Фаулер взял только отображение времени срабатывания будильника. Сам же звонок и настройка времени срабатывания будильника (да и настройка текущего времени) остались за рамками диаграммы.
-
Добрался до Фаулера.
Я не понимаю, зачем в одной диаграмме объединять абсолютно не связанные между собой сущности.
Если бы вы захотели представить это с помощью диаграммы непараллельных состояний, то получилась бы беспорядочная диаграмма при необходимости добавить состояния.
Но именно это в данном случае и получилось.
Разделение двух областей поведения на две диаграммы состояний делает ее значительно яснее.
Если бы это было так, то не было бы этой темы на форуме. Просто нечего было бы обсуждать.
-
Но именно это в данном случае и получилось.
Попробовал построить эквивалентную диаграмму без параллельных и вложенных состояний - 7 состояний и 15 переходов, вряд ли так лучше.
-
Попробовал построить эквивалентную диаграмму без параллельных и вложенных состояний - 7 состояний и 15 переходов, вряд ли так лучше.
Но зачем располагать всё на одной диаграмме? Отображение времени и работа радио/CD между собой никак не связаны и не влияют друг на друга. Конечно, если все состояния независимых элементов попытаться впихнуть в одну диаграмму, мы получим экспоненциальный рост её сложности (в пределе придётся перемножать количество состояний всех элементов).
Почему не изобразить две (или три, если так уж необходимо рисовать на диаграмме состояния "вкл/выкл")?
Каждая диаграмма рисуется с какой-то целью. Если это описание требований, то набор из нескольких диаграмм будет намного проще и понятнее. А в данном случае даже простое текстовое описание будет понятнее. Здесь на несчастные шесть состояний используется минимум шесть разных элементов языка. Такая визуализация бессмысленна.
-
Отображение времени и работа радио/CD между собой никак не связаны и не влияют друг на друга.
Почему не изобразить две (или три, если так уж необходимо рисовать на диаграмме состояния "вкл/выкл")?
Между собой непосредственно не связаны, но оба/обе связаны с "вкл/выкл".
Каждая диаграмма рисуется с какой-то целью. Если это описание требований, то набор из нескольких диаграмм будет намного проще и понятнее. А в данном случае даже простое текстовое описание будет понятнее. Здесь на несчастные шесть состояний используется минимум шесть разных элементов языка. Такая визуализация бессмысленна.
Первоначальная цель темы - разобраться на простом примере в семантике, то есть как читать, а не как писать.
-
Возможное решение с двумя вложенными автоматами (если хочется моделировать "несвязанное" отдельно). На самом деле это три диаграммы, которые склеены в редакторе. Места склейки пометил красным. Нестандартный узел среда VisualParadigm добавляет сама.
-
По стандарту владельцем перехода является регион.
Но в стандарте при описании групповых переходов ничего не говорится о регионах, а подчёркивается, что групповой переход исходит из (всего) композитного состояния.
Кажется, что эти утверждения противоречат друг другу, но это не так. В первом идет речь о синтаксисе и под словом "переход" подразумевается то, что на диаграмме изображается ровно одной линией со стрелкой, которая идет от (псевдо)состояния источника к (псевдо)состоянию цели. Во втором же говорится о семантике, и под словом "переход" понимается смена одного состояния на другое (под состоянием здесь понимается тоже не то, что в первом).
Разница хорошо ощущается при ортогональных композитных состояниях:
в первом утверждении состояния это 1)DisplayTime 2)DisplayAlarmTime 3)PlayCD 4)PlayRadio;
во втором утверждении состояния это 1)DisplayTime&PlayCD 2)DisplayTime&PlayRadio 3)DisplayAlarmTime&PlayCD 4)DisplayAlarmTime&PlayRadio.
-
Кажется, что эти утверждения противоречат друг другу, но это не так. В первом идет речь о синтаксисе и под словом "переход" подразумевается то, что на диаграмме изображается ровно одной линией со стрелкой, которая идет от (псевдо)состояния источника к (псевдо)состоянию цели. Во втором же говорится о семантике, и под словом "переход" понимается смена одного состояния на другое (под состоянием здесь понимается тоже не то, что в первом).
Разница хорошо ощущается при ортогональных композитных состояниях:
в первом утверждении состояния это 1) DisplayTime 2) DisplayAlarmTime 3) PlayCD 4) PlayRadio;
во втором утверждении состояния это 1) DisplayTime&PlayCD 2) DisplayTime&PlayRadio 3) DisplayAlarmTime&PlayCD 4) DisplayAlarmTime&PlayRadio.
Владелец перехода -- элемент метамодели UML, т. е. речь не только от том, как изображать на диаграмме. Я полагаю, что владение переходом определяет не только внешний вид. Кстати, вопрос, кто владеет каждым рассматриваемым переходом.)
Разницу можно прочувствовать, если добавить действия по выходу в каждое вложенное состояние (stopDispleying..., stopPlaying...), или считать, что есть do-деятельности и следить, прерываются они или нет. По второй трактовке получается, что несмотря на то, что владеет переходом нижний регион[?], срабатывание перехода вызывает прекращение do-деятельностей в верхнем регионе (или выполнение действий по выходу).
У Рамбо и Блахи в их книге "UML 2.0. Объектно-ориентированное моделирование и разработка" есть пример 6.11 с термостатом. Я полагаю, что он нарисован по 1й трактовке. Иначе выходит, что установка часов вызывает переключение единиц измерения температуры (с Цельсиев на Фаренгейты).
-
Владелец перехода -- элемент метамодели UML, т. е. речь не только от том, как изображать на диаграмме. Я полагаю, что владение переходом определяет не только внешний вид. Кстати, вопрос, кто владеет каждым рассматриваемым переходом.)
Согласен с утверждением, а сам использовал понятия не модели, а диаграммы потому, что: 1)думалось так проще и понятнее 2)привык, что диаграмма должна отражать (почти) всё, что есть в модели.
Про владение переходами: on и off владеет единственный регион будильника целиком; alarm, time и переходом от начального к DisplayTime владеет верхний регион состояния On; CD, radio, переходом от начального к историческому и переходом от исторического к PlayRadio владеет нижний регион состояния On.
Разницу можно прочувствовать, если добавить действия по выходу в каждое вложенное состояние (stopDispleying..., stopPlaying...), или считать, что есть do-деятельности и следить, прерываются они или нет. По второй трактовке получается, что несмотря на то, что владеет переходом нижний регион[?], срабатывание перехода вызывает прекращение do-деятельностей в верхнем регионе (или выполнение действий по выходу).
Последний гвоздь в крышку гроба второй трактовки.
У Рамбо и Блахи в их книге "UML 2.0. Объектно-ориентированное моделирование и разработка" есть пример 6.11 с термостатом. Я полагаю, что он нарисован по 1й трактовке. Иначе выходит, что установка часов вызывает переключение единиц измерения температуры (с Цельсиев на Фаренгейты).
Переходом after(90 sec without input) владеет регион InteractiveDisplay [?]. Если его (переход) заменить на эквивалентную конструкцию с fork - получится 4 перехода, а кто будет владеть каждым из них?
-
Про владение переходом в стандарте пишут примерно так:
Кого считать владельцем перехода точно не определено, но это один из регионов, в котором содержится переход, и который принадлежит прямо или косвенно конечному автомату. Рекомендуется, чтобы владельцем перехода был регион такой что: исход и цель перехода находятся в нём; сам он находится глубже всего в иерархии вложенности. Если исход перехода по событию Radio на диаграмме Фаулера -- состояние On, то владельцем по этой рекомендации следует считать основной регион автомата.
Можно заключить, что смыслы, вкладываемые в примеры от Фаулера и Рамбо с Блахой нестандартны. Если бы UML позволял проводить границы не только между регионами внутри состояния, но и между регионом и состоянием, то групповые переходы от "границы региона" и групповые переходы от границы состояния могли бы наглядно показывать разницу между двумя трактовками. Полагаю, что Фаулер и Блаха с Рамбо рисовали переходы от "границы региона". А по стандарту эти переходы следует считать идущими от границы состояния.
Выходит, что переходом after(90 sec without input) действительно владеет регион InteractiveDisplay. При явном представлении в виде составного перехода владелец будет тот же.
-
Про владение переходом в стандарте пишут примерно так:
Кого считать владельцем перехода точно не определено, но это один из регионов, в котором содержится переход, и который принадлежит прямо или косвенно конечному автомату. Рекомендуется, чтобы владельцем перехода был регион такой что: исход и цель перехода находятся в нём; сам он находится глубже всего в иерархии вложенности.
Искал в стандарте, где это зафиксировано не в виде фразы (сама фраза - 14.2.3.8.5 Transition ownership из UML 2.5), а как ограничение в метамодели - и не нашел.
Если исход перехода по событию Radio на диаграмме Фаулера -- состояние On, то владельцем по этой рекомендации следует считать основной регион автомата.
А если вместо этого перехода сделать 2 перехода (по одному для каждого подсостояния нижнего региона) по событию Radio, то они будут иметь владельцем нижний регион?
Если бы UML позволял проводить границы не только между регионами внутри состояния, но и между регионом и состоянием, то групповые переходы от "границы региона" и групповые переходы от границы состояния могли бы наглядно показывать разницу между двумя трактовками. Полагаю, что Фаулер и Блаха с Рамбо рисовали переходы от "границы региона". А по стандарту эти переходы следует считать идущими от границы состояния.
Может то, что переход локальный, говорит о том, что он идет от "границы региона"?
-
Искал в стандарте, где это зафиксировано не в виде фразы (сама фраза - 14.2.3.8.5 Transition ownership из UML 2.5), а как ограничение в метамодели - и не нашел.
Действительно так. Я полагаю, что в этом месте стандарта лакуна.
А если вместо этого перехода сделать 2 перехода (по одному для каждого подсостояния нижнего региона) по событию Radio, то они будут иметь владельцем нижний регион?
Если следовать рекомендации стандарта, то так и будет. Ради эксперимента посмотрел как определит владельца перехода среда Visual Paradigm. Переходом от границы композитного состояния в этой среде владеет собственник этого состояния. Переходом к границе -- собственник состояния, из которого исходит переход. Т. е. владелец перехода совпадает с владельцем его истока (даже если переход идёт наружу из композитного состояния).
Может то, что переход локальный, говорит о том, что он идет от "границы региона"?
Локализация (если следовать стандарту) предусмотрена на уровне состояний, а не регионов-владельцев. Локальный переход выполняется без выполнения действий по входу и по выходу и без прерывания do-деятельности состояния, в котором он локализован. То, что локализация не связана с регионом-владельцем, тоже не способствует ясности картины.
Если обратиться к Д. Харелу, то можно видеть, что его "регионы", которые он называл компонентами ничем не отличаются от состояний. Ортогональное состояние у него образуется как результат декартова произведения компонент-состояний-сомножителей. http://www.wisdom.weizmann.ac.il/~harel/papers/Statecharts.pdf (http://www.wisdom.weizmann.ac.il/~harel/papers/Statecharts.pdf) Также он рассматривает вопрос, рисовать ли границы ортогонального состояния (не совпадающие с границами регионов) -- рис. 21а и b. И, не видя необходимости в двойных границах, указывает как предпочтительный вариант с одинарными. Но вариант с двойной границей указан как возможный.
В "метамодели" Харела можно легко придти к той трактовке 2-й примеров Фаулера, Рамбо и Блахи, которую мы обсуждали.
Добавлю, что во всей коллекции примеров диаграмм от Харела нет ни одного примера, в котором переход идёт от границы региона. Есть рис. 14 из статьи по ссылке выше, но там обычное неортогональное состояние. Сборник примеров см. тут с 16-й страницы: http://www.wisdom.weizmann.ac.il/~harel/papers/Statecharts.History.pdf (http://www.wisdom.weizmann.ac.il/~harel/papers/Statecharts.History.pdf) Смотреть с осторожностью. Уровень вложенности доходит до шести. )))
-
Я полагаю, что в этом месте стандарта лакуна.
И приходится её (лакуну) заполнять :)
Зачем вообще нужен владелец перехода (а по метамодели переход любого типа обязан иметь регион-владельца)?
Когда речь идет о внешнем переходе понятно, почему должен быть владелец - мало знать исход и цель. Например надо различать (см. вложения 1-3), а указание региона-владельца и позволит это сделать.
Если переход локальный, то зачем ему владелец? Мы и так знаем, что не выйдем за границы состояния, из которого исходит локальный переход (а значит и любого из регионов, в которые это состояние непосредственно или опосредованно входит)!
локализация не связана с регионом-владельцем
Не понял :'(
-
Не понял :'(
Описание внешних/локальных/внутренних переходов в стандарте осуществлено без упоминания термина регион. Там говорится о состоянии-истоке, и состоянии, содержащем переход. Содержащее переход состояние, видимо должно определяться по картинке, т. к. по метамодели его определить затруднительно, если следовать стандарту. Так, я полагаю, что с точки зрения стандарта все Ваши три примера неотличимы, если представлять их не графически, а как набор взаимосвязанных экземпляров метаклассов (элементов UML).
В прочем, сами составители стандарта ему не следуют. Например, на рис. 14.34 приведены примеры локальных переходов (см. аттач), но левый нижний переход не является локальным, он внутренний (его исток и его цель совпадают!). Внутренние переходы по стандарту изображаются без линий (см. 14.2.4.10). Т. е. рисунок из стандарта нарушает сам стандарт.)))
Про регионы в стандарте есть попытка разъяснения в 14.2.3.2. Я затрудняюсь понять, чего не хватало в исходном предложении Харела, и почему завели регионы.
-
Описание внешних/локальных/внутренних переходов в стандарте осуществлено без упоминания термина регион. Там говорится о состоянии-истоке, и состоянии, содержащем переход. Содержащее переход состояние, видимо должно определяться по картинке, т. к. по метамодели его определить затруднительно, если следовать стандарту. Так, я полагаю, что с точки зрения стандарта все Ваши три примера неотличимы, если представлять их не графически, а как набор взаимосвязанных экземпляров метаклассов (элементов UML).
Начну очень издалека. :)
Предварительное замечание: когда я "читаю" стандарт (и не только), придерживаюсь подхода - если что-то зафиксировано формально в модели (на диаграмме), то уже не так важно, что об этом говорит текстовое описание.
Если рассматривать только простые состояния, то:
- переходы могут быть только внешними или внутренними
- внешний переход описывается ровно одним исходным состоянием и ровно одним целевым состоянием (еще событием, условием и действием, но это не важно в рамках обсуждаемой темы)
- внутренний переход мог бы описываться одним состоянием, но можно (как в стандарте, для единообразия) и исходным и целевым, но они должны совпадать
- владелец перехода не нужен: есть единственный кандидат - единственный регион самого автомата
Появление композитных-неортогональных состояний изменяет картину:
- появляется иерархия подчинения состояний
- для внешнего перехода появляется необходимость указать в каких рамках иерархии подчинения состояний он происходит (про это мои 3 примера) и это такое состояние/регион (подчиняющее состояние должно быть композитным, а между композитными состояниями и регионами существует ассоциация "ровно один к ровно одному", поэтому всё равно кого из них указывать), которое подчиняет и исходное и целевое, но необязательно непосредственно
- появляется возможность локального перехода (указание рамок иерархии подчинения состояний не нужно, так как определяется исходным состоянием, но для единообразия...). Тут появляются первые шероховатости: просится указать в качестве региона регион подчиненный исходному состоянию, но тогда нарушается правило "исход и цель находятся в нём", но это "правило" не записано как формальное ограничение, но мало ли чего не записано формально...
Ортогональность состояния (как и всего автомата):
- делает необходимым наличие понятия регион, чтобы именно ему подчинялись подчиненные состояния
- внешние переходы между состояниями, подчинёнными одному региону (если они не выходят за рамки ортогонального состояния - а таких большинство), имеют этот регион в качестве владельца
- шероховатости становятся непреодолимыми - уже нельзя в качестве владельца брать не регион
- может решение - для локальных (а значит и внутренних) переходов нет региона-владельца? (но это изменение метамодели, а это очень подозрительно и очень опасно!)
-
Написать свой патч к стандарту было бы круто, но я вряд ли в это смогу внести свой вклад.
По-моему, внешность/локальность перехода рассматривается в зависимости от некоторого состояния. Один и тот же переход может быть внешним для одного состояния и локальным для другого. Понятие владения переходом по смыслу связано или близко с его локальностью. Метамодель этого не отражает. Стандарт чётко об этом не говорит. И это неожиданный [для меня] неприятный сюрприз.
По-моему, у Харела было изящно: ортогональное состояние описывается декартовым произведением нескольких состояний. Т. е. хареловские регионы -- это полноценные состояния. Не увеличивается количество сущностей. Владение (если оно им не вводилось, то можно ввести) соответствовало расположению перехода внутри границ состояния.
-
Написать свой патч к стандарту было бы круто
Цель, конечно, не модифицировать стандарт, а в нём самом найти решение, или просто найти решение
По-моему, внешность/локальность перехода рассматривается в зависимости от некоторого состояния. Один и тот же переход может быть внешним для одного состояния и локальным для другого.
Переход имеет ровно одно состояние-исход, и по отношению к именно этому состоянию определяется будет переход внешним (будет выход и выходная деятельность из этого состояния) или локальным (не будет выхода и выходной деятельности)
Владение (если оно им не вводилось, то можно ввести) соответствовало расположению перехода внутри границ состояния.
В UML владение тоже соответствует расположению перехода внутри границ состояния.
хареловские регионы -- это полноценные состояния
этого не хватает для локальных переходов для того, чтобы владелец перехода был в иерархии подчинения состояний не ниже исхода
-
Переход имеет ровно одно состояние-исход, и по отношению к именно этому состоянию определяется будет переход внешним (будет выход и выходная деятельность из этого состояния) или локальным (не будет выхода и выходной деятельности)
Ваши 3 примера, как мне кажется, показывают, что это не так. Если локальностью перехода считать то самое "будет ли действие по выходу и прерывание do-деятельности", то выйдет, что внешность/локальность можно определять не только для исхода, но для любого состояния, к которому переход имеет отношение.
В UML владение тоже соответствует расположению перехода внутри границ состояния.
Почему бы так и не сказать в стандарте? Всё началось с того, что в примерах Фаулера расположение группового перехода в границах региона не соответствует тому, что этому переходу стандарт предписывает выходы из соседних регионов.
Этого не хватает для локальных переходов для того, чтобы владелец перехода был в иерархии подчинения состояний не ниже исхода.
Если не привязывать понятие локальности исключительно к исходу, то промежуточный элемент в иерархии не нужен, я полагаю.
-
Ваши 3 примера, как мне кажется, показывают, что это не так. Если локальностью перехода считать то самое "будет ли действие по выходу и прерывание do-деятельности", то выйдет, что внешность/локальность можно определять не только для исхода, но для любого состояния, к которому переход имеет отношение.
Давайте по шагам:
- Переход имеет ровно одно состояние-исход
- Внешность/локальность перехода определяется по отношению к переходу целиком
- Переход внешний рисуется наружу от границы состояния-исхода и не имеет ограничений кто будет состоянием-целью (соответствующий экземпляр метакласса Transition имеет значение атрибута kind равное external).
- Для внешнего перехода действие по выходу из состояния-исхода осуществляется
- Переход локальный рисуется внутрь от границы (композитного?) состояния-исхода и состояние-цель не может быть снаружи состояния-исхода (соответствующий экземпляр метакласса Transition имеет значение атрибута kind равное local)
- Для локального перехода действие по выходу из состояния-исхода не осуществляется - выхода то и нет
Почему бы так и не сказать в стандарте? Всё началось с того, что в примерах Фаулера расположение группового перехода в границах региона не соответствует тому, что этому переходу стандарт предписывает выходы из соседних регионов.
Локальные переходы появились в стандарте не сразу. А то, что сказано в стандарте про владение переходом (14.2.3.8.5 Transition ownership) вполне подходит для внешних переходов.
В стандарте много непонятного. Например полюса ассоциаций между Vertex и Transition обозначены как производные (правила определены в 14.5.13.6 как операции с такими же именами). Такой приём (вычисление полюса ассоциации по значению противоположного полюса) можно использовать вообще для любой ассоциации, но нигде больше такого нет в стандарте.
-
Давайте по шагам:
Да, можно идти по шагам. Но можно взглянуть с другого угла на диаграммы состояний: не через призму понятий, предлагаемых стандартом, а через исходные положения Харела, через рассмотренные нами примеры. Всё наше обсуждение, как мне кажется, показало, что нарисованное на диаграмме вполне можно понять, а написанное в стандарте даёт такую терминологию, метамодель и семантику, что смыслы расходятся с нарисованным. Можно продолжать держаться за написанное и патчить. Можно смотреть как то же самое нарисованное изложил другими словами Харел. Можно пытаться подбирать свои собственные слова, подходящие к тому, что видит на диаграмме глаз.
Переход имеет ровно одно состояние-исход.
В примере 1 исходом перехода по стандарту и по "нестандарту" является состояние С.
В примере 2 исходом перехода по стандарту является состояние С а по "нестандарту" являются состояния С и B.
В примере 3 исходом перехода по стандарту является состояние С а по "нестандарту" являются состояния С, B и A.
"Нестандарт" мы видим глазами на диаграмме и понимаем, что при переходе придётся выйти из 1 (в примере 1), 2 (в примере 2) и 3 (в примере 3) состояний. Но стандартное понимание исхода узко. Оно говорит, что во всех 3 случаях исход 1. Стандартное понимание исхода позволяет выразить лишь то, надо ли делать exit из состояния, от которого непосредственно начинается переход. Видимое глазами нестандартное понимание исхода позволяет выразить то, что надо делать exit'ы всех покидаемых состояний.
Внешность/локальность перехода определяется по отношению к переходу целиком
В примере 1 переход внешний по стандарту, а по "нестандарту" он внешний для С, но локальный для B (кандидата во владельцы перехода) и А.
В примере 2 переход внешний по стандарту, а по "нестандарту" он внешний для С и B, но локальный для А (кандидата во владельцы перехода).
В примере 3 переход внешний по стандарту, а по "нестандарту" он внешний для С, B и А. Владеет переходом сам автомат (по "нестандарту").
Нестандартное понимание согласуется с видимым глазом расположением части стрелки за границами состояния, по отношению к которому исследуется локальность/нелокальность.
Переход внешний рисуется наружу от границы состояния-исхода и не имеет ограничений кто будет состоянием-целью (соответствующий экземпляр метакласса Transition имеет значение атрибута kind равное external).
Это положение показывает, как стандартное понимание отдаляется от визуального. Глаз видит, что то, будет ли переход внешним (т. е. будет ли автомат делать exit'ы и какие), зависит от всего перехода, от того, как он лёг на диаграмму и на границы состояний, а не только лишь от того, где переход начался.
Не примите выше написанное за попытку предлагать нестандартные термины, метамодель и проч. В обсуждении приведён ряд диаграмм, авторы которых составляли их, опираясь на видимые глазом смыслы и вошли в противоречие со стандартом. Учитывая, что среди авторов известные специалисты и один из "троих друзей", можно предположить, что стандарт не рассчитан на такие примеры. Более простые машины состояний он описывает верно и в полном соответствии с увиденным. А эти -- в неполном.
-
Похоже мы (вдвоем, за стандарт пока утверждать не буду :) ) по-разному понимаем то, что называем состоянием-исходом для перехода:
- Я называю то единственное состояние, от которого идет линия со стрелкой, обозначающая переход
- Вы называете то множество состояний, из которых при совершении перехода придется выйти (и совершить exit-действия)
Но мы одинаково понимаем, что произойдет (какие действия выдут выполнены и в каком порядке) при переходе в примерах:
- exit(C), entry(D)
- exit(C), exit(B), entry(B), entry(D)
- exit(C), exit(B), exit(A), entry(A), entry(B), entry(D)
Вы (и Харел :) ) это объясняете тем, что exit выполняется для тех состояний, которые линия перехода пересекает изнутри наружу, а entry выполняется для тех состояний, которые линия перехода пересекает снаружи внутрь (ориентируясь на конкретный синтаксис).
Я (и стандарт) это объясняем тем, что exit выполняется для цепочки подчиненных состояний от исхода до владельца (но не включая его), а затем entry выполняется для цепочки подчиненных состояний от владельца до цели (ориентируясь на абстрактный синтаксис).
Поскольку в отношении внешних переходов конкретный и абстрактный синтаксисы хорошо согласованы - результат у всех получается одинаковый.
А в отношении локальных переходов абстрактный синтаксис подкачал (Харел рулит!) - вот отсюда и проблемы.
-
Похоже мы (вдвоем, за стандарт пока утверждать не буду :) ) по-разному понимаем то, что называем состоянием-исходом для перехода:
Я не пишу о своём понимании, я показываю, что можно вкладывать смыслы, отличающиеся от стандартных, и получать более внятные, на мой взгляд, объяснения чем те, что предлагает стандарт. У Харела нет деления переходов на локальные/внешние/внутренние. От этого его "метамодель" ничуть не страдает.
Недостаток стандарта мне видится в том, что кое-что, выраженное в конкретном синтаксисе, не нашло явного отражения в абстрактном синтаксисе. Имеется в виду невнятица про владельца, из-за которой в Ваших 3-х примерах его для внешнего перехода придётся определять на глазок, а не по метамодели.
-
Тогда как будет выглядеть ответ на вопрос в первом топике не по стандарту, а по Харелу? (нижний регион будем считать дополненным начальным состоянием с переходом к историческому, как Вы и показывали на примере другой диаграммы из "Ответ #10 : 07 Апреля 2016, 00:57:40")
-
В прочем, сами составители стандарта ему не следуют. Например, на рис. 14.34 приведены примеры локальных переходов (см. аттач), но левый нижний переход не является локальным, он внутренний (его исток и его цель совпадают!). Внутренние переходы по стандарту изображаются без линий (см. 14.2.4.10). Т. е. рисунок из стандарта нарушает сам стандарт.)))
Придумалась казуистическая трактовка, которая бы позволила не считать левый нижний "красный" переход внутренним. Если исток перехода = {s0 s1}, а цель = {s0}, то они не совпадают. А с истоком = {s0 s1} = цели переход был бы внутренним и рисовался бы строчкой текста. Но снова смотрим в метамодель и видим, что исток = vertex, в данном случае, -- состояние, а не коллекция или конфигурация состояний.
Я не забыл про вопрос о трактовке по Харелу. Точный ответ для него достаточно трудоёмок. Чтобы его составить, мне надо освободиться от других дел.
-
Придумалась казуистическая трактовка, которая бы позволила не считать левый нижний "красный" переход внутренним.
А если так: на рис. 14.34 левый нижний (и верхний) переход не внутренний, а локальный потому, что целью является композитное состояние (s0) и в целевую конфигурацию состояний должно войти то элементарное состояние, на которое есть переход от начального псевдосостояния. Пример: дополним рис. 14.34 состоянием s2 и начальным псевдосостоянием внутри s0 с переходом к s2. Тогда для исходной конфигурации {s0, s1} внутренний переход (для s0!) приведет к той же конфигурации {s0, s1}, а локальный переход - к конфигурации {s0, s2}.
-
А если так: на рис. 14.34 левый нижний (и верхний) переход не внутренний, а локальный потому, что целью является композитное состояние (s0) и в целевую конфигурацию состояний должно войти то элементарное состояние, на которое есть переход от начального псевдосостояния. Пример: дополним рис. 14.34 состоянием s2 и начальным псевдосостоянием внутри s0 с переходом к s2. Тогда для исходной конфигурации {s0, s1} внутренний переход (для s0!) приведет к той же конфигурации {s0, s1}, а локальный переход - к конфигурации {s0, s2}.
Разбираемый пример показывает, что описание локальных и внутренних переходов в стандарте дано неаккуратно и не отражено должным образом в метамодели. Так мне кажется.
Очевидно, что нет особой необходимости запрещать рефлексивные локальные переходы. Если составителю диаграммы нужно, чтобы осуществлялся выход из всех вложенных подсостояний, но не выход композитного, он нарисует стрелкой рефлексивный локальный переход. Если не нужно -- он напишет текстом внутренний переход.
К сказанному Вами замечу, что мы не можем считать переход внутренним или локальным не по его свойствам, а по наличию/отсутствию начального псевдосостояния в суперсостоянии и перехода из него. Так мне кажется.)
-
Разбираемый пример показывает, что описание локальных и внутренних переходов в стандарте дано неаккуратно и не отражено должным образом в метамодели. Так мне кажется.
Так и мне кажется, а раз я/Вы не один, то "кажется" уже слишком скромно.
Очевидно, что нет особой необходимости запрещать рефлексивные локальные переходы. Если составителю диаграммы нужно, чтобы осуществлялся выход из всех вложенных подсостояний, но не выход композитного, он нарисует стрелкой рефлексивный локальный переход. Если не нужно -- он напишет текстом внутренний переход.
Хороший пример, вызвал вопрос - в примере из предыдущего сообщения (рис. 14.34 с состоянием s2) какими (локальными или внешними) будут переходы, если бы они были нарисованы внутри s0 (мой вариант в скобках):
- из s0 в s0 (локальный, он и нарисован слева внизу)
- из s0 в s1 (локальный, он и нарисован слева в середине)
- из s1 в s0 (не знаю!, стандарт считает внешним)
- из s1 в s2 (внешний)
К сказанному Вами замечу, что мы не можем считать переход внутренним или локальным не по его свойствам, а по наличию/отсутствию начального псевдосостояния в суперсостоянии и перехода из него. Так мне кажется.)
Переход внутренний или локальный сам по себе, но для локального перехода, целью которого является композитное состояние, это композитное состояние должно иметь начальное псевдосостояние (также, как для внешнего перехода, целью которого является композитное состояние, это композитное состояние должно иметь начальное псевдосостояние).
-
Тогда как будет выглядеть ответ на вопрос в первом топике не по стандарту, а по Харелу?
По Харелу диаграмма состояний основывается на формализме higraph'ов (хайграфов), введённым им же (см. (http://www.dcs.ed.ac.uk/home/kxt/on_visual_formalisms.pdf)).
В хайграфе ребро-переход соединяет между собой два блоба (blobs) -- набора вершин-состояний, соединённых связками И- и ИЛИ-. Каждый такой блоб-набор определяет некоторое множество допустимых конфигураций состояний. Блоб в терминах UML -- это состояние или композитное состояние и, может быть, регион. И это важно, что переход, фактически, описывает биекцию между наборами конфигураций состояний.
Если диаграмма нарисована в соответствии с замыслом Фаулера, то она выглядит так как в приложении.
DisplayAlarm & PlayCD --radio--> DisplayAlarm & PlayRadio
другие части биекции, описываемой переходом по radio:
DisplayAlarm & PlayRadio --radio--> DisplayAlarm & PlayRadio
DisplayCurrent & PlayCD --radio--> DisplayCurrent & PlayRadio
DisplayCurrent & PlayRadio --radio--> DisplayCurrent & PlayRadio
Если нужно, чтобы переход по radio затрагивал оба региона, то стрелку следует рисовать от границы состояния On. В этом случае описываемая переходом биекция:
DisplayAlarm & PlayCD --radio--> DisplayCurrent & PlayRadio
DisplayAlarm & PlayRadio --radio--> DisplayCurrent & PlayRadio
DisplayCurrent & PlayCD --radio--> DisplayCurrent & PlayRadio
DisplayCurrent & PlayRadio --radio--> DisplayCurrent & PlayRadio
Как-то так.
-
Хороший пример, вызвал вопрос - в примере из предыдущего сообщения (рис. 14.34 с состоянием s2) какими (локальными или внешними) будут переходы, если бы они были нарисованы внутри s0 (мой вариант в скобках):
- из s0 в s0 (локальный, он и нарисован слева внизу)
- из s0 в s1 (локальный, он и нарисован слева в середине)
- из s1 в s0 (не знаю!, стандарт считает внешним)
- из s1 в s2 (внешний)
В стандартных терминах локальности/внешности так и будет.
Переход внутренний или локальный сам по себе, но для локального перехода, целью которого является композитное состояние, это композитное состояние должно иметь начальное псевдосостояние (также, как для внешнего перехода, целью которого является композитное состояние, это композитное состояние должно иметь начальное псевдосостояние).
Я имел в виду, что локальность перехода лучше (разумнее) определять для него самого, а не для его возможных связок с переходами из начальных состояний. Конкретная диаграмма может быть такой, что от границы состояния, к которой ведёт локальный/внешний переход, может начинаться цепочка переходов из начальных псевдосостояний, которая телепортирует куда-то внутрь вложенных подсостояний (при этом маршрут телепортации может зависеть от предыстории, например, чтобы было веселее). В таком случае цепочку проще разбить на звенья и описывать поведение по частям. Локальность/внутренность -- это поведение и свойство первого звена.
-
Была мысль продолжить ряд примеров 1-2-3 из этого сообщения (http://www.uml2.ru/forum/index.php?topic=6532.msg40256#msg40256) примерами 4 и 5, где рефлексивный переход из композитного состояния нарисован так, что его дуга пересекает границы одного или двух вложенных состояний. По стандарту такое обозначение нельзя объяснить, как мне кажется. Но почему бы его не допустить, считая, что при таких переходах выполняется цепочка входов, затем действие при переходе, затем цепочка выходов?
-
Если диаграмма нарисована в соответствии с замыслом Фаулера, то она выглядит так как в приложении.
Получается, что Фаулер ошибся - если надо, чтобы переход затронул только один регион (но для нескольких состояний этого региона), то в соответствии с UML надо завести композитное состояние на эти состояния и делать переходы от этого композитного состояния (у вас это пунктирная линия).
Я имел в виду, что локальность перехода лучше (разумнее) определять для него самого, а не для его возможных связок с переходами из начальных состояний.
Я тоже это имел в виду - обязательность наличия начального состояния это дополнительное ограничение.
Локальность/внутренность -- это поведение и свойство первого звена.
Да, причем свойства определяются для каждого звена отдельно. То, что мы называем звеном в стандарте (в метамодели) обозначено transition. Мне давно хотелось поднять вопрос о терминологии: - в описании (спецификации, диаграмме) автомата есть vertex (состояния и псевдосостояния) и transition (звенья)
- при работе автомата есть конфигурации (как допустимые сочетания состояний, но не псевдосостояний) и переходы (смена одной конфигурации на другую). На самом деле это не совсем точно - например не учитывается "историчность".
-
Получается, что Фаулер ошибся - если надо, чтобы переход затронул только один регион (но для нескольких состояний этого региона), то в соответствии с UML надо завести композитное состояние на эти состояния и делать переходы от этого композитного состояния (у вас это пунктирная линия).
Возможно. Фаулера не очень заботило соответствие стандарту: часть его диаграмм им самим помечены как ненормативные. Или до версии 2.5 было что-то, что позволяло ему выразить нужный ему смысл именно так. Полагаю, что он и Рамбо, рисуя переходы от границ композитных состояний, исходили из диаграмм Харела (у которого "регион" -- это состояние, и есть представление о "зазоре" между границами "региона" и суперсостояния, в которое тот входит). Думаю, Фаулеру претила мысль о том, чтобы рисовать лишнюю рамочку. В принципе можно было бы в конкретном синтаксисе установить, что переход от пунктирной линии, разделяющей регионы "принадлежит" региону, а от сплошной границы суперсостояния -- суперсостоянию.
Мне давно хотелось поднять вопрос о терминологии: - в описании (спецификации, диаграмме) автомата есть vertex (состояния и псевдосостояния) и transition (звенья)
- при работе автомата есть конфигурации (как допустимые сочетания состояний, но не псевдосостояний) и переходы (смена одной конфигурации на другую). На самом деле это не совсем точно - например не учитывается "историчность".
Ценное замечание.
-
В принципе можно было бы в конкретном синтаксисе установить, что переход от пунктирной линии, разделяющей регионы "принадлежит" региону, а от сплошной границы суперсостояния -- суперсостоянию.
Переход, который "принадлежит" региону (и идущий от пунктирной линии) нужен только тогда, когда относится ко ВСЕМ без исключения состояниям региона. Если не ко всем, то приходится всё равно заводить композитное состояние (принадлежащее региону), в которое включать только те состояния региона, к которым относится переход. Примеры:- У Рамбо и Блахи в их книге "UML 2.0. Объектно-ориентированное моделирование и разработка" рис. 6.11 - регион InteractiveDisplay, композитное состояние Setup, переход after (90 sec without input)
- У Харела в "STATECHARTS: A VISUAL FORMALISM FOR COMPLEX SYSTEMS" Fig. 28. регион chime-status, композитное состояние enabled, переход d (in chime.on)
-
Переход, который "принадлежит" региону (и идущий от пунктирной линии) нужен только тогда, когда относится ко ВСЕМ без исключения состояниям региона. Если не ко всем, то приходится всё равно заводить композитное состояние (принадлежащее региону), в которое включать только те состояния региона, к которым относится переход. Примеры:- У Рамбо и Блахи в их книге "UML 2.0. Объектно-ориентированное моделирование и разработка" рис. 6.11 - регион InteractiveDisplay, композитное состояние Setup, переход after (90 sec without input)
- У Харела в "STATECHARTS: A VISUAL FORMALISM FOR COMPLEX SYSTEMS" Fig. 28. регион chime-status, композитное состояние enabled, переход d (in chime.on)
Это точно. Просто я подумал, что Рамбо не зря на рис. 6.11 часть переходов (по set day, set clock, view program) нарисовал от границы между регионами, часть (по run program, power on) -- от границы суперсостояния. Или это совпадение.)
В стандарте попалось неясное место (вымарал, т. к. неверно прочёл знак).
-
Просто я подумал, что Рамбо не зря на рис. 6.11 часть переходов (по set day, set clock, view program) нарисовал от границы между регионами, часть (по run program, power on) -- от границы суперсостояния. Или это совпадение.)
Рисуя переход от границы суперсостояния Рамбо, скорее всего, имел в виду то же самое, что и рисуя от границы региона:- регион Night light switch не имеет начального псевдосостояния, а это делает невозможным повторный вход в регион - это нужно для перехода от границы суперсостояния (хотя здесь, скорее всего, ошибка - на стр. 149 есть фраза:"Подсветка управляется выключателем, поэтому начальное значение для нее не имеет смысла". Желание правильное, то есть в диаграмме должно что-то быть, но не исключение начального состояния, а, например, псевдосостояние решения "ромбик" после начального)
- нигде ранее ничего на эту тему не говорится
- рисуя переход от границы региона подчеркивается идея того, что переход внутри суперсостояния это переход внутри региона. Да и любая точка на границе суперсостояния относится ровно к одному региону
-
Рисуя переход от границы суперсостояния Рамбо, скорее всего, имел в виду то же самое, что и рисуя от границы региона
Согласен. А ведь можно было бы наделить разным смыслом переходы идущие от пунктирной и от сплошной границы.
регион Night light switch не имеет начального псевдосостояния, а это делает невозможным повторный вход в регион - это нужно для перехода от границы суперсостояния (хотя здесь, скорее всего, ошибка - на стр. 149 есть фраза:"Подсветка управляется выключателем, поэтому начальное значение для нее не имеет смысла". Желание правильное, то есть в диаграмме должно что-то быть, но не исключение начального состояния, а, например, псевдосостояние решения "ромбик" после начального)
Текст Рамбо показывает, что для него ортогональные регионы -- как бы подмашины.
А вот можно ли рисовать от начального псевдосостояния N-зубец с ромбиком, это вопрос открытый. Параграф 14.2.3.7 говорится, что из него может идти один переход (одно звено?) без сторожа и триггера, на OCL это продублировано в 14.5.6.6 (в другом месте 14.2.4.7 можно указать триггер, если это событие создания экземпляра, а начальное псевдосостояние лежит на верхнем уровне). Куда может идти это звено, об этом не сказано, но можно предположить, что, чтобы ограничения не теряли силу, кончаться оно должно на границе состояния, или псевдосостояния истории. Схожее ограничение есть на переход из псевдосостояния истории. Предположительно, из него тоже нельзя растить многозвенный переход.
нигде ранее ничего на эту тему не говорится
Увы, это так.
рисуя переход от границы региона подчеркивается идея того, что переход внутри суперсостояния это переход внутри региона. Да и любая точка на границе суперсостояния относится ровно к одному региону
Геометрически это верно. Но можно представить себе переход внутри состояния, но не внутри региона с явным форком, от которого идут звенья в регионы. Его первое звено по конкретному синтаксису будет лежать в каком-то из регионов, но по смыслу оно исходит от суперсостояния. Наличие в конкретном синтаксисе явной видимой границы релиона, отделяющей его от суперсостояния, могло бы быть полезно в таком случае.
-
А вот можно ли рисовать от начального псевдосостояния N-зубец с ромбиком, это вопрос открытый. Параграф 14.2.3.7 говорится, что из него может идти один переход (одно звено?) без сторожа и триггера, на OCL это продублировано в 14.5.6.6 (в другом месте 14.2.4.7 можно указать триггер, если это событие создания экземпляра, а начальное псевдосостояние лежит на верхнем уровне). Куда может идти это звено, об этом не сказано, но можно предположить, что, чтобы ограничения не теряли силу, кончаться оно должно на границе состояния, или псевдосостояния истории. Схожее ограничение есть на переход из псевдосостояния истории. Предположительно, из него тоже нельзя растить многозвенный переход.
Может далее не будем особо ориентироваться на стандарт - пытаясь улучшить и формализовать Харела он и не улучшил, и не формализовал (формализация без полноты и непротиворечивости не нужна).
Опираться можно на Харела и на здравый смысл (почти цитата получилась :) ).
Где возможны (и даже обязаны быть) переходы без триггера?- из начального псевдосостояния
- из композитного неортогонального состояния, если в нем есть хоть одно финальное состояние
- где-то ещё
Вопрос: что должно выполняться для исходящих переходов без триггера (из начального псевдосостояния и композитного неортогонального состояния, если в нем есть хоть одно финальное состояние):- ровно один переход, без сторожа
- несколько со сторожами - взаимно исключающими, но полностью перекрывающими все возможностм
- что-то ещё
Ещё вопрос: может ли совсем не быть исходящих переходов без триггера из композитного неортогонального состояния, если в нем есть хоть одно финальное состояние
-
Может далее не будем особо ориентироваться на стандарт - пытаясь улучшить и формализовать Харела он и не улучшил, и не формализовал (формализация без полноты и непротиворечивости не нужна).
Опираться можно на Харела и на здравый смысл (почти цитата получилась :) ).
Принято безоговорочно.)
Где возможны (и даже обязаны быть) переходы без триггера?- из начального псевдосостояния
- из композитного неортогонального состояния, если в нем есть хоть одно финальное состояние
- где-то ещё
Вопрос: что должно выполняться для исходящих переходов без триггера (из начального псевдосостояния и композитного неортогонального состояния, если в нем есть хоть одно финальное состояние):- ровно один переход, без сторожа
- несколько со сторожами - взаимно исключающими, но полностью перекрывающими все возможностм
- что-то ещё
Ещё вопрос: может ли совсем не быть исходящих переходов без триггера из композитного неортогонального состояния, если в нем есть хоть одно финальное состояние
В математической модели конечного автомата определено следующее: во-первых, начальное состояние является полноценным состоянием; во-вторых, в детерминированном автомате (вложенные автоматы не рассматриваем) начальное состояние одно. Харел в своей статье 1987 года пишет о начальных состояниях в том же ключе. Это всегда единственное состояние "региона", которое помечается на диаграмме специальным образом: рисуется кружок-точка и от него проводится одно звено к начальному состоянию. Поначалу (см. "Statecharts in the Making") это спец. обозначение оставалось лишь обозначением, но время шло. На рис. 21 из "Statecharts in the Making" можно видеть, что обозначение стало восприниматься [самим Харелом] на основе конкретного синтаксиса как полноценный переход из неполноценного псевдосостояния, которое в UML назвали "начальным". Думаю, что этот рисунок -- причина сумятицы в стандарте, который в 2-х местах запрещает, а в 1-м разрешает триггеры на переходе из начального п/состояния.
Нужно ли ориентироваться на мат. модель? Ответ не очевиден, так как часто на диаграмме начального состояния нет и это сделано специально. А раз допускается меньше одного начального состояния, то почему бы не допустить больше одного [полагая начальными именно состояния а не спец. обозначение]? Опять же, недетерминированный автомат может иметь несколько начальных состояний, а другие элементы недетерминизма на UML-диаграммах состояний возможны (недетерминированная работа choice и junction).
Но что если обратиться к самому понятию "начального" состояния, как это было проделано с "локальностью/нелокальностью" перехода? Что оно обозначает на самом деле? Можно заметить, что начальность связана со входом в состояние. При каждом входе в композитное состояние (при каждом запуске машины состояний) одно из подсостояний является первым, находящимся в начале, трассы меняющихся текущих состояний. То есть, то, что выше называлось "начальным состоянием" следовало полностью называть "начальным состоянием по умолчанию". При переходах извне состояния, оканчивающихся в подсостоянии, начальное состояние указывается явно как цель перехода. При переходах извне, оканчивающихся на границе подсостояния, начальным состоянием является "начальное по умолчанию". При переходах извне, оканчивающихся в предыстории, начальным оказывается "начальное по предыстории".
Исходя из сказанного, я бы предложил "вернуться к корням", т. е. убрать начальное псевдосостояние и добавить метку "начальное по умолчанию" для состояний. Первый недостаток такого решения очевиден. Нельзя будет разместить на "псевдозвене" действия по инициализации вроде тех, что на рис. 21 у Харела. Однако, это легко решить, введя дополнительное состояние. Это делает немного громоздким автомат, но, на мой взгляд, упрощает метамодель и описание языка диаграмм состояний. Второй недостаток -- есть огромная аудитория пользователей языка, которая привыкла к такому обозначению.
Всё это, конечно, не ответ на заданные вопросы, а контекст этих вопросов.
Про финальное состояние можно вести схожее обсуждение. Так, у Харела почти нет примеров со специально обозначенным финальным состоянием, а те, что есть, как я полагаю, появляются под влиянием UML. Финальное состояние находится на [противоположном] конце трассы меняющихся текущих состояний [или участка этой трассы]. Финальное состояние в "математических" автоматах имеет другой смысл по сравнению со стандартом. Стандартный смысл описан отрывочно и неясно. И. т. п. По всему этому можно судить, удачное ли это обозначение, и оправдывает ли удобство [?] его использования усложнение описания языка.
Третий аспект кроется в том, что метамодель машины состояний предполагает некоторого исполнителя, которого приходится реализовывать некоторым производителям CASE-средств. С позиции реализатора такого исполнителя может быть удобно, чтобы были начальные и финальные состояния.
А теперь, отбросив радикализм), даю свои ответы с умеренно консервативной позиции:
Переходы без триггера возможны:- из начального псевдосостояния (единственный, без сторожа, с возможным эффектом)
- из псевдосостояния истории (для обозначения предыстории по умолчанию: единственный, без сторожа, с возможным эффектом)
- из композитного неортогонального состояния, если в нем есть хоть одно финальное состояние
- из простого состояния, если в нем есть do-деятельность
- из композитного ортогонального состояния, если в каждом его регионе есть одно (или более чем одно) финальное состояние
- (если под переходами понимаются и звенья-части других переходов) из junction и choice псевдосостояний
Только в случаях спец. обозначений (т. е. начального и исторического) накладываются ограничения единственности и отсутствия сторожа. В других случаях их нет. Взаимное исключение и т. д. зависит от того какой автомат мы описываем: детерминированный/недетерминированный/блокирующийся.)
Исходящих переходов без триггера из композитного неортогонального состояния, если в нем есть хоть одно финальное состояние, может не быть. Мы вправе игнорировать событие завершения, если таково описываемое нами поведение.
-
какой автомат мы описываем: детерминированный/недетерминированный/блокирующийся
точно не недетерминированный, скорее всего детерминированный (не нашёл что такое блокирующийся).
из начального псевдосостояния (единственный, без сторожа, с возможным эффектом)
обязательно должен быть
из псевдосостояния истории (для обозначения предыстории по умолчанию: единственный, без сторожа, с возможным эффектом)
а этот уже необязательный (бывают автоматы, в которых достигнуть исторического псевдосостояния возможно только когда композитное состояние исторического псевдосостояния уже посещалось - пример на рис. 21 из "Statecharts in the Making": историческое из checkEnvironment доступно только из paused, в которое можно попасть только побывав в checkEnvironment)
Только в случаях спец. обозначений (т. е. начального и исторического) накладываются ограничения единственности и отсутствия сторожа.
Вместо ограничения отсутствия сторожа можно использовать ограничение, что все сторожа взаимно исключающие, но полностью перекрывающие все возможности, особенно если у junction и choice псевдосостояний нет ограничения, что сторожа всех исходящих переходов взаимно исключающие, но полностью перекрывающие все возможности. Если у junction и choice псевдосостояний такое ограничение есть, то проще сделать единственный переход от начального/исторического к junction/choice, а от junction/choice уже несколько переходов.
из простого состояния, если в нем есть do-деятельность
немного странно - если есть деятельность, то она может закончиться, а если нет - то и никакого события не возникает. Может правильней иметь событие со смыслом, что уже ничего больше делать не надо (или что всё уже сделано), тогда если do-деятельность пуста, считать что это событие наступает, когда состояние становится активным. Такое поведение будет похоже на поведение с финальным состоянием композитного состояния - если у композитного состояния есть исходящий переход без триггера и с "подходящим" сторожем, то финальное состояние как бы "проскакивается".
из композитного неортогонального состояния, если в нем есть хоть одно финальное состояние
из композитного ортогонального состояния, если в каждом его регионе есть одно (или более чем одно) финальное состояние
все исходящие переходы без триггера (как и переходы с совпадающим триггером) должны иметь взаимоисключающие сторожа
-
(не нашёл что такое блокирующийся)
Пожалуй, с блокировкой я погорячился. Этот термин ближе к диаграммам деятельности. Но можно рассматривать что-то вроде "протокольных автоматов с действиями". Т. е. диаграмма состояний составляется в расчёте не на все возможные последовательности событий, а на "правильные". Если события происходят неправильно, автомат ломается-блокируется (в псевдосостоянии, из которого не может попасть в полноценное состояние).
По остальному скажу, что отвечал на первую часть вопроса -- о возможности. Обязательность в некоторых случаях зависит от стиля, от назначения диаграммы и каких-либо соглашений. Например, мне претит, когда есть историческое псевдосостояние, но нет входов в него, или когда на диаграмме есть "состояние-действие", у которого ничего нет, кроме выхода по завершению и действия по входу (громоздкая конструкция, легко заменяемая звеном с эффектом) и т. п.
Если у junction и choice псевдосостояний такое ограничение есть, то проще сделать единственный переход от начального/исторического к junction/choice, а от junction/choice уже несколько переходов.
В своём отступлении про начальное состояние я пытался объяснить (себе) появление и развитие этого специального обозначения. "Странные" ограничения в стандарте связаны, на мой взгляд, с тем, что специальное обозначение ("звено с кружком") со временем стало трактоваться как полноценный переход. Для меня предпочтительнее вернуться назад, к корням, а значит, запретить "звену с кружком" иметь сторожа, входить в составные переходы и т. п.. Тогда причина запретов становится явной. Иначе, следует отмести запреты, и, я думаю, разрешить ждать в начальном состоянии наступления триггера. Т. е. оно должно иметь те же права, что и финальное состояние, с той лишь поправкой, что из финального нельзя явно выйти, а в начальное нельзя явно войти. Позиция авторов текущей версии стандарта странная, как мне кажется, -- ни туда, ни сюда.
немного странно - если есть деятельность, то она может закончиться, а если нет - то и никакого события не возникает. Может правильней иметь событие со смыслом, что уже ничего больше делать не надо (или что всё уже сделано), тогда если do-деятельность пуста, считать что это событие наступает, когда состояние становится активным. Такое поведение будет похоже на поведение с финальным состоянием композитного состояния - если у композитного состояния есть исходящий переход без триггера и с "подходящим" сторожем, то финальное состояние как бы "проскакивается".
Да, такой подход может иметь место. Но к чему он приводит? Насколько он прагматичен? Состояние (с пустой деятельностью и переходом по завершению) превращается не в способ поведения объекта, а в промежуточную проскакиваемую вершину. Такой конструкции легко найти замену -- тот же junction, например. Оправдать использование такой избыточной, по-моему, конструкции затруднительно.
все исходящие переходы без триггера (как и переходы с совпадающим триггером) должны иметь взаимоисключающие сторожа
Для детерминированного автомата такое требование разумно.
P. S. И вообще, попалась тут книга, автор которой призывает использовать UML нестандартно, творчески.) Обдумываю это предложение.)
-
P. S. И вообще, попалась тут книга, автор которой призывает использовать UML нестандартно, творчески.) Обдумываю это предложение.)
- подскажите что за книга
- когда диаграммы используются для непосредственного общения или для размышления - вполне нормально отступить от стандарта, но если речь идет о документировании - отступать от какого-то единого понимания стандарта нельзя
- если нестандартно, творчески означает: в рамках стандарта (или единого понимания стандарта), но не примитивно, то это не может не приветствоваться
Например, мне претит, когда есть историческое псевдосостояние, но нет входов в него
Вы и Харел считаете, что историческое псевдосостояние должно иметь входы. Я согласен, да и стандарт не против. Но тогда появляется вопрос: может ли композитное неортогональное состояние (или регион ортогонального состояния) иметь одновременно псевдосостояния глубокой и неглубокой истории? Стандарт и я считаем, что да (14.5.8.6 первые 2 ограничения). Более того, я (но не стандарт) считаю, что псевдосотояний глубокой (неглубокой) истории может быть несколько - лишь бы их исходящие переходы отличались хоть чем-нибудь (целевым состоянием или деятельностью на переходе).
из финального нельзя явно выйти
Если речь идет о композитном ортогональном состоянии (с 2 регионами), то переход из финального состояния одного из регионов за пределы этого композитного ортогонального состояния легко интерпретируется: срабатывание триггера имеет результат, если в первом регионе достигнуто финальное состояние, а во втором регионе состояние может быть любым. Причем заменить финальное состояние первого региона обычным состоянием нельзя: есть переход без триггера от композитного состояния - значит в каждом регионе должно быть финальное состояние.
Да, такой подход может иметь место. Но к чему он приводит? Насколько он прагматичен? Состояние (с пустой деятельностью и переходом по завершению) превращается не в способ поведения объекта, а в промежуточную проскакиваемую вершину. Такой конструкции легко найти замену -- тот же junction, например. Оправдать использование такой избыточной, по-моему, конструкции затруднительно. Для детерминированного автомата такое требование разумно.
Дам разъяснение: Харел даёт хорошее, но неформальное описание, стандарт пытается дать формальное, но хорошим его не назовёшь. Я пробую (пока для себя) построить модель (в виде диаграммы классов) абстрактного синтаксиса автомата и если что-то плохо укладывается (вызывает усложнение диаграммы), пытаюсь изменить абстрактный синтаксис автомата (не потеряв ничего существенного).
-
1. подскажите что за книга
Д. В. Кознов "Основы визуального моделирования"
2. когда диаграммы используются для непосредственного общения или для размышления - вполне нормально отступить от стандарта, но если речь идет о документировании - отступать от какого-то единого понимания стандарта нельзя
Точно замечено. Отступление означает изменение возможной области применения и аудитории.
3. если нестандартно, творчески означает: в рамках стандарта (или единого понимания стандарта), но не примитивно, то это не может не приветствоваться
Согласен. Хотя сама книга даёт пример нестандартной трактовки отдельных элементов UML-нотации. Что тоже можно рассматривать как своего рода творчество. Впрочем, офтопик.
Вы и Харел считаете, что историческое псевдосостояние должно иметь входы. Я согласен, да и стандарт не против.
Но стандарт ограничивает количество исходящих переходов из исторического псевдосостояния, ничего не говоря об обязательном наличии хоть одного входящего.
Но тогда появляется вопрос: может ли композитное неортогональное состояние (или регион ортогонального состояния) иметь одновременно псевдосостояния глубокой и неглубокой истории? Стандарт и я считаем, что да (14.5.8.6 первые 2 ограничения).
Да, может. Интересно было бы рассмотреть более-менее реалистичный пример, когда это пригождается.
Более того, я (но не стандарт) считаю, что псевдосостояний глубокой (неглубокой) истории может быть несколько - лишь бы их исходящие переходы отличались хоть чем-нибудь (целевым состоянием или деятельностью на переходе).
Я полагаю, то "звено со знаком вертолётной площадки" это условное обозначение вроде "звена с кружком". Поэтому в этом случае я за стандарт в плане ограничений (но не в плане объяснений-описаний).
Если речь идет о композитном ортогональном состоянии (с 2 регионами), то переход из финального состояния одного из регионов за пределы этого композитного ортогонального состояния легко интерпретируется: срабатывание триггера имеет результат, если в первом регионе достигнуто финальное состояние, а во втором регионе состояние может быть любым. Причем заменить финальное состояние первого региона обычным состоянием нельзя: есть переход без триггера от композитного состояния - значит в каждом регионе должно быть финальное состояние.
Я имел в виду лишь то, что из финального состояния нельзя явно рисовать переходы.
Дам разъяснение: Харел даёт хорошее, но неформальное описание, стандарт пытается дать формальное, но хорошим его не назовёшь. Я пробую (пока для себя) построить модель (в виде диаграммы классов) абстрактного синтаксиса автомата и если что-то плохо укладывается (вызывает усложнение диаграммы), пытаюсь изменить абстрактный синтаксис автомата (не потеряв ничего существенного).
Такую инициативу можно только поддержать.
-
Но стандарт ограничивает количество исходящих переходов из исторического псевдосостояния, ничего не говоря об обязательном наличии хоть одного входящего.
Хоть не запрещает.
Я полагаю, то "звено со знаком вертолётной площадки" это условное обозначение вроде "звена с кружком". Поэтому в этом случае я за стандарт в плане ограничений (но не в плане объяснений-описаний).
На картинке - верхний автомат: как добиться того же эффекта с одним историческим (то, что триггер "a" на горизонтальных стрелках, а триггер "b" на вертикальных - случайное совпадение)?
Я имел в виду лишь то, что из финального состояния нельзя явно рисовать переходы.
На картинке - нижний автомат: как добиться того же эффекта без перехода из финального состояния (последовательность триггеров "аа" приводит к State8, "ab" и "ba" - к State10)?
-
На картинке - верхний автомат: как добиться того же эффекта с одним историческим (то, что триггер "a" на горизонтальных стрелках, а триггер "b" на вертикальных - случайное совпадение)?
От предыстории по умолчанию можно избавиться, заведя переменную-признак "были ли мы в State1", добавить действия по её инициализации и изменению, раздвоить переходы в State1 через choice/junction со сторожем, который при истинности признака ведёт нас в единое псевдосостояние истории, при ложности -- в нужное подсостояние внутри State1. Понятное дело, что с помощью введения переменной можно вообще избавиться от исторических псевдосостояний.
На картинке - нижний автомат: как добиться того же эффекта без перехода из финального состояния (последовательность триггеров "аа" приводит к State8, "ab" и "ba" - к State10)?
Можно убрать явный переход из финального состояния, финальное состояние в верхнем регионе сделать обычным, завести две переменные-признака x1 -- "завершён ли верхний регион?" и x2 -- "завершён ли нижний регион?", добавить их инициализацию и действия по изменению, групповой переход по завершению из State6 заменить на переход по триггеру -- событию изменения when(x1 and x2).
Я не настаиваю, что именно так и нужно делать. Должен сработать компромисс -- усложняя нотацию, соизмеряем, оправдывает ли более трудночитаемое описание языка выгоды от более лаконичных диаграмм в особых случаях. Как я писал выше, смыслы финального состояния в стандарте не прояснены должным образом. Возможно, что допущение явных переходов из финальных состояний (а также do-деятельностей в них, внутренних переходов) не усложнит язык, а лишь очистит его от лишних запретов. Некоторое затруднение может быть связано с устоявшимся стереотипом, что явных переходов из финального состояния не бывает.
-
Сначала о глобальном - мне нравится, как проходит обсуждение, поэтому появились вопросы:
- есть ли в интернете другие места (лучше русскоязычные), где обсуждения похожих тем (нюансы языков моделирования) происходят так же конструктивно?
- почему молчит остальная аудитория форума, варианты:
- джуниоры пытаются разобраться в том, что все уже давно знают - пусть разбираются сами, лучше усвоят;
- очень важная, но сложная тема - сказать по ходу нечего, дождёмся результатов;
- то, что обсуждают, никому никогда не понадобится, но влезать - себе дороже?
От предыстории по умолчанию можно избавиться, заведя переменную-признак "были ли мы в State1", добавить действия по её инициализации и изменению, раздвоить переходы в State1 через choice/junction со сторожем, который при истинности признака ведёт нас в единое псевдосостояние истории, при ложности -- в нужное подсостояние внутри State1. Понятное дело, что с помощью введения переменной можно вообще избавиться от исторических псевдосостояний.
Наличие и трактовка перехода из исторического псевдосостояния как раз направлены на избавление от такой переменной-признака. Избавление от переменных оправдано тем, что переменные сильно снижают наглядность диаграммы: места, где они изменяются и проверяются ничем визуально не связаны, кроме имени переменной.
Должен сработать компромисс -- усложняя нотацию, соизмеряем, оправдывает ли более трудночитаемое описание языка выгоды от более лаконичных диаграмм в особых случаях.
Несколько псевдосостояний истории в регионе - изменение только в одном месте синтаксиса (0-1 на 0-*), но не семантики (неважно сколько исторических псевдосостояний, при выполнении можем одновременно добраться только до одного).
Как я писал выше, смыслы финального состояния в стандарте не прояснены должным образом. Возможно, что допущение явных переходов из финальных состояний (а также do-деятельностей в них, внутренних переходов) не усложнит язык, а лишь очистит его от лишних запретов. Некоторое затруднение может быть связано с устоявшимся стереотипом, что явных переходов из финального состояния не бывает.
Финальное является именно состоянием, а не псевдосостоянием потому, что автомат может находиться именно в нём (особенно, если это финальное состояние композитного состояния). Отсутствие в финальном состоянии do-деятельностей и внутренних переходов обусловлено тем, что хочется подчеркнуть, что ничего существенного (с точки зрения региона/состояния, к которому относится финальное состояние) уже произойти не может - только выход, причём это будет и выход из региона/состояния. Но оказалось, что в случае композитного ортогонального (в отличие от неортогонального) состояния появляется новая ситуация - часть регионов достигла финального состояния, а часть - нет.
-
Сначала о глобальном - мне нравится, как проходит обсуждение, поэтому появились вопросы:- есть ли в интернете другие места (лучше русскоязычные), где обсуждения похожих тем (нюансы языков моделирования) происходят так же конструктивно?
- почему молчит остальная аудитория форума, варианты:
- джуниоры пытаются разобраться в том, что все уже давно знают - пусть разбираются сами, лучше усвоят;
- очень важная, но сложная тема - сказать по ходу нечего, дождёмся результатов;
- то, что обсуждают, никому никогда не понадобится, но влезать - себе дороже?
Мне тоже понравился наш обмен мнениями. Так перемыть косточки UML у меня даже с коллегами на работе не получалось.
Других мест не знаю, т. к. не искал. Может быть, кто-то из старожилов подскажет.
Комментировать участие/неучастие в этой теме других участников не возьмусь. Я почти их не знаю.
Наличие и трактовка перехода из исторического псевдосостояния как раз направлены на избавление от такой переменной-признака.
Справедливо. С переменными диаграмма становится более императивной, что не всегда желательно.
неважно сколько исторических псевдосостояний, при выполнении можем одновременно добраться только до одного.
Это так, но, вероятно, придётся прописать такое положение в языке. Сделать это формально (на OCL) затруднительно. Сама нотация может обескураживать: несколько псевдосостояний предыстории изображают одну предысторию и несколько меток для состояний, являющихся предысторией по умолчанию. Мне кажется, что такая пометка состояния могла бы делаться не звеном из "вертолётной площадки", а тегом на самом состоянии. Хотя такой вариант, скорее всего менее нагляден, чем стандартный.
Отсутствие в финальном состоянии do-деятельностей и внутренних переходов обусловлено тем, что хочется подчеркнуть, что ничего существенного (с точки зрения региона/состояния, к которому относится финальное состояние) уже произойти не может - только выход, причём это будет и выход из региона/состояния. Но оказалось, что в случае композитного ортогонального (в отличие от неортогонального) состояния появляется новая ситуация - часть регионов достигла финального состояния, а часть - нет.
Мне интересно, откуда появилась в UML такая трактовка? Уж не от неудавшегося сращивания диаграмм состояний с диаграммами деятельности в 1-й версии UML? Ведь в "математических" автоматах финальное состояние -- обычное состояние с дополнительным свойством, т. е. у математиков оно в каком-то смысле больше, чем обычное состояние, а не наоборот.
-
Так перемыть косточки UML у меня даже с коллегами на работе не получалось.
Цель - не наехать, а выбрать или скомпоновать для себя подходящее средство для использования. У меня нет большого опыта практического использования диаграмм состояний UML, а диаграмм классов - есть. И тут UML - явный лидер по возможностям, опережая и "сущность-связь", и Object Role Modeling, и EXPRESS, и других (хотя в отдельных аспектах может им уступать).
Это так, но, вероятно, придётся прописать такое положение в языке. Сделать это формально (на OCL) затруднительно.
Убрать из 14.5.8.6 первые 2 ограничения.
Сама нотация может обескураживать: несколько псевдосостояний предыстории изображают одну предысторию и несколько меток для состояний, являющихся предысторией по умолчанию.
Просто каждый вход в композитное состояние может иметь своё отношение к обработке истории (строго говоря каждый вход внутрь и одно общее на все входы на границу композитного состояния): будет ли учитываться предыдущее посещение композитного состояния и, если да, то что делать, если предыдущего посещения не было.
Мне кажется, что такая пометка состояния могла бы делаться не звеном из "вертолётной площадки", а тегом на самом состоянии. Хотя такой вариант, скорее всего менее нагляден, чем стандартный.
Когда-то такой знак "вертолётной площадки" и был тэгом на композитном состоянии (без входящих и исходящих переходов), что означало, что любой повторный вход в композитное состояние означает продолжение с места прерывания. Потом стало ясно, что это слишком узко, что иногда надо продолжить, а иногда и начать по новой.
Мне интересно, откуда появилась в UML такая трактовка? Уж не от неудавшегося сращивания диаграмм состояний с диаграммами деятельности в 1-й версии UML? Ведь в "математических" автоматах финальное состояние -- обычное состояние с дополнительным свойством, т. е. у математиков оно в каком-то смысле больше, чем обычное состояние, а не наоборот.
В "математических" автоматах финальное состояние играет другую роль: если обработка последовательности сигналов завершилась в финальном состоянии, то последовательность "правильная".
-
Зачем же вмешиваться в столь длинную и детальную дискуссию? Тут надо глубоко проникнуть в проблему, которая двигает эту беседу. А это на самом деле не так просто. Потому ваша беседа воспринимается, как академическая.
-
Убрать из 14.5.8.6 первые 2 ограничения.
Я думал о том, что затруднительно описать ограничение, которое бы сказало, что диаграмма "с душком" (например, из-за недетерминированного составного перехода, у которого несколько звеньев заканчиваются в разных исторических псевдосостояниях одного региона). Впрочем, такие сложности не связаны именно с множественностью исторических псевдосостояний, должен признать.
Просто каждый вход в композитное состояние может иметь своё отношение к обработке истории (строго говоря каждый вход внутрь и одно общее на все входы на границу композитного состояния): будет ли учитываться предыдущее посещение композитного состояния и, если да, то что делать, если предыдущего посещения не было.
Попробую так. Конкретный синтаксис с несколькими предысториями допускает толкование, что для каждого способа входить в состояние по предыстории (в Вашем примере от 16.06 таких способов у State1 два -- левый и правый) есть отдельная память, ведущая независимую историю. Т. е. при входе слева срабатывает левая предыстория, справа -- правая. Если бы "вертолётная площадка" была одна, повода для такого толкования не возникало бы.
Когда-то такой знак "вертолётной площадки" и был тэгом на композитном состоянии (без входящих и исходящих переходов), что означало, что любой повторный вход в композитное состояние означает продолжение с места прерывания. Потом стало ясно, что это слишком узко, что иногда надо продолжить, а иногда и начать по новой.
Замечу, что у Харела (автора предысторий) во всех его примерах в "площадку" обязательно входит звено. То есть, у него это не совсем тэг.
Общий недостаток нотации начальных и исторических псевдосостояний вижу в том, что для обозначения дефолтных состояний (начального по умолчанию, истории по умолчанию) используются звенья. Визуально такие звенья мало чем отличаются от обычных и хочется повесить на них триггер, к примеру. Но стандарт не велит. Если бы такие псевдозвенья выглядели бы не так, как обычные, запреты стандарта были бы подкреплены конкретным синтаксисом. Придумался простой способ достичь этого. Псевдопереходы из начальных и исторических псевдосостояний нужно рисовать пунктиром. Связать пунктир с невозможностью повесить триггер легко.
В "математических" автоматах финальное состояние играет другую роль: если обработка последовательности сигналов завершилась в финальном состоянии, то последовательность "правильная".
"Математическая" трактовка почти та же, что у протокольных диаграмм состояний. А протокольные финальные состояния нечем не отличаются от обычных.
К финальному состоянию стандарт привязывает специфический аспект -- генерацию события завершения для региона. Схожий с завершением, на мой взгляд, момент связан с терминацией (terminate-псеводостоянием). Только terminate прибивает всю машину. Представим, что есть два вида таких псевдосостояний: первый (обычный) -- для завершения региона, второй (со *) -- для завершения всей машины. Т. е. я хочу подвести к тому, что финальное состояние региона -- это, по смыслу, псевдосостояние, т. к. это условное обозначение.
Рассуждения о том, что финальное состояние -- стабильная вершина, как мне кажется, схоластичны. Если регион достиг финала, то нет никакой разницы, считаем ли мы "текущим" одно из его финальных состояний или никакое из его подсостояний, поскольку он завершён. Понятие стабильной вершины само по себе вызывает вопросы. Простое состояние без do-деятельности с переходом из него, запускаемым по завершению, стабильно лишь фиктивно. При работе машины оно проскакивается. Т. е. стабильность определяется работой автомата, а не на уровне синтаксиса. Псевдосостояния -- это спец. обозначения. Именно этим они отличаются от состояний. То, что псевдосостояния нестабильные вершины, не отделяет их от состояний (которые тоже могут быть нестабильны).
-
Конкретный синтаксис с несколькими предысториями допускает толкование, что для каждого способа входить в состояние по предыстории (в Вашем примере от 16.06 таких способов у State1 два -- левый и правый) есть отдельная память, ведущая независимую историю. Т. е. при входе слева срабатывает левая предыстория, справа -- правая. Если бы "вертолётная площадка" была одна, повода для такого толкования не возникало бы.
Когда "вертолётная площадка" одна, то и история одна, причём как она изменяется (до сих пор мы больше внимания уделяли тому, как история используется) тоже понятно: если выход через финальное состояние, то история обнуляется, если нет, то в историю записывается та конфигурация, из которой произошёл выход (в случае неглубокой истории из этой конфигурации будет использоваться только верхний уровень).
Если считать, что для каждого способа входить в состояние по предыстории есть отдельная память, то нужно определить как на каждую из этих "памятей" влияет выход из композитного состояния. На примере диаграммы: если произошёл выход из State1, конфигурация могла быть State2, а могла и State3. Как это повлияет на историю левого исторического и как это повлияет на историю правого исторического (ведь выход из State2 не означает, что вход был через левое историческое)? Может считать, что влияние оказывается на ту историю, через которую произошёл вход? Но вход мог произойти и без истории (в примере этого нет, но могло бы быть)!
Остаётся вариант, что история композитного состояния одна общая (это согласуется и с тем случаем, когда имеются по одному псевдосостоянию и глубокой и неглубокой истории - история у них общая).
Замечу, что у Харела (автора предысторий) во всех его примерах в "площадку" обязательно входит звено. То есть, у него это не совсем тэг.
Здесь в "площадку" звенья ни входят, ни выходят (правда это не Харел и не UML) http://matlab.exponenta.ru/stateflow/book1/2.php
Общий недостаток нотации начальных и исторических псевдосостояний вижу в том, что для обозначения дефолтных состояний (начального по умолчанию, истории по умолчанию) используются звенья. Визуально такие звенья мало чем отличаются от обычных и хочется повесить на них триггер, к примеру. Но стандарт не велит. Если бы такие псевдозвенья выглядели бы не так, как обычные, запреты стандарта были бы подкреплены конкретным синтаксисом. Придумался простой способ достичь этого. Псевдопереходы из начальных и исторических псевдосостояний нужно рисовать пунктиром. Связать пунктир с невозможностью повесить триггер легко.
Конкретный синтаксис это вообще субъективно. Тут бы с абстрактным синтаксисом (где всё сводится к "да" или "нет") разобраться.
"Математическая" трактовка почти та же, что у протокольных диаграмм состояний. А протокольные финальные состояния нечем не отличаются от обычных.
Я понимаю "математический" автомат, как что-то похожее на https://ru.wikipedia.org/wiki/Конечный_автомат
К финальному состоянию стандарт привязывает специфический аспект -- генерацию события завершения для региона. Схожий с завершением, на мой взгляд, момент связан с терминацией (terminate-псеводостоянием). Только terminate прибивает всю машину. Представим, что есть два вида таких псевдосостояний: первый (обычный) -- для завершения региона, второй (со *) -- для завершения всей машины. Т. е. я хочу подвести к тому, что финальное состояние региона -- это, по смыслу, псевдосостояние, т. к. это условное обозначение.
Рассуждения о том, что финальное состояние -- стабильная вершина, как мне кажется, схоластичны. Если регион достиг финала, то нет никакой разницы, считаем ли мы "текущим" одно из его финальных состояний или никакое из его подсостояний, поскольку он завершён. Понятие стабильной вершины само по себе вызывает вопросы. Простое состояние без do-деятельности с переходом из него, запускаемым по завершению, стабильно лишь фиктивно. При работе машины оно проскакивается. Т. е. стабильность определяется работой автомата, а не на уровне синтаксиса. Псевдосостояния -- это спец. обозначения. Именно этим они отличаются от состояний. То, что псевдосостояния нестабильные вершины, не отделяет их от состояний (которые тоже могут быть нестабильны).
Состояния могут быть нестабильными, а псевдосостояния нестабильны всегда.
В примере 2-я диаграмма - состояние State6 определяет 3 стабильные конфигурации ({State7, State9},{State7, final},{final, State9}) и одну нестабильную - {final, final}. А если не будет исходящего без триггера перехода из State6 - 4 стабильные? А если такой переход будет, но с условием (которое может и выполняться, и невыполняться) - и то проскакивается, то не проскакивается?
-
Остаётся вариант, что история композитного состояния одна общая (это согласуется и с тем случаем, когда имеются по одному псевдосостоянию и глубокой и неглубокой истории - история у них общая).
Другой вариант, что, если непонятно в какую память записывать, то записывать в обе.) Думаю, что можно напридумывать правила, описывающие модель с несколькими памятями. Речь шла о визуальной метафоре, которая, как мне кажется, сообщает не о том, что есть несколько вариантов истории по умолчанию, а о том, что есть несколько историй. Вот у Харела предлагалось использовать в сторожевых условиях темпоральную логику, сведения о текущем состоянии в ортогональном регионе и т. п. В таком же духе можно от общей одной "вертолётной площадки" провести пунктиры к разным дефолтным предысториям и на пунктирах этих написать "сторожей", проясняющих выбор дефолтной предыстории.
Здесь в "площадку" звенья ни входят, ни выходят (правда это не Харел и не UML)
Создателям Симулинка, вероятно, так было проще реализовывать симулятор. Они и junction превратили в choice.) Реализаторская точка зрения тоже имеет значение, вообще говоря.
Конкретный синтаксис это вообще субъективно.
В подкрепление этого тезиса можно вспомнить конкретные синтаксисы от каждого из "троих друзей" до того как их "подружили".)
Состояния могут быть нестабильными, а псевдосостояния нестабильны всегда.
Могу ещё раз сказать, что стабильность определяется при работе автомата. Можно построить пример [бессмысленного] автомата без стабильных состояний. Упор на стабильность не поясняет, зачем в язык были введены псевдосостояния. Введены они как спец. обозначения, и относиться к ним, как я полагаю, стоит именно так. Можно поправить стандарт, указав там "могут/всегда", но это мало что прояснит о запрете, к примеру, цеплять к псевдосостоянию входное и выходное действие. Оно -- вершина? Вершина. Мы через неё проходим? Проходим -- вон стрелочки идут. Значит, входим и выходим, но не задерживаемся, ведь она нестабильная вершина. И т. д. Если говорить, что псевдосостояние -- это спец. обозначение, что звено, входящее в него или исходящее из него -- не переход, то такое описание будет адекватнее, как мне кажется. Про стабильность/нестабильность можно говорить, рассматривая работу автомата, если это важно по каким-то [другим] причинам.
Если угодно, разница между псевдосостоянием и обычным состоит в том, что для того, чтобы покинуть состояние придётся "съесть" из очереди событие (даже если это событие завершения, которое автомат сам себе может подкладывать в очередь в тот момент, когда "хочет" его съесть). Покидание псевдосостояния происходит сразу без "съедания" события из очереди. Но ведь можно нагромоздить и такое, что при проходе сквозь псевдосостояние порождается событие его завершения, а звено из псевдосостояния должно рассматриваться как переход по этому порождаемому событию. Так мы нивелируем разницу между проскакиваемым состоянием и псевдосостоянием с точки зрения работы автомата.
-
В примере 2-я диаграмма - состояние State6 определяет 3 стабильные конфигурации ({State7, State9},{State7, final},{final, State9}) и одну нестабильную - {final, final}. А если не будет исходящего без триггера перехода из State6 - 4 стабильные? А если такой переход будет, но с условием (которое может и выполняться, и невыполняться) - и то проскакивается, то не проскакивается?
Я рассматриваю способы указывать, что в некоторых состояниях генерируется событие завершения региона. Это можно делать, рисуя от таких состояний (псевдо)звено к псевдосостоянию "крестик без *". ("Крестик со *" будет генерировать завершение всей машины.) Конструкция из состояния и "крестика" будет по смыслу похожа на стандартное финальное состояние, с той лишь разницей, что от обычного состояния можно рисовать переходы, а от финального нельзя, что в обычном состоянии может быть do-деятельность, а в финальном нельзя, входные/выходные действия -- аналогично. Т. е. генерация завершений может быть изображена спец. обозначением -- псевдосостоянием, соединённым с обычным состоянием, а не неполноценным финальным недосостоянием.
Генерацию завершения можно изображать как спец. действие, хотя это может быть не так наглядно.
Рассуждения о нестабильности финальных состояний были неточны, признаю. Можно пытаться считать, что, попав в финальное состояние региона, автомат генерирует событие завершения региона и текущим состоянием становится сам завершённый регион (по Харелу регионы -- состояния). В случае с несколькими финальными состояниями внутри региона, это неудобно, так как может быть важно в каком именно из них произошло завершение.
-
Другой вариант, что, если непонятно в какую память записывать, то записывать в обе.)
Дело в том, что всегда непонятно в какую память записывать, поэтому если записывать в обе,то обе памяти оказываются идентичными.
Вот у Харела предлагалось использовать в сторожевых условиях темпоральную логику, сведения о текущем состоянии в ортогональном регионе и т. п. В таком же духе можно от общей одной "вертолётной площадки" провести пунктиры к разным дефолтным предысториям и на пунктирах этих написать "сторожей", проясняющих выбор дефолтной предыстории.
Да, это формально допустимый вариант, но он требует введения переменной, которая будет содержать информацию для работы "сторожей". А переменная требует инициализации значения и ...(выше уже говорилось: "переменные сильно снижают наглядность диаграммы"). Другое дело, если переменные уже существуют для обслуживания автомата - например используются в каких-то деятельностях (entry, exit, do или на переходах).
По поводу пунктиров: они будут выражать невозможность повесить триггер, но есть и другие ограничения, например обязательное отсутствие сторожа и/или деятельности на переходе. Есть еще одно соображение (не против визуального выделения, а против именно пунктира) - когда рисуешь от руки на бумаге, то часто сначала ясно, что нужна соединительная линия, а только потом ясно, какого она типа. А превратить нарисованную сплошную в пунктирную достаточно затратно, уж лучше бы сделать какую-нибудь пометку. Но это опять про конкретный синтаксис ;)
-
Дело в том, что всегда непонятно в какую память записывать, поэтому если записывать в обе,то обе памяти оказываются идентичными.
Каждый выход происходит после какого-то входа. Часть входов происходит по левому пути (через левую память), часть по правому. Через какую память входили, в ту и пишем.
Да, это формально допустимый вариант, но он требует введения переменной, которая будет содержать информацию для работы "сторожей". А переменная требует инициализации значения и ...(выше уже говорилось: "переменные сильно снижают наглядность диаграммы"). Другое дело, если переменные уже существуют для обслуживания автомата - например используются в каких-то деятельностях (entry, exit, do или на переходах).
Харел использовал "системные переменные", которые описывают [текущую | прошлую] конфигурацию состояний автомата. Они не вводятся автором диаграммы. Пример стандартной "системной переменной" без имени -- время -- в событиях времени at(12pm), after(1ns).
По поводу пунктиров: они будут выражать невозможность повесить триггер, но есть и другие ограничения, например обязательное отсутствие сторожа и/или деятельности на переходе. Есть еще одно соображение (не против визуального выделения, а против именно пунктира) - когда рисуешь от руки на бумаге, то часто сначала ясно, что нужна соединительная линия, а только потом ясно, какого она типа. А превратить нарисованную сплошную в пунктирную достаточно затратно, уж лучше бы сделать какую-нибудь пометку. Но это опять про конкретный синтаксис ;)
Думаю, что, разделяя звенья и псевдозвенья, можно договориться о том, что на самом деле запрещать на псевдозвене (и не запрещать сторожей и эффекты просто ради запрета). Пунктиры взяты по аналогии с зависимостями с диаграмм классов. Там-то они прижились.
P. S. Выходила книга Бьянкуцци, Уорден. Пионеры программирования. В ней помимо всего прочего "трое друзей" рассказывают про историю UML, критикуют и предсказывают ему будущее. Pdf-ка гуляет по сети.
-
Прибавлю, что в "стандарте" (http://goo.gl/53njmo) UMLя для слепых пунктиров не было предусмотрено, но их легко ввести, если использовать резинки с узелками. ;D
-
Каждый выход происходит после какого-то входа. Часть входов происходит по левому пути (через левую память), часть по правому. Через какую память входили, в ту и пишем.
Ответ:
Если считать, что для каждого способа входить в состояние по предыстории есть отдельная память, то нужно определить как на каждую из этих "памятей" влияет выход из композитного состояния. На примере диаграммы: если произошёл выход из State1, конфигурация могла быть State2, а могла и State3. Как это повлияет на историю левого исторического и как это повлияет на историю правого исторического (ведь выход из State2 не означает, что вход был через левое историческое)? Может считать, что влияние оказывается на ту историю, через которую произошёл вход? Но вход мог произойти и без истории (в примере этого нет, но могло бы быть)!
Правила для обслуживания нескольких исторических псевдосостояний должны быть такими, чтобы если будет только одно историческое псевдосостояние обслуживание происходило так, как это описано в стандарте или у Харела. Я вижу 2 варианта:- любой выход оказывает влияние на все истории
- выход оказывает влияние только на историю, по которой произошёл вход, а если вход произошёл без истории, то на все истории
Критерием, который мог помочь при выборе между этими вариантами, могло быть описание поведения, если композитное состояние одновременно имеет и глубокую, и неглубокую историю. Но у Харела таких случаев я не нашел, и в стандарте тоже (хотя в 14.5.8.6 первые 2 ограничения записаны так, что это возможно). Моя позиция - любой выход оказывает влияние на все истории (но подкрепить её нечем).
P. S. Выходила книга Бьянкуцци, Уорден. Пионеры программирования. В ней помимо всего прочего "трое друзей" рассказывают про историю UML, критикуют и предсказывают ему будущее. Pdf-ка гуляет по сети.
Читал: объясняет, почему плохо, но неясно как будет хорошо.
-
Ответ:
Я недопонимаю. Картинка в голове такая. Если входим через левую/правую память, то сразу пишем в неё подсостояние, в котором оказались (глубина вложения подсостояния зависит от глубины истории). [Вообще говоря, не пишем, т. к. оно там и так лежит.] Вытираем записанное при смене подсостояния на нужном уровне глубины, пишем новое. Дошли до финального -- вытираем (+ вписываем предысторию по умолчанию либо начальное по умолчанию). Вышли -- предысторией стало то, что записали последним. Если входим не через левую/ правую память, то те же самые действия выполняем с каждой памятью (предварительно очищая, если не пуста).
Ваш пример мне не ясен, так как в нём лишь часть картинки -- как выходим.
Читал: объясняет, почему плохо, но неясно как будет хорошо.
По мне, в большей степени, объясняет, что у каждого в голове своя порода тараканов.)
-
Критерием, который мог помочь при выборе между этими вариантами, могло быть описание поведения, если композитное состояние одновременно имеет и глубокую, и неглубокую историю. Но у Харела таких случаев я не нашел, и в стандарте тоже (хотя в 14.5.8.6 первые 2 ограничения записаны так, что это возможно). Моя позиция - любой выход оказывает влияние на все истории (но подкрепить её нечем).
Необязательно. Можно считать, что разноуровневые истории работают совместно, а одноуровневые независимы.) Не то чтобы я настаиваю на множественности/независимости памятей. Речь скорее о соответствии между визуальным представлением и идеями, которые оно отображает. Если история/память одна, то и "вертолётная площадка" одна. Если несколько вариантов предыстории, то несколько элементов обозначающих эти варианты (а не несколько "площадок"). Разумно, если отдельное отображение имеется для памяти и отдельное -- для предысторий по умолчанию. В стандарте для второго служит [псевдо]звено. Значит, для первого -- "площадка". Отсюда "площадка" одна, псевдозвеньев несколько. Такая логика.
-
Необязательно. Можно считать, что разноуровневые истории работают совместно, а одноуровневые независимы.)
Недопустимое сочетание: пусть есть одна глубокая и две неглубокие истории - получается глубокая совместна с каждой неглубокой, а неглубокие между собой нет! Допустимы сочетания:- разноуровневые истории работают совместно, и одноуровневые совместно (одна общая история на все "вертолётные площадки")
- разноуровневые истории работают независимо, а одноуровневые совместно(одна общая история на все "глубокие" "вертолётные площадки" и одна общая история на все "неглубокие" "вертолётные площадки")
- разноуровневые истории работают независимо, и одноуровневые независимо (своя история на каждую "вертолётную площадку")
Не то чтобы я настаиваю на множественности/независимости памятей. Речь скорее о соответствии между визуальным представлением и идеями, которые оно отображает. Если история/память одна, то и "вертолётная площадка" одна. Если несколько вариантов предыстории, то несколько элементов обозначающих эти варианты (а не несколько "площадок"). Разумно, если отдельное отображение имеется для памяти и отдельное -- для предысторий по умолчанию. В стандарте для второго служит [псевдо]звено. Значит, для первого -- "площадка". Отсюда "площадка" одна, псевдозвеньев несколько. Такая логика.
Не то чтобы я настаиваю на единственности/зависимости памятей. Но для меня "вертолётная площадка" - это не признак "отдельной" истории, а признак обращения к "общей" истории, а звено, выходящее из "вертолётной площадки" - указание что делать, если в этой "общей" истории ничего не записано (или записано "особое" значение).
Картинка в голове такая. Если входим через левую/правую память, то сразу пишем в неё подсостояние, в котором оказались (глубина вложения подсостояния зависит от глубины истории). [Вообще говоря, не пишем, т. к. оно там и так лежит.] Вытираем записанное при смене подсостояния на нужном уровне глубины, пишем новое. Дошли до финального -- вытираем (+ вписываем предысторию по умолчанию либо начальное по умолчанию). Вышли -- предысторией стало то, что записали последним. Если входим не через левую/ правую память, то те же самые действия выполняем с каждой памятью (предварительно очищая, если не пуста).
Как-то не очень хорошо выглядит - при одних входах работаем ровно с одной памятью, а при других - со всеми памятями. Да и что называем "входом" - пересечение границы композитного состояния снаружи внутрь, которое заканчивается на "вертолётной площадке" или ещё где-нибудь? А как воспринимать звено, которое заканчивается на "вертолётной площадке", но не пересекает границы композитного состояния (Harel "STATECHARTS: A VISUAL FORMALISM FORCOMPLEX SYSTEMS*" Fig.14)? Попутно вопрос по этой диаграмме: вместо использования конструкции с историческим псевдосостоянием можно завести внутренний переход в состоянии update (хотя бы в UML)?
-
Недопустимое сочетание: пусть есть одна глубокая и две неглубокие истории - получается глубокая совместна с каждой неглубокой, а неглубокие между собой нет!
Да. Получается. А что в этом недопустимого? Содержание то у глубокой и неглубокой (если они осмысленно используются) может быть разным и меняться в разные моменты. Совместность означает, что мы работаем на обоих уровнях.
Не то чтобы я настаиваю на единственности/зависимости памятей. Но для меня "вертолётная площадка" - это не признак "отдельной" истории, а признак обращения к "общей" истории, а звено, выходящее из "вертолётной площадки" - указание что делать, если в этой "общей" истории ничего не записано (или записано "особое" значение).
При таком подходе, я полагаю, "площадка" становится чем-то вроде оперения у стрелки псевдозвена. (Как у некоторых математиков стрелки из ниоткуда помечали начальные состояния автоматов. У Харела кружок начального состояния столь мал, что похож на оперение стрелки.) Но в оперение-"площадку" входит переход. Т. е. она -- вершина. А зачем одну общую предысторию представлять несколькими разными вершинами? Как глазом увидеть, что она общая? Почему видимые несколько "площадок" надо в голове объединять? Разве это наглядно?
Как-то не очень хорошо выглядит - при одних входах работаем ровно с одной памятью, а при других - со всеми памятями. Да и что называем "входом" - пересечение границы композитного состояния снаружи внутрь, которое заканчивается на "вертолётной площадке" или ещё где-нибудь?
Называем любой вход в состояние и любой вход в предысторию. Если не хочется работать с двумя памятями, можно ввести понятие памяти по умолчанию и метить её спецтегом. Например, правую пометим спецтегом. Далее, если не знаем, куда писать (вошли не в предысторию), то пишем по дефолту вправо.)
У Харела в статьях про Statemate и Rhapsody явно говорится, что "площадка" в состоянии одна, на минуточку. В тех же статьях, кстати, есть двузубцы с choice/junction, растущие из начальных состояний. Привет от Харела составителям стандарта [и мне].))
А как воспринимать звено, которое заканчивается на "вертолётной площадке", но не пересекает границы композитного состояния (Harel "STATECHARTS: A VISUAL FORMALISM FORCOMPLEX SYSTEMS*" Fig.14)?
Как переход в запомненное в истории состояние. Или в дефолтную предысторию, если ничего не запомнено. Или в [дефолтное] начальное состояние, если дефолтной предыстории нет, или не можем понять, какая она.
Попутно вопрос по этой диаграмме: вместо использования конструкции с историческим псевдосостоянием можно завести внутренний переход в состоянии update (хотя бы в UML)?
у него там, как я понял, идея в том, чтобы параметризовать эффект такого перехода (в зависимости от состояния апдейтить разные переменные). Почему там важно оставаться внутри композитного состояния, я не уяснил, но пусть так. В UML придётся завести по локальному переходу со своим эффектом в каждом подсостоянии. Если эффект одинаков, то локальный переход может быть общим и лежать в композитном состоянии.
-
Но в оперение-"площадку" входит переход.
В общем случае - не менее одного перехода. Причём это правило действует на все вершины (состояния и псевдосостояния), кроме начального (у начального своё правило - если оно относится к композитному состоянию, не менее одного перехода к этому композитному состоянию). Смысл - любая вершина должна быть достижимой.
Т. е. она -- вершина. А зачем одну общую предысторию представлять несколькими разными вершинами?
Для того, чтобы показать разные варианты поведения (когда историческая память не содержит никакого значения).
Как глазом увидеть, что она общая? Почему видимые несколько "площадок" надо в голове объединять? Разве это наглядно?
То, что она общая - заложено в семантике (в одной из возможных семантик).
Мне подумалось, что ограничение на единственность исторического псевдосостояния в рамках композитного состояния (в разных источниках) обусловлена тем, что:- прагматичность нескольких исторических псевдосостояний невелика
- определить предпочтительную семантику при нескольких исторических псевдосостояниях нелегко
В тех же статьях, кстати, есть двузубцы с choice/junction, растущие из начальных состояний. Привет от Харела составителям стандарта [и мне].))
Если имеется в виду Fig. 18. из "The Rhapsody Semantics of Statecharts", то всё нормально - из начального псевдосостояния ровно одно звено, без триггера и условия.
у него там, как я понял, идея в том, чтобы параметризовать эффект такого перехода (в зависимости от состояния апдейтить разные переменные). Почему там важно оставаться внутри композитного состояния, я не уяснил, но пусть так. В UML придётся завести по локальному переходу со своим эффектом в каждом подсостоянии. Если эффект одинаков, то локальный переход может быть общим и лежать в композитном состоянии.
Сформулирую вопрос по другому - если композитное состояние имеет внутренний переход, то это:- недопустимо
- означает, что все подчиненные состояния имеют такой внутренний переход
- означает, что все подчиненные состояния имеют внешний переход в себя с указанными свойствами (триггер, условие, действие). Этот вариант мне не нравится, да и Харел моделирует его локальным переходом к историческому псевдосостоянию (Fig. 34. "STATECHARTS: A VISUAL FORMALISM FOR COMPLEX SYSTEMS*")
-
В общем случае - не менее одного перехода. Причём это правило действует на все вершины (состояния и псевдосостояния), кроме начального (у начального своё правило - если оно относится к композитному состоянию, не менее одного перехода к этому композитному состоянию). Смысл - любая вершина должна быть достижимой.
Хорошо бы описать, что такое вершина, что общего между разными типами вершин, и обосновать дискриминацию разных типов вершин.
Для того, чтобы показать разные варианты поведения (когда историческая память не содержит никакого значения).
Может быть, рассмотреть другой способ?
То, что она общая - заложено в семантике (в одной из возможных семантик).
Мне подумалось, что ограничение на единственность исторического псевдосостояния в рамках композитного состояния (в разных источниках) обусловлена тем, что:- прагматичность нескольких исторических псевдосостояний невелика
- определить предпочтительную семантику при нескольких исторических псевдосостояниях нелегко
Мне понравился прагматизм Рамбо, высказавшегося в своём интерью, что стандартизация языку моделирования не обязательна. Для каких-то задач множественные исторические псевдосостояния могут быть полезны. В этих случаях оправдано расширить язык. Сделать свой DSL для моделирования автоматов.
Поиски примеров диаграмм с глубокой и неглубокой предысторией в одном состоянии привели к задаче из студенческого quiz-а, не имеющей никакого смысла, кроме проверки знаний. Интересно найти что-то более жизненное для множественных предысторий.
Если имеется в виду Fig. 18. из "The Rhapsody Semantics of Statecharts", то всё нормально - из начального псевдосостояния ровно одно звено, без триггера и условия.
Как мы обсуждали, в стандарте нет явной градации на звенья и переходы. Диаграмму можно трактовать так, что из начального состояния выходит один составной переход, на котором есть сторожа.
Сформулирую вопрос по другому - если композитное состояние имеет внутренний переход, то это:- недопустимо
- означает, что все подчиненные состояния имеют такой внутренний переход
- означает, что все подчиненные состояния имеют внешний переход в себя с указанными свойствами (триггер, условие, действие). Этот вариант мне не нравится, да и Харел моделирует его локальным переходом к историческому псевдосостоянию (Fig. 34. "STATECHARTS: A VISUAL FORMALISM FOR COMPLEX SYSTEMS*")
Я уверен в ответе 2 (с уточнениями). Обоснование видел в "A Crash Course in UML State Machines" M. Samek. Там есть пример с перекрывающимися разноуровневыми локальными переходами у вложенных состояний.
-
Хорошо бы описать, что такое вершина, что общего между разными типами вершин, и обосновать дискриминацию разных типов вершин.
Вершина (Vertex) = состояние (State) + псевдосостояние (Pseudostate). Потом, при рассмотрении вложенных автоматов (StateMachine), возможно добавятся и ссылки на точки соединения (ConnectionPointReference). А такое дискриминация вершин?
Может быть, рассмотреть другой способ?
Какой (кроме junction/choice после звена из "вертолётной площадки")?
Как мы обсуждали, в стандарте нет явной градации на звенья и переходы. Диаграмму можно трактовать так, что из начального состояния выходит один составной переход, на котором есть сторожа.
В описании (диаграмме) автомата есть только звенья (Transition). У каждого звена ровно 1 вершина-исто(чни)к и ровно 1 вершина-цель.
Я уверен в ответе 2 (с уточнениями). Обоснование видел в "A Crash Course in UML State Machines" M. Samek. Там есть пример с перекрывающимися разноуровневыми локальными переходами у вложенных состояний.
Принято
-
Вершина (Vertex) = состояние (State) + псевдосостояние (Pseudostate). Потом, при рассмотрении вложенных автоматов (StateMachine), возможно добавятся и ссылки на точки соединения (ConnectionPointReference). А такое дискриминация вершин?
Это понятно, но зачем выделяется такая категория? Очевидно же, что автомат лишь визуально состоит из вершин и звеньев, а на самом деле определяет правила переключения между конфигурациями состояний и сопутствующее поведение. У отделённого сиамского близнеца диаграмм состояний -- диаграмм деятельности -- контрольные узлы никто не называет псевдоузлами, например. И не говорит о стабильности.
Дискриминация: кому можно, а кому нельзя entry, exit, do, входящие звенья, исходящие звенья.
Какой (кроме junction/choice после звена из "вертолётной площадки")?
Заручимся тем, что Харел придумал чистить предысторию спец. действием. По его плохому примеру разрешим проверять, пуста ли предыстория в стороже. Тогда, в Вашем примере можно рисовать двузубец с choice, первый зуб которого идёт в "вертолётную площадку" (одну! общую!) и имеет сторожа [not EmptyHistory], второй идёт в предысторию по умолчанию и имеет сторожа [else]. Прелесть в том, что можно рисовать трезубец, n-зубец и описывать условные дефолтные предыстории.
Другой способ менее выразительный -- разрешить переходам в предысторию иметь второе дополнительное (пунктирное:) остриё, указывающее на дефолтную предысторию для этого перехода. Основное (сплошное) остриё идёт только в "площадку" (которая одна, общая).
В описании (диаграмме) автомата есть только звенья (Transition). У каждого звена ровно 1 вершина-исто(чни)к и ровно 1 вершина-цель.
Такое прочтение возможно. С другой стороны можно видеть (в тексте, не в метамодели!) составные переходы (compound transition) и всюду дальше их первого упоминания подозревать, что транзишэнами называют и их и звенья. Довольно бессмысленно, на мой взгляд, запрещать в стандарте проводить из начального псевдосостояния несколько исходящих звеньев, но разрешать(?) рисовать хареловский эквивалентный им N-зубец с choice/junction.
-
Это понятно, но зачем выделяется такая категория? Очевидно же, что автомат лишь визуально состоит из вершин и звеньев, а на самом деле определяет правила переключения между конфигурациями состояний и сопутствующее поведение. У отделённого сиамского близнеца диаграмм состояний -- диаграмм деятельности -- контрольные узлы никто не называет псевдоузлами, например. И не говорит о стабильности.
Зачем вводится понятие "вершина", которое объединяет понятия "состояние" и "псевдосостояние"? У состояний и псевдосостояний много общего (например каждое звено исходит от ровно одного из них и приходит ровно к одному из них).
Заручимся тем, что Харел придумал чистить предысторию спец. действием. По его плохому примеру разрешим проверять, пуста ли предыстория в стороже. Тогда, в Вашем примере можно рисовать двузубец с choice, первый зуб которого идёт в "вертолётную площадку" (одну! общую!) и имеет сторожа [not EmptyHistory], второй идёт в предысторию по умолчанию и имеет сторожа [else]. Прелесть в том, что можно рисовать трезубец, n-зубец и описывать условные дефолтные предыстории.
Другой способ менее выразительный -- разрешить переходам в предысторию иметь второе дополнительное (пунктирное:) остриё, указывающее на дефолтную предысторию для этого перехода. Основное (сплошное) остриё идёт только в "площадку" (которая одна, общая).
Отразил, как понял в 1 и 2 вложении. Вложение 3 - вариант с запоминанием в переменной c откуда пришли, вложение 4 - провокационная версия того же.
Такое прочтение возможно. С другой стороны можно видеть (в тексте, не в метамодели!) составные переходы (compound transition) и всюду дальше их первого упоминания подозревать, что транзишэнами называют и их и звенья.
Беда стандарта, что в текстовой части смешаны и синтаксис, и семантика (это ещё не беда - так многие источники делают: действительно при первоначальном изучении только так и можно что-то понять), и при этом один и тот же термин "переход" используется и при описании синтаксиса, и при описании семантики, а часть, которая должна однозначно определить синтаксис - метамодель, этой цели не достигает.
Довольно бессмысленно, на мой взгляд, запрещать в стандарте проводить из начального псевдосостояния несколько исходящих звеньев, но разрешать(?) рисовать хареловский эквивалентный им N-зубец с choice/junction.
Согласен, всё равно такой N-зубец надо проверять на полноту выходов. Вложения 3 и 4 содержат пример того же для исторического псевдосостояния. Может это всё для того, чтобы только после choice/junction проверять полноту выходов?
-
Зачем вводится понятие "вершина", которое объединяет понятия "состояние" и "псевдосостояние"? У состояний и псевдосостояний много общего (например каждое звено исходит от ровно одного из них и приходит ровно к одному из них).
Это понятно. Но в том же ключе можно назвать элементы диаграмм классов вершинами [графа, которым является ДК].
Отразил, как понял в 1 и 2 вложении. Вложение 3 - вариант с запоминанием в переменной, откуда пришли, вложение 4 - провокационная версия того же.
Благодарю. В 2 провокационно хотелось пунктирную часть видеть исходящей из середины сплошной (на манер пунктира класса ассоциации).
Что касается 3.1 (4?), почему бы нет. Junction -- спец. обозначение, позволяющее нарисовать несколько переходов, сэкономив на стрелках-звеньях, дублирующихся сторожах, эффектах, триггерах. Зачем требовать триггер именно на первые звенья? Может быть, требовать, что бы не было более одного триггера на любом из возможных путей?
Беда стандарта, что в текстовой части смешаны и синтаксис, и семантика (это ещё не беда - так многие источники делают: действительно при первоначальном изучении только так и можно что-то понять), и при этом один и тот же термин "переход" используется и при описании синтаксиса, и при описании семантики, а часть, которая должна однозначно определить синтаксис - метамодель, этой цели не достигает.
+1
Согласен, всё равно такой N-зубец надо проверять на полноту выходов. Вложения 3 и 4 содержат пример того же для исторического псевдосостояния. Может это всё для того, чтобы только после choice/junction проверять полноту выходов?
Мудрёно.
-
Это понятно. Но в том же ключе можно назвать элементы диаграмм классов вершинами [графа, которым является ДК].
В стандарте используется Vertex, которое переводится как "вершина", вот и стал так называть.
В 2 провокационно хотелось пунктирную часть видеть исходящей из середины сплошной (на манер пунктира класса ассоциации).
Не смог (инструмент EA12).
Зачем требовать триггер именно на первые звенья? Может быть, требовать, что бы не было более одного триггера на любом из возможных путей?
Именно такой вывод и хотел получить
Мудрёно.
Переходы из одной Vertex не должны "пересекаться" - сработать может только один переход. Но из некоторых Vertex (например начальное псевдосостояние) обязательно надо выйти. Есть 2 способа это обеспечить:- обязательное единственное transition без триггера и без условия - наглядно на диаграмме видно, если нарушено
- непустой набор transition без триггера и с условиями, дополняющими друг друга - ошибки не очень наглядны
-
Во вложении первый результат "модели (в виде диаграммы классов) абстрактного синтаксиса автомата".
Ограничено только простыми состояниями, поэтому отсутствуют псевдосостояния deepHistory, shallowHistory, join, fork, entryPoint, exitPoint, terminate (пока не нужны) и junction, choice (легко не получается, а диаграмма итак не простая).
Есть и другие недостатки (преодолимые, но за счёт усложнения диаграммы):- нет внутренних переходов (локальных пока и быть не может)
- нет гарантии достижимости состояний - наличие хотя бы одного входящего перехода является необходимым, но недостаточным условием
- одно и тоже событие (trigger) может и запустить переход, и являться буферизируемым
- допустимы явно ненужные ситуации, например: сразу из начального переход в финальное или в состоянии без do-деятельности есть исходящий переход без триггера
- действительно ли из состояния должен исходить хотя бы один переход (действительно ли всегда должна быть возможность покинуть состояние, если оно не финальное)
-
Добавил внутренние переходы, разграничил буферизируемые и запускающие переходы триггеры. Сложность возросла раза в два. Появилась (точнее ещё раз всплыла тема уже по диаграмме классов - дерево? подклассов Transition http://www.uml2.ru/forum/index.php?topic=6583.msg40740#msg40740 (http://www.uml2.ru/forum/index.php?topic=6583.msg40740#msg40740)).
-
Добавил только choice, сложность существенно увеличилась.
-
Лето... отпуска... даже у НЛО. Извините, отсутствовало и не отвечало. Теперь вернулось и буду посмотреть. ;D
-
Лето... отпуска... даже у НЛО. Извините, отсутствовало и не отвечало. Теперь вернулось и буду посмотреть. ;D
На Альдебаран что ли летало, уважаемое НЛО, хотя почему ое - объект вроде :)?
-
На Альдебаран что ли летало, уважаемое НЛО, хотя почему ое - объект вроде :)?
По поясу астероидов моталось. Ое -- это по стандарту по словарю. )
-
Попробую на зуб. Сомнительным кажется соединение класса с перечислимым типом с помощью ассоциации (SimpleState-*--*-TypeStateBehaviour). М. б. соединить SimpleState со StateBehaviour, а TypeStateBehaviour сделать типом квалификатора при этой связи?
Пользуясь случаем врублю офтопик. Стандарт против внутренних переходов по завершению. А, собственно, почему?
-
Сомнительным кажется соединение класса с перечислимым типом с помощью ассоциации (SimpleState-*--*-TypeStateBehaviour).
Что вызывает сомнение - то, что перечислимый тип может участвовать в ассоциации?
М. б. соединить SimpleState со StateBehaviour, а TypeStateBehaviour сделать типом квалификатора при этой связи?
Для меня это эквивалентное преобразование: класс-ассоциацию (многие ко многим) всегда можно заменить на ассоциацию от одного из ассоциируемых с квалификатором по другому из ассоциируемых (картинка во вложении).
Стандарт против внутренних переходов по завершению. А, собственно, почему?
Можно предположить, что дело в "звучании" терминов - "ФИНАЛЬНОЕ состояние", "переход по ЗАВЕРШЕНИЮ". Явно звучит "Конец", "Финиш", "Уже всё". И тут внутренний переход, что явно предполагает продолжение - непорядок!.
-
Что вызывает сомнение - то, что перечислимый тип может участвовать в ассоциации?
Привычнее видеть, что у класса есть атрибут перечислимого типа и проведена зависимость от класса к типу. Привычка идёт от увиденного в книгах и т. п. В стандарт не лазило. Как по мне, data type и enumeration недоклассификаторы, в том смысле, что их "экземпляры" не соединяются с экземплярами классов, а являются значениями их слотов.
Для меня это эквивалентное преобразование: класс-ассоциацию (многие ко многим) всегда можно заменить на ассоциацию от одного из ассоциируемых с квалификатором по другому из ассоциируемых (картинка во вложении).
В верхней части рисунка у класса C починённое положение, а у A и B -- главное. Они полноправные партнёры в связи, C -- их обслуживает, обеспечивая сохранение свойств связи. В нижней части рисунка полноправны A и C, а B уточняет связь. StateBehaviour -- часть состояния. Разумно связать их ассоциацией (композицией). Тот факт, что поведение каждого типа (по входу, по выходу и внутренняя деятельность) у состояния может быть не более чем одно, удобно показать квалификатором.
Можно предположить, что дело в "звучании" терминов - "ФИНАЛЬНОЕ состояние", "переход по ЗАВЕРШЕНИЮ". Явно звучит "Конец", "Финиш", "Уже всё". И тут внутренний переход, что явно предполагает продолжение - непорядок!.
Гипотетически, если понадобилось бы промоделировать поведение, при котором по завершении деятельности проверяется условие, а затем по результатам проверки осуществляется действие, внутренний переход по завершению был бы полезен. Без него решение немного сложнее.
-
Заметил ошибку в диаграмме: квалификатор не с той стороны. Исправление во вложении 1. Там же отображена зависимость (в соответствии с
Привычнее видеть, что у класса есть атрибут перечислимого типа и проведена зависимость от класса к типу.
).
Привычнее видеть, что у класса есть атрибут перечислимого типа и проведена зависимость от класса к типу. Привычка идёт от увиденного в книгах и т. п. В стандарт не лазило. Как по мне, data type и enumeration недоклассификаторы, в том смысле, что их "экземпляры" не соединяются с экземплярами классов, а являются значениями их слотов.
Все три диаграммы во вложении 2 эквивалентны. И неважно, является B классом или enumeration.
-
Вот уж не знаю, откуда рисовать зависимость к B. От ассоциации?)
-
В общем случае может быть использование B в нескольких квалификаторах. Чтобы зависимость была одна, она должна быть от C.
-
Стандарт пишет, что квалификаторы принадлежат memberEnd'ам ассоциации, не оконечным классам. (И даже, что рисовать квалификатор надо не как "бородавку" на классе, а как "присоску" на ассоциации.) Это значит, что от B зависит ассоциация. Описание связанных ей классов A и C может не содержать упоминания B, и классы могут быть независимы от B.
И, конечно, в стандарте (как и в книгах) мне не попался ни один пример с квалификатором-классом.
-
При таком подходе, я полагаю, "площадка" становится чем-то вроде оперения у стрелки псевдозвена.
Дочитало стандарт 2.5 до описания конкретного синтаксиса. Нашло там стрелки, у которых кружки являются частью оперения (или острия), и про которые подчёркнуто, что это не две части диаграммы, а одна. К моему сожалению, это не части диаграмм состояний, а потерянные и найденные сообщения на диаграммах последовательности. Интересно, к какой версии стандарта кружки отделятся и заживут своей жизнью.)
На своей родной планете уже видело "творческое использование" найденных сообщений (безымянных) как своего рода "начальных псевдосостояний" на диаграмме последовательности. Объяснение "творчества":
-- А это у вас что?
-- А это у меня отмечено, откуда всё начинается.