библиотека автоматов состояний Nemerle.Statechart
От: CodingUnit Россия  
Дата: 20.07.11 10:34
Оценка: 98 (7)
Идея написания библиотеки работы с конечными автоматами на Nemerle пришла давно, вот здесь началась развиваться тема на форуме:
http://rsdn.ru/forum/nemerle/3716028.aspx
Автор: CodingUnit
Дата: 24.02.10


Все это время я потихоньку развивал проект, сейчас библиотека вошла в рабочую фазу, реализованы основные функции семантики автоматов UML. С выходом Nemerle.Peg добавились новые возможности создания языка DSL. Подобные библиотеки есть во всех языках, например boost::statechart в C++, Sanford.StateMachineToolkit, SimpleStateMachine — C# State Machine Library — Boo and Rhino DSL, StaMa, Stateless. Хотелось бы иметь и такую же в Nemerle, плюсы от использования Nemerle очевидны, это удобный разбор dsl языка описания автомата (в аналогичных библиотеках как правило неудобно создавать сами диаграммы), анализ на этапе компиляции, генерация высокоэффективного кода, практически полное отсутствие динамических конструкций ускоряющие код. Идея хорошо себя оправдала, я тестировал аналогичные автоматы Sanford.StateMachineToolkit и моей библиотеки, разница в скорости в плюс библиотеки на Nemerle была в десятки раз. Все это говорит о том что аналогов подобной библиотеки в мире нет, остальные библиотеки проигрывают в скорости и удобстве описания автомата, все это дает причину опубликовать библиотеку для широкого использования. Хотел спросить есть ли у сообщества согласие на хостинг библиотеки в snippets, я хотел назвать Nemerle.Statechart.
Текущие возможности библиотеки таковы:
— язык описания диаграммы состояний представляет собой текстовый dsl вида
state Parked
{
  EngineStarted => IdleInNeutral;
}

state IdleInNeutral
{
  EngineKilled => Parked;
  GearEngaged  => IdleInGear;       
}

state IdleInGear
{
  GearDisengaged => IdleInNeutral;
  GasApplied     => RacingAlong;
}

state RacingAlong
{
   BrakeApplied       => IdleInGear;
   CarCrashedIntoTree => CarDestroyed;
}

state CarDestroyed
{
}


Здесь изображен плоский автомат, библиотека включает большинство из возможностей uml автоматов, например такой автомат:


можно дополнить сторожевыми условиями, входными выходными действиями и получить в конечном счете что то типа:
[statechart(<#
  
  flags : auto_initial, transition_completed_events debug;
  
  state A  
  {
      (H) => D;
      
      $>;
      $<;
      
      b => E;
      f => D; // cross
      
      state B
      {
          0 / init_action => C;
          (H*) => E;
          $>;
          $<;

          b => D; // cross
          
          d => D;
          f [test_guard1] / f_action =>@;
          k => A;
          c => E;
          _ => D;
          
          state C
          {
              $>;
              a / A;
              $<;
              
              b [test_guard2] => E; 
              m =>@;
          }
          
          state E
          {
              $>;
              $<;
              i => D;
              j => A;
              o /final_action1 => final;
          }
          
      }
            
      state D
      {
          $>;  
          $<;
          e => B;
          n => B.H;
      }
      
      g => H;
  }
  #>
  )]
  class PathCoverFsm
  {
      
      //[GuardFor(test_guard1)]
    test_guard1() : bool// {get;set;}
    {
      true
    }
      
    test_guard2 : bool// {get;set;}
    {
      get
      {
        true
      }
    }
      
    test_guard3 : bool// {get;set;}
    {
      get
      {
        true
      }
    }      
  }
}


вся эта штука потом парсится, анализируется и в конечном счете получается код класса содержащие определения состояний, события обработчики для действий, входных, выходных и при переходах и это можно использовать в другом коде. Сама обработка событий основывается на виртуальных методах.

весь список возможностей на текущий день:

— парсинг метаттрибута текстового описания автомата
— анализ путей переходов
— генерация представления автомата в класс
— анализ и генерация истории shallow и deep history
— переходы по умолчанию из исторических состояний
— сторожевые условия
— встраиваемые члены сторожевых условий
— конечные состояния (final)
— начальные состояния (initial)
— действия при входе и выходе
— сброс истории при переходе в конечное состояние (check spec)
— приоритет переходов вложенных классов
— внутренние переходы

еще не достает до полноты:
-terminal pseudostate
-do activity
-choice
-junction
-fork and join pseudostates
-orthogonal regions
-local and external transitions
-deffered events

Что скажет сообщество на сей творческий порыв




от макросов до вариантов
и массой всяких преимуществ
благодаря nemerle-братству
программеров жизнь стала лучше
Re[2]: [Nemerle.Statechart] примеры и описания
От: CodingUnit Россия  
Дата: 23.08.11 12:40
Оценка: 95 (5)
Выложил видео с примером работы приложения, автомата описанного в прошлый раз, видео здесь

Продолжаю писать примеры использования и описание библиотеки автоматов. На этот раз добавил функцию работы с параллельными состояниями, и хочу ее описать. Этой функции нет почти не в одной библиотеке, а она очень необходимая. Были реализованы следующие функции:

— работа автомата в параллельных независимых состояниях
— примитивы для разделения потока и слияния fork и join
— разные варианты переходов в/из параллельных состояний
— конечные состояния и переходы по завершению в параллельных состояниях

Что же дают параллельные состояния? В отличие от обычных состояниях, в одном из которых может пребывать автомат, при входе в параллельное композитное состояние автомат входит сразу в несколько его подсостояний и пребывает в них одновременно. При этом он может выполнять некую параллельную активность в каждом из состояний и независимо реагировать на события и осуществлять переходы независимые от других параллельных регионов. На диаграмме параллельные области в состоянии показываются пунктирной линией:



Здесь показан процесс обучения студентов, не важно в каком порядке выполняются задания, главное они должны быть все пройдены. Здесь при входе в состояние Taking Class он заходит в его начальное состояние Incomplete, оно является композитным то есть содержит другие состояния и параллельным, имеет 3 независимые области, при входе в это состояние автомат входит сразу во все его подрегионы, и будет пребывать в 3х состояниях Lab1, Term Project, Final Test, после появления событий lab done, он переходит из Lab1 В Lab2 также и в других регионах когда появится событие project done, pass (завершен проект, сдал тест) каждое состояние в подрегионе перейдет в конечное состояние, которое обозначается как черный кружок в белом (бычий глаз). Когда все три региона окажутся в конечном состоянии сработает переход по умолчанию (стрелка из состояния Incomplete без события) в состояние Passed, то есть студент сдал тест.
Если автомат будет находится в состоянии Final Test и появится событие fail, то есть не сдал тест, то автомат выходит из состояния Final Test и из всех состояний в других регионах принудительно и переходит в состояние Failed.

всегда при переходе на границу композитного состояния осуществляется переход в начальные состояние его областей. Возможен переход в одно вложенное
параллельное состояние, при этом будет неявный вход во все остальные параллельные состояния через начальные переходы.

Конечное состояние (final state), означает что композитное состояние завершило свою деятельность и может осуществлять переход по завершении, в параллельном состоянии имеет иную семантику чем в последовательном. В последовательных состояниях переход в final означает что состояние завершилось и если есть переход по умолчанию из верхнего состояния (completion transition), то он срабатывает. В параллельных этот переход сработает если все параллельные регионы находились в конечном состоянии, иначе регион будет ожидать завершения других регионов находясь в конечном состоянии.




В этом примере показана работа электронного терминала. В состоянии selectAmount при возникновении события amount автомат осуществляет переход в конечное состояние и сразу переходит через переход по завершению в состояние VerifyTransaction.

Ниже представлен расширенный пример еще одного автомата, настоящих электронных часов:



Часы могут одновременно пребывать в нескольких режимах параллельно, здесь имеются разные состояния отображения Display, подсветка Light вкл или выключена L-On, L-Off, Chime выбор звонка, при этом могут быть как подсветка, так и разные режимы отображения, установки будильника Alarm-set, то есть любые независимые комбинации режимов. Это невозможно реализовать на последовательных состояниях, поскольку здесь требуются именно несколько состояний одновременно. Я не буду вдаваться в подробности автомата, скажу только что при запуске становятся активными все состояния в параллельных областях и они могут менятся в каждой из областей как реакция на события. Когда часы ломаются, он выходит из всех состояний в состояние Dead. Остальные аспекты я думаю будут понятны, если что то неясно читайте предыдущие сообщения или задавайте вопросы.

Синтаксис:




state TakingClass
{
  flags : auto_initial; // показывает что первое подсостояние есть начальное
  
  Extern => Lab2 TermProject FinalTest; // разделение fork переход сразу в три состояния

  state Incomplete
  {
    _ => Passed; // переход по завершении (нет триггера)

    state Lab1
    {
      lab_done => Lab2;
    }
    
    state Lab2
    {
      lab_done => $0;
    }

    [----------] // определение границы параллельной области
    
    state TermProject
    {
      project_done => $0; // переход в конечное состояние
    }

    [----------] // определение границы параллельной области
    
    initial => FinalTest;

    state FinalTest
    {
      pass => final; // переход в конечное состояние
      fail => Failed; // переход во вне
    }
  }

  state Passed
  {
  }
  
  state Failed
  {
  }
}


[img]Продолжаю писать примеры использования и описание библиотеки автоматов. На этот раз добавил функцию работы с параллельными состояниями, и хочу ее описать. Этой функции нет почти не в одной библиотеке, а она очень необходимая. Были реализованы следующие функции:

— работа автомата в параллельных независимых состояниях
— примитивы для разделения потока и слияния fork и join
— разные варианты переходов в/из параллельных состояний
— конечные состояния и переходы по завершению в параллельных состояниях

Что же дают параллельные состояния? В отличие от обычных состояниях, в одном из которых может пребывать автомат, при входе в параллельное композитное состояние автомат входит сразу в несколько его подсостояний и пребывает в них одновременно. При этом он может выполнять некую параллельную активность в каждом из состояний и независимо реагировать на события и осуществлять переходы независимые от других параллельных регионов. На диаграмме параллельные области в состоянии показываются пунктирной линией:



Здесь показан процесс обучения студентов, не важно в каком порядке выполняются задания, главное они должны быть все пройдены. Здесь при входе в состояние Taking Class он заходит в его начальное состояние Incomplete, оно является композитным то есть содержит другие состояния и параллельным, имеет 3 независимые области, при входе в это состояние автомат входит сразу во все его подрегионы, и будет пребывать в 3х состояниях Lab1, Term Project, Final Test, после появления событий lab done, он переходит из Lab1 В Lab2 также и в других регионах когда появится событие project done, pass (завершен проект, сдал тест) каждое состояние в подрегионе перейдет в конечное состояние, которое обозначается как черный кружок в белом (бычий глаз). Когда все три региона окажутся в конечном состоянии сработает переход по умолчанию (стрелка из состояния Incomplete без события) в состояние Passed, то есть студент сдал тест.
Если автомат будет находится в состоянии Final Test и появится событие fail, то есть не сдал тест, то автомат выходит из состояния Final Test и из всех состояний в других регионах принудительно и переходит в состояние Failed.

всегда при переходе на границу композитного состояния осуществляется переход в начальные состояние его областей. Возможен переход в одно вложенное параллельное состояние, при этом будет неявный вход во все остальные параллельные состояния через начальные переходы.

Конечное состояние (final state), означает что композитное состояние завершило свою деятельность и может осуществлять переход по завершении, в параллельном состоянии имеет иную семантику чем в последовательном. В последовательных состояниях переход в final означает что состояние завершилось и если есть переход по умолчанию из верхнего состояния (completion transition), то он срабатывает. В параллельных этот переход сработает если все параллельные регионы находились в конечном состоянии, иначе регион будет ожидать завершения других регионов находясь в конечном состоянии.
Внутри одного региона параллельного состояния автомат живет в последовательных состояниях.




В этом примере показана работа электронного терминала. В состоянии selectAmount при возникновении события amount автомат осуществляет переход в конечное состояние и сразу переходит через переход по завершению в состояние VerifyTransaction.

Ниже представлен расширенный пример еще одного автомата, настоящих электронных часов:



Часы могут одновременно пребывать в нескольких режимах параллельно, здесь имеются разные состояния отображения Display, подсветка Light вкл или выключена L-On, L-Off, Chime выбор звонка, при этом могут быть как подсветка, так и разные режимы отображения, установки будильника Alarm-set, то есть любые независимые комбинации режимов. Это невозможно реализовать на последовательных состояниях, поскольку здесь требуются именно несколько состояний одновременно. Я не буду вдаваться в подробности автомата, скажу только что при запуске становятся активными все состояния в параллельных областях и они могут менятся в каждой из областей как реакция на события. Когда часы ломаются, он выходит из всех состояний в состояние Dead. Остальные аспекты я думаю будут понятны, если что то неясно читайте предыдущие сообщения или задавайте вопросы.

Также существуют псевдосостояния помогающие при работе с параллельными областями, поток перехода может разделится с помощью fork (разделение, слева от состояния Process) и объединятся при выходе из параллельных областей с помощью Join (два перехода объединяющиеся перед Cleanup) как показано на рисунке:



При этом он может входить в любые подсостояния композитного параллельного состояния, переход запускающий переход в fork имеет одно событие запускающее переход, может иметь сторожевое условие и действие и идет стрелкой напрямую в псевдосостояние fork, (которое показывает жирной чертой,) из которого разветвляется на два и более перехода, отрезки не могут иметь сторожевых условий и идут напрямую в конечные состояния или псевдосостояния. Join антоним для fork, в него идут несколько стрелок переходов, которые срабатывают по одному событию, могут иметь сторожевые условия и действия, если оба перехода запущены, то есть появилось событие, и сторожевые условия истинны, то осуществляется переход в псевдосостояние join и далее через выходной переход в конечное состояние. При этом параллельное состояние завершается свою деятельность и становится неактивным.

Я тут довавил fork переход в диаграмме обучения сразу в три состояния ко 2й лабораторке для определенного студента и выход из первый лабороторок, если студент выбыл.

Синтаксис:

state TakingClass
{
  flags : auto_initial; // показывает что первое подсостояние есть начальное
  
  Extern => Lab2 TermProject FinalTest; // разделение fork переход сразу в три состояния
  join j1 => Failed;  // создаем псевдосостояние join

  state Incomplete
  {
    _ => Passed; // переход по завершении (нет триггера)
    
    state Lab1
    {
      lab_done => Lab2;
      leaved => (j1); // переход в псевдосостояние join j1 1 й отрезок
    }
    
    state Lab2
    {
      lab_done => $0;
    }

    [----------] // определение границы параллельной области
    
    state TermProject
    {
      project_done => $0; // переход в конечное состояние
      leaved => (j1); // переход в псевдосостояние join j1 2 й отрезок
    }

    [----------] // определение границы параллельной области
    
    initial => FinalTest;

    state FinalTest
    {
      pass => final; // переход в конечное состояние
      fail => Failed; // переход во вне
      leaved => (j1); // переход в псевдосостояние join j1 3 й отрезок
    }
  }

  state Passed
  {
  }
  
  state Failed
  {
  }
}


Сами же параллельные состояния реализованы в виде специальных классов, в иерархии дерева состояний, которые внутри себя содержат ссылки на несколько независимых переменных состояний:



реакции выглядат так:


состояния которые содержатся в параллельных ведут себя также как обычные

Переходы выглядят несколько иначе чем для обычных состояний, входы и выходы из параллельных состояний задействуют другие состояния поэтому работают по другому:

Переход в Fork:


Переход сразу во внутреннее состояние:


Но по сути и производительности они мало отличаются от обычных переходов.

Осталось совсем немного доделать остальных возможностей, из них:

— synch псевдосостояние (примитив синхронизации)
— junction псевдосостояние, переход с ветвлением
— choice/branch/merge узлы выбора
— импорт и экспорт в диаграммы редактора
— остальные доделки

Ждите статью и новых примеров.


от макросов до вариантов
и массой всяких преимуществ
благодаря nemerle-братству
программеров жизнь стала лучше

nemerle.statechart uml statechart nemerle
Re[2]: библиотека автоматов состояний Nemerle.Statechart
От: CodingUnit Россия  
Дата: 27.07.11 16:27
Оценка: 29 (3)
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, CodingUnit, Вы писали:


CU>>Хотел спросить есть ли у сообщества согласие на хостинг библиотеки в snippets, я хотел назвать Nemerle.Statechart.


VD>Все будут только "за".


VD>Только делать теперь это нужно через создание fork-а и размещения пул-реквеста на github. Тут рядом это все описано. Почитай, плиз.

VD>http://www.rsdn.ru/forum/nemerle/4336310.1.aspx
Автор: Ziaw
Дата: 09.07.11


CU>>еще не достает до полноты:

CU>> -terminal pseudostate
CU>> -do activity
CU>> -choice
CU>> -junction
CU>> -fork and join pseudostates
CU>> -orthogonal regions
CU>> -local and external transitions
CU>> -deffered events

VD>Еще бы понимать что все это значит .


Это элементы семантики UML автомата, все это я разъясню в процессе описания библиотеки, скажу вкратце,
что будет в библиотеке:
текущие возможности:
— создание иерархических автоматов UML, с поддержкой входных, выходных действий, начальные, конечные, исторические состояния

будущие возможности из описанных выше:
— terminal pseudo state — терминальное состояние при котором автомат должен завершатся
— do activity это деятельность которую автомат должен осуществлять в состоянии, то есть некоторый поток который должен работать
— orthogonal regions — ортогональные области, это области в которых автомат пребывает одновременно, то есть параллельно в двух и более состояниях, ака параллелизм, моделируется с помощью многопоточности
— junction — сложный переход, в котором может быть одно событие но на пути много разных разветвлений в разные состояния по разным сторожевыми условиям
— fork and join это псевдосостояния помогающие разделить поток на несколько параллельных, join синхронизирует потоки
— local and external это разные виды переходов, local не вызывает выход из состояния при переходе, подразумевается переход в подсостояние
— deffered events — отложенные события, события которые должны откладываться до лучших времен

VD>Скажет — давай! Только к этому делу еще нужно качественное описание и побольше примеров.


Описание постараюсь набросать, начну с некоторого начального описания библиотеки на примерах, которое потом внесу в документацию библиотеки.

Библиотека Nemerle.Statechart это ответ сообщества Nemerle на запрос автоматного, реактивного и событийного программирования, в ней предполагается внести перспективные функции, возможные с помощью системы метапрограммирования Nemerle. Сама библиотека представлена в виде макроса, который делится на три части:
— парсер (основанный на Nemerle.Peg) который обеспечивает преобразование текстового описания автомата в дерево
— анализ дерева автомата, это статический анализ, переходов, действий, проверка на правильность описания, обработка и создания структур для генерации
— генерация автомата в запускаемый код, в виде класса, в котором представлены подклассы состояний, переменные текущего состояния, историй, событий действий которые срабатывают при входах, выходах из состояний и переходах

Для чего все это нужно?

Автоматы состояний — это поведенческая абстракция, которая помогает разделить общее поведение системы или класса на некоторое множество разных состояний, соединенных переходами и реагирующими на события. Как известно новейшие языки и платформы делают шаги в сторону реактивности и событийности, введение в язык конструкции делегатов, событий, помогает строить поведение классов с помощью концепции событийного программирования.

Цитата из википедии:

Событи́йно-ориенти́рованное программи́рование (англ. event-driven programming; в дальнейшем СОП) — парадигма программирования, в которой выполнение программы определяется событиями — действиями пользователя (клавиатура, мышь), сообщениями других программ и потоков, событиями операционной системы (например, поступлением сетевого пакета).

Как правило, в реальных задачах оказывается недопустимым длительное выполнение обработчика события, поскольку при этом программа не может реагировать на другие события. В связи с этим при написании событийно-ориентированных программ часто применяют автоматное программирование.

Событийно-ориентированное программирование, как правило, применяется в трех случаях:

при построении пользовательских интерфейсов (в том числе графических);
при создании серверных приложений в случае, если по тем или иным причинам нежелательно порождение обслуживающих процессов;
при программировании игр, в которых осуществляется управление множеством объектов.


Применение и плюсы автоматов состояний широко известны, такой подход позволяет строить поведение системы визуально, на практике я столкнулся с тем что гору if else конструкций можно преобразовать в несколько легко представляемых состояний, разделенных переходами, которые визуально легко представляются и переносятся в код, при этом код понятен, и чист, легко расширяется, обдумывается и отлаживается из за того что описание автомата легко представляется в виде диаграммы.
В автоматном программировании, поведение системы или класса может легко расширяться, за счет добавления состояний или переходов, а не модификации логики, в какой то мере это часто лучше рекурсии и даже удобных match конструкций.
Вот здесь интересные статьи по системам работающим по событиям:
http://www.excode.ru/art6033p2.html
http://www.ict.edu.ru/vconf/files/3195.rtf
здесь

В процессе жизненного цикла система или класс системы, может менять свое состояние, как реакция на внешние события, в каждом состоянии объект себя ведет по разному. Автоматы состояний можно использовать при моделировании поведения графического интерфейса, как реакции на действия пользователя, различные приложения с множеством разных режимов работы в которых система ведет себя по разному, моделирование объектов реального мира, например в играх солдат может быть в нескольких состояниях: стоит, бежит, лежит, стреляет, оружие достано, говорит, спит, целится в каждом из этих состояний он меняет свой внешний вид (что может осуществлятся при входе в это состояние), и по другому реагирует на внешние события, например может споткнутся если бежит, на какие то события он может не реагировать в определенных состояниях, а в каких то наоборот может, например стреляет в ответ на выстрел, что не может делать если оружие не достано или если он спит.
Разные потоки workflow, цикл жизни объекта, разные протоколы легко реализуются на автоматах, причем эта библиотека с легкостью даст возможность автоматизировать классы, и использовать в системах реального времени, где требуется высокая вычислительная скорость, поскольку за счет статического анализа, изменения состояний и переходы осуществляются очень быстро, как правило это сводится к присваиванию полю класса, нескольких вызовов и запуска событий.
Практически любая сложная логика может быть описана автоматами, автоматы начали применятся и исследоваться с середины прошлого века, в разных научных кругах, отечественных и зарубежныхх разработках.
Сначала применялись различные подходы такие как детерменированные и недетерменированные автоматы, автоматы Мили и Мура, затем Д.Харел разработал более сложную и полную семантику автоматов, иерархических автоматов, в которых состояния группировались на основе принципа Или и И, Или когда автомат находится в одном из состояний, И когда в нескольких (параллельных). Введены разные теории семантики автоматов, которые были объеденены в стандарте UML.
Я вкратце опишу диаграммы и их составляющие, для тех кто не знаком с диаграммами состояний UML, а рассмотрю их интерпретацию в языке описания автоматов в библиотеке и представлю несколько примеров.

Вот статьи по теории диаграмм состояний:
http://www.business-process.ru/designing/methodology/uml/theory/statechat_diagram_theory.html
http://khpi-iip.mipk.kharkiv.edu/library/case/leon/gl6/gl6.html
http://ertostik.net/uml/diagramma-sostoyaniy-state-diagram.html

вся диаграмма представляет собой ориентированный граф, вершинами которого являются состояния, а переходы дугами.
Диаграмма состоит из композитных состояний, которые включают другие подсостояния, с одним возможно неявным верхним состоянием.
Когда состояние находится во внутреннем состоянии, то активны и все его родительские состояния.

— черный кружок со стрелкой есть начальное состояние, когда автомат начинает работу он входит в верхнее начальное состояние, переход из которого осуществляется в одно из подсостояний, когда автомат входит в композитное состояние через переход, то он входит в его начальное состояние, в которое осуществляется переход из начального состояния

Вот диаграмма состояний телефона:

Система телефона находится в одном из следующих состояний:
1) Сначала система входит в состояние Idle, то есть телефон ожидает и пребывает в нем
2) Когда наступает событие lift receiver то есть поднята трубка, осуществляется переход из состояния Idle в состояние Active при этом сначала вызывается действие get dial tone — получить сигнал выдачи гудка (?),
3) При входе в состояние Active, переход осуществлятся сразу в его начальное псевдосостояние, из которого сразу же система переходит в состояние Dial Tone то есть проигрывание гудка
4) do / play dial tone — обозначает деятельность внутри состояния, то есть состояние осуществляет активность проигрывает гудок
5) при наступлении события after 15 sec, то есть после 15 секунд, телефон переходит в состояние Time-out в котором постоянно проигрывает сообщение, из этого состояния он может выйти только если положена трубка caller hangs up переход из родительского состояния Active, то есть принадлежащий ко всем внутренним состояниям, если автомат находится в любом из подсостояний Active то событие caller hangs up выводит из него автомат и переводит в состояние Idle то есть если кладем трубку то телефон ожидает
6) Далее последовательно автомат переходит по соотв. событиям состояния Connecting (соединения), Ringing (звонит), Busy, Talking
Дальнейшее обсуждение диаграммы состояний я думаю лишне, должна быть уже понятна концепция, весь этот автомат текстово можно представить в следующем виде (в будущем надеюсь сделать перевод графического представления из редактора автоматически в автомат):


// макроаттрибут statechart
[statechart(<#

 flags : auto_initial; // начальные флаги автомата

 // определяем состояние Idle
 state Idle
 {
  lift_receiver / get_dial_tone => Active; // переход: событие / действие => конечное состояние
 }

 // определяем состояние Active
 state Active
 {
   
   caller_hangs_up / disconnect => Idle; // 
   terminate => $0; // переход в конечное состояние

   state DialTone
   {
     do / play_dial_tone; // внутренняя активность (пока не поддерживается)
     after15_sec => TimeOut;
     dial_digit => Dialing;
   }
   
   state TimeOut
   {
   }
   
   state Dialing
   {
     dial_digit [incomplete] => @; // переход со сторожевым условием в себя
     after15_sec => TimeOut;
     dial_digit [invalid] => Invalid;
     dial_digit [valid] / connect => Connecting; 
   }
   
   state Invalid
   {
     do / playMessage;
   }

   state Connecting
   {
     connected => Ringing;
     busy => Busy;
   }

   state Busy
   {
     do / play_busy_tone;
   }

   state Ringing
   {
    do / play_ringing_tone;
    callee_answers / enable_speech => Talking;   
   }
   
   state Talking
   {
     callee_hangs_up => Pinned;
   }
   
   state Pinned
   {
     callee_answers => Talking;
   } 
 }
#>)
class PhoneFsm
{
}


Далее после компиляции макрос должен проанализировать автомат и создать методы, он создаст действия при переходах, do хотя пока и не поддерживается, его можно заменить входными действиям, можно описать ключевые слова используемые в языке:


state Имя // состояние
{
 entry / action; // действие при входе
 exit / action2; // действие при выходе
 
 _ =>
 (H*) => Имя2;// историческое состояние, автомат запоминает последнее состояние при выходе, переход в это состояние возвращает запомненное состояние 
      // *  означает Deep History - глубокая история которая запоминает подсостояние на любой глубине вложенности
      // стрелочка означает переход по умолчанию из исторического состояния, если нет истории осуществляется он
 state Имя2
 {
  $>; // входное действие (альтернативный синтаксис) для него создается событие внутри класса, 
      // к которому можно присоединить обработчик запускающийся при входе в состояние
  $<; // выходное действие 
   
  trigger [guard] / action => State3; // событие [сторожевое условия] / действие при переходе => Состояние
                                      // сторожевые условия вычисляются при наступлении события, если оно истинно значит переход сработает
  (H) // историческое состояние Shallow - запоминает верхнее подсостояние этого состояния
  evt => final; // переход в конечное состояние, при этом композитное состояние завершается
 }
} 
 
state State3
{
  exit
     {
     Something2 // действие при входе 1
     Something3 // действие при входе 2
     } // другой синтаксис для входного действия
  A => Имя.H; // переход в историческое состояние
}


Тут я описал основной синтаксис, оставшуюся семантику UML думаю со временем включу, парсер пока не распознает сложные и ошибки и выдает обычные сообщения которые в него заложены, синтаксис расширяем если у кого есть мысли как его улучшить, анализатор и генератор тоже если будут найдены баги или если будут советы по улучшению архитектуры можно поправить. На этом сообщение завершаю, после рассмотрю остальные аспект и дам больше примеров. Я сделал пулл реквест библиотеки, когда она будет добавлена в git ее можно скачать и попробовать. Буду рад любым комментариям и вопросам.





от макросов до вариантов
и массой всяких преимуществ
благодаря nemerle-братству
программеров жизнь стала лучше
nemerle.statechart
Re[9]: библиотека автоматов состояний Nemerle.Statechart
От: CodingUnit Россия  
Дата: 10.08.11 17:47
Оценка: 48 (1)
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, CodingUnit, Вы писали:


CU>>Хочу задать вопрос по архитектуре автомата, встала задача сделать внутреннюю активность то есть параллельную деятельность осуществляемую в автомате, специфика в том что асинхронное действие надо прерывать когда автомат захочет.

CU>>Я начал реализовывать через поток Thread, но код тяжеловат каждый раз приходится запускать создавая новый объект Thread и останавливать через Abort Join, есть возможности в библиотеке Rx Extensions, но не очень хорошо ссылаться на внешнюю библиотеку, может известны другие более экономичные подходы для реализации отменяемых асинхронных действий?

VD>Такие вещи нужно реализовывать на базе пула потоков. В .net 4 есть библиотека упрощающая подобные задачи (см. класс Task). Пул потоков позволяет не тратить время на создание потоков и распределяет работу между имеющимися процессорами, так как старается выделять столько процессоров сколько нужно для их загрузки (ни больше, и не меньше).


VD>Поток лучше не прерывать исключением, а использовать идеологию токенов отмены (cancellation token). По сути это навортоты над простым приемом — предаем в функцию ссылку на некий флаг и проверяем его все время. Если он поднят, то завершаем выполнение.


Создал пул реквест с новыми фичами, реализовал:

— поддержку do активности в состоянии на базе Task из .net 4
— разные флаги к этой фиче чтобы можно было настраивать
— terminate узел (см. описание Terminate)
— провел некоторые оптимизации в анализаторе и генераторе, убрал обработчики действий в соотв. им вх/вых действия
— сделал пример с gui для работы с файлами

Do активность позволяет состоянию внутри себя производить некоторую деятельность, когда состояние активируется оно запускает свою деятельность помеченную как: do / имя
внутри описания состояния и эта активность работает в параллельном процессе независимо от поступающих событий. Если состояние изменяется на другое или автомат останавливается то активность завершается принудительно. Это сделано на базе Task и токенов отмены как посоветовал Влад. Теперь эту возможность можно использовать, я пока еще не встречал библиотек которые бы включали эту возможность языка UML. Ниже я опишу как эту возможность можно использовать и ее нотацию.
Еще одна из задач библиотеки наиболее более полно приблизиться к стандарту UML, и передать его семантику диаграмм состояний, что реализовано не во всех библиотеках. Для этого я перелопачиваю сейчас стандарт, и справочник по UML, и разные описания семантики диаграмм состояний, беседую с западными авторами статей по поводу тонких моментов семантики.
Надеюсь эта цель будет достигнута, от сообщества же требуется хорошенько оттестить библиотеку и выловить баги, разные случаи и запрещенные комбинации, я выловил уже большую часть, но могут быть разные тонкие моменты, ведь язык это вещь сложная, библиотека по сути включает в себя маленький компилятор (парсер, анализатор, генерация).

Terminate узел это псевдосостояние (псевдосостояние означает что это не настоящее состояние, в нем автомат не может пребывать, я постепенно опишу все псевдосостояния, они дают разные управляющие конструкции для работы с автоматом) при входе в которое автомат завершается, то есть уничтожается. Я реализовал этот узел в виде вызова метода Terminate в определенной точке истории автомата, то есть при переходе по определенному событию в узел Terminate. Прошлый пример с системой сохранения файлов, я дополнил узлом terminate, логика дополнена так что если пользователь запускает выход, то запрашивается вопрос о сохранении если файл не был сохранен.

Диаграмма дополняется узлом terminate, нотация которого может быть:
state A
{
terminate;
x;
X;
}


Он отображается как большой крестик поэтому и выбран синтаксис Х,
в ниже описанном автомате взятом из предыдущего примера узел объявлен как X; в верхнем состоянии. Код дополняется следующим:


  [statechart(<#

  flags : auto_initial transition_completed_events;

  0 => Ожидание;

  state НенужноСохранение
  {

      $> / СохранениеВыкл;
            
      НовыйФайл => НужноСохранение;
      ОткрытФайл =>@;
      Выход => X;
      
      state Сохранен
      {
          $> / НадписьИмяФайла ПоследнийФайлТек;
          Сохранение =>@;
          Изменение => Измененный;
      }

      state Ожидание
      {
          $> / СохранениеВсеВыкл НадписьНазваниеПрограммы;
          $< / СохранениеКакВкл;
      }

  }

  state НужноСохранение
  {
      $> / СохранениеВкл;
      ОткрытФайл, Сохранение => НенужноСохранение;
      НовыйФайл =>@;
      Выход => X;
      
      state Новый
      {
          $> / НадписьФайл ПоследнийФайлПустой;
      }

      state Измененный
      {
          $> / НадписьИзменен;
      }

  }

  X;
  #>


В тело класса можно встраивать методы для работы, в примере работы с файлами я встраивал методы запуска событий, которые дают сообщение о сохранении перед запуском события, на этапе теста я не переопределял методы уже существующих событий (хотя надо бы сделать именно так, чтобы нельзя было вызвать события без проверок), но для теста оставил чтобы тестировать автомат без проверок и диалогов. Простое определение метода дает встроить логику в автомат состояний, можно делать переопределение, это можно сделать двумя путями, назначив члену тоже имя что и в определении автомата, например:

если в классе объявить метод НовыйФайл то он переопределит запуск события Новый Файл которые срабатывают также через методы:

[statechart()]
class FileFsm
{
    public НовыйФайл() : void
    {
        when (НовыйДиалог()) НовыйФайл();
    }
    
    [EventFor(Сохранение)] // переопределяет событие Сохранение 
    public Сохранить() : void
    { 
    }
}


Чтобы задать явно что метод переопределяет какое то событие это можно сделать через аттрибут EventFor(имясобытия), тогда он переопределит его и будет везде использоваться этот метод. Помимо запуска событий через вызовы методов, которые генерируются, есть еще метод RunEvent который генерируется автоматически и делает тоже самое но принимает перечисление в качестве параметра и запускает обработчики внутри себя на основе перечисления.
Переопределять можно не только события, но также действия и сторожевые условия. Семантика при этом подобна описанной выше для событий за исключением того, что
аттрибуты называются ActionFor и GuardFor соответственно. Сторожевые условия несколько отличаются от действий тем что они представляются не событиями а свойством,
с выходным типом void -> bool то есть функцией которая должна возвратить true или false для соответствующего сторожевого условия.

Сегодня опишу еще один вариант автомата, с новыми возможностями историей и внутренней активностью, это реальный случай из моей практики. Мне пришлось писать приложение для взаимодействия с прибором, который присоединялся к компьютеру через COM или USB порт. Прибор надо было калибровать, считывать, записывать данные, измерять с помощью него. Логику приложения и gui я вынес полностью в автомат, который я и представлю, без него я бы долго и муторно выслеживал ошибки и пытался бы наладить правильную логику, что я уже перенес в своей практике, с помощью автоматов этого можно легко избежать.

На диаграмме представлен автомат работы программы, программа связывается с прибором и имеет в своем интерфейсе кнопку соединения, которая запоминает свое состояние (залипает), выбор COM порта, сообщения о состоянии программы и прибора.



Вот так выглядит диаграмма состояний.


Программа в процессе своей жизненной истории переживает несколько состояний или режимов, основными двумя ее состояниями являются NotConnected и Working.
В первом оно пребывает по умолчанию при входе, во второе переходит когда пользователь нажимает связь с прибором. Все состояния обрамляются одним большим композитным
состоянием, которое просто обобщает весь автомат.

1) При входе в состояние NotConnected запускаются действия при входе в это состояние, отключаются элементы работы с прибором, которые должны быть активны только если
он подсоединен, статус сбрасывается на обычный, контролы для запуска соединения включены

2) При нажатии на кнопку соединения в правом верхнем углу, запускается событие Нажато Соединение, при этом программа пытается открыть выбранный порт и проверяет открывается ли он.
Сторожевое условие проверяется однократно при наступлении события, если оно истинно то переход запускается если ложно то событие игнорируется и переход не запускается.
Здесь это помогает тем что кнопка не залипает лишний раз если порт не открылся

3) Если порт открылся и запускается переход, автомат начинает вход в состояние Working, оно композитное то есть содержит вложенные подсостояния, одно из них может быть активно,
но если активно вложенное то и все его родители. Это дает например если в композитном состоянии Working запускается событие Отжато соединение то автомат выходит из
всех (любого) активных состояний внутри него и входит в состояние NotConnected, то есть все вложенные состояния реагируют на событие в родительском состоянии.

4) Итак автомат начинает вход в состояние Working, сначала он запускает действие при входе залипает кнопка и выключаются кнопки работы с портом, чтобы нельзя было
выбрать порт, поскольку программа работает только с одним портом. Переход внутри композитного состояния начинается с начального псевдосостояния (initial transition).
В нашем случае из начального псевдосостояния идет переход в состояние Connecting.

5) Сначала необходимо подать тестовый запрос в порт и определить есть ли прибор на линии, прибор при этом должен ответить. Здесь показан пример использования внутренней
активности в состоянии Connecting при этом программа последовательно начинает подавать запросы в линию, прибора может и не быть подключено тогда программа
будет просто висет и пытаться снова.

6) Если произошло соединение и прибор ответил срабатывает переход в состояние Scanning, в этом состоянии надо опросить состояние прибора снять с него его имена,
идентификатор и опросить остальные параметры. При входе в это состояние Начинается подаваться очередь запросов, на каждый из которых должен быть получен ответ,
если ответ не был получен или получен некорректно то запускается событие Соединение разорвано и автомат переходит в состояние Соединения снова, и пытается подать
последовательно тестовый запрос и все остальные чтобы получены были адекватные ответы

7) Если очередь запросов была пройдена и получены ответы (не случилось сбоя), то прибор входит в состояние Connected, из его начального состояния переход идет
прямо в историческое состояние. Что это такое? Историческое состояние запоминает "историю", то есть последнее состояние в котором находилось это родительское состояние.
Существует два типа исторического псевдосостояния, shallow history (обозначается H в кружке) и deep history (H* в кружке), первая запоминает состояние на первом уровне вложенности, то есть последнее верхнее подсостояние,
в состоянии Connected ими являются Interaction, Flash Working, Loading и Mode Change. Второй тип истории запоминает любое подсостояние на любом уровне вложенности,
им могут быть все вышеописанные включая их подсостояния как Stop, Measures в Interaction.

8) Переход в историческое состояние активирует его историю, то есть автомат сразу входит в то состояние в котором находился (по правилам истории), в нашем случае
deep history (со звездочкой), но какое состояние будет если он еще не был в этом состоянии? Ответ прост, он переходит в состояние по умолчанию, для этого существует
такое понятие как default transition, или переход по умолчанию из исторического состояния, он показывает состояние которое должно активироваться если истории
еще нет. У нас он начинает свой путь с Interaction. Сохранение же состояния всегда осуществляется при выходе из того состояния в котором объявлено историческое
псевдосостояние.

9) Итак начинает осществляться вход в состояние Interaction, в этом состоянии пользователь должен общаться с прибором, автомат входит в Idle Scanning, сканирование
прибора и Stop. При этом включатся кнопки управления режимами прибора, можно запустить его на измерение и остановить.

10) При этом в состоянии Stop программа просто постоянно опрашивает данные с прибора, его калибровочные данные в нижнем правом углу бегает индикатор связи с прибором

11) Если в этом состоянии нажать кнопку разъединения, то осуществляется выход из всех состояний в Working, в обратном порядке и осуществляется переход в NotConnected,
при этом порядок таков: выход Stop, выход IdleScanning, NoCalibration, Interaction (сохраняется его история), Connected (сохраняется его история), Working. При этом запускаются
все действия при выходе каждого из состояний из которых выходим и действия при входе в те состояние в которые входим. Входим в NotConnected.

12) Далее если мы нажимаем кнопку соединения вновь, то программа уже знает что мы работали в том то режиме и восстанавливает с помощью истории предыдущий
режим, визуально это выглядит интеллектуально, программа продумывает эти ходы (с помощью автомата), последовательно переходя через Connecting, Scanning поскольку
обязательно надо соединиться и просканировать данные (может быть подключен другой прибор или отключен вообше), далее в истории Connected находится запомненное
глубокое состояние Stop в которое и входит автомат последовательно запуская все входные действия на пути из Connected в Stop.

13) Чтобы перевести прибор и программу в состояние измерения, мы запускаем кнопку управления, которые активны при этом надо послать сначала команду прибору
на измерение, программа при этом через событие Изменение режима переходит из Interaction в Mode Change, в нем посылается запрос прибору и производится переход
когда прибор ответил, но переход уже нужен не в Stop а в Measures (измерения), для этого используются сторожевые условия на переходах из состояния Mode Change,
срабатывает один из этих переходов с правильным сторожевым условием

14) В состоянии измерение программа посылает запросы и отображает даннные измерения

15) Также есть возможность перевода в режим работы с флэш памятью прибора, Flash Working при этом все запросы прерываются при выходе из Idle Scanning, Interaction
и в диалоге работы с флэш можно посмотреть флэш память, очистить, считать данные. Когда пользователь закрывает диалог программа входит в историческое состояние
в состоянии Interaction то есть восстанавливает предыдущий режим работы

К сожалению показать как это все работает в реальном времени не представляется возможнным (нужен прибор и программа), но поверьте на слово, логика
пользовательского интерфейса программы выглядит очень интересно и умно за счет этих включений, выключений контролов в нужное время, индикаторов
обмена, изменяющихся сообщений состояния, что называется реактивный пользовательский интерфейс. И на отладку этого дела я потратил очень малое время,
вся отладка сводилась к правильному пониманию диаграммы и введения ее соответствия в коде, чтобы все обработчики были подключены и запускали нужные действия.

При этом возможности приложения последовательно наращиваются, сначала не было истории, появилась, потом добавляется состояние FlashWorking которого не было, и так
далее, все это довольно легко расширяемо и быстро перенастраивается. В диаграмме это только надо добавить новое подсостояние и переход к нему, или объединить
состояния в один родитель, текст переписать в описании несложно, но при этом изменяется логика во всем приложении и после перекомпиляции будет новой. Макроаттрибут
перекомпилируется довольно быстро, сама библиотека только долго собирается (400 кб уже весит dll ка), но для тех кто ее не собирает это не существенно.

[statechart(<#

flags : auto_initial; 

state NotConnected
{
 entry / status_ready;
 entry / buttons_init;

 connecting_clicked [PortOpened] => Working; 
}

state Working
{
  
  state Connecting
  {
   do / testing_connection; // внутренняя деятельность в состоянии (крутится в нем)
  }
  
  state Scanning
  {
    $> / begin_scan; // альтернативный синтаксис входного и выходного действия
    $< / stop_reqs;
  }

  state Connected
  {   
     0 => H; // начальный переход в историческое состояние

     (H*) => Interaction; // историческое состояние и переход по умолчанию

    state Interaction
    {
      $> / pribor_controls_ena;
      $< / pribor_controls_dis;
      
      (H*) // другое историческое состояние

      state NoCalibration
      {
       
       state IdleScanning
       {
         entry / mode_buttons_ena;
         exit / mode_buttons_dis;

         state Stop
         {
           do / scan;
         }

         state Measures
         {
           do / show_meas;
         } 
       }
      }

      state Calibration
      {
      }

      mode_change => ModeChange;
      flash_dialog => FlashWorking; 
    }

    state FlashWorking
    {
      _ => Interaction.H;
    }
    
    state ModeChange
    {
      reqs_complete [mode_is_stop] => Measures;
      reqs_complete [mode_is_measure] => Stop;
    }
    
    state Loading
    {
    }
  }

  
}


#>)]
class GuiFsm
{
}


Дальше после компиляции, надо будет правильно подключить обработчики к действиям, для входных, выходных действий, связать событие в пользовательском интерфейсе с
запуском событий автомата, привязать активности и сторожевые условия к объектам программы и пользовательскому интерфейсу и все. Вся эта сложная логика
начинает работать, не знаю сколько бы ушло время на отладку без конечного автомата, но уж точно в несколько раз больше чем создание диаграммы состояний и перенос
ее в описание автомата библиотеки. Как видите достаточно один раз переосмыслить логику на диаграмме и приложение может сразу перестроено на новый лад и расширять
его будет удобно, можно при этом манипулировать большими сущностями поведения системы (состояниями и переходами), что дает сразу кумулятивный эффект в наращивании
сложной функциональности.
В будущем расскажу о других возможностях библиотеки, далее планируется работа с параллельными состояниями, которые дают еще один пласт мощи для написания сложных систем,
но реализация их в библиотеке не так проста как обычных последовательных состояний, поэтому я трачу на них больше времени и отложил на реализацию после основных функций.

ЗЫ: Если вы вклинитесь в теорию диаграмм состояний, то вам будет очень просто решать сложные задачи. Надеюсь эта библиотека поможет эффективно вам решить их.
Re[4]: [Nemerle.Statechart] примеры и описания
От: CodingUnit Россия  
Дата: 24.08.11 08:22
Оценка: 4 (1)
Здравствуйте, FDSC, Вы писали:

FDS>Здравствуйте, CodingUnit


FDS>Ты не мог бы пояснять обозначения на схемах, а то написано много, а понять ничего не возможно, и что это за стандарт такой и где взять его описание (жел., на русском) то же.


Что именно непонятно, для начала конечно лучше посмотреть описание диаграмм состояний UML, например здесь:

http://www.business-process.ru/designing/methodology/uml/theory/statechat_diagram_theory.html
http://khpi-iip.mipk.kharkiv.edu/library/case/leon/gl6/gl6.html
http://ertostik.net/uml/diagramma-sostoyaniy-state-diagram.html

UML (Unified Modelling Language) — унифицированный язык моделирования, визуальный язык, вобрал в себя лучшие практики моделирования структуры и поведения программных систем, включает в себя 13 видов диаграмм, один из них Диаграммы состояний — концепция визуального представления конечного автомата, можешь почитать начиная с этого сообщения, где я начал описание:

http://www.rsdn.ru/forum/nemerle/4391490.aspx
Автор: VladD2
Дата: 24.08.11


Есть много книг по UML, он позволяет проектировать и моделировать приложение перед его созданием и служит для лучшего понимания работы приложения и общения разработчиков, сами же диаграммы состояний помогают легче понять сложную логику и перенести ее в код с помощью библиотеки.

Вот книги:
UML. Руководство пользователя (Грейди Буч, Джеймс Рамбо, Айвар Джекобсон)
UML. Основы. Краткое руководство по унифицированному языку моделирования (Мартин Фаулер)

Если что задавай вопросы, отвечу.
Re[5]: проблема с билдом в VS2010
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.08.11 11:17
Оценка: 2 (1)
Здравствуйте, FDSC, Вы писали:

FDS>Здравствуйте, VladD2, Вы писали:



VD>>Собрать компилятор из исходников довольно просто. Нужно только предварительно поставить VS 2010 SP1 и VS SDK 2010. Далее остается только скачать исходники и запустить DevBuildQuick-4.cmd.



FDS>Влад, я собрал компилятор без VS SDK (у меня пиратка и SDK не ставится),


Какая еще пиратка? VS никак не защищена и на просторах торрентов туча инсталяторов из МСДН-а.

FDS>вроде бы без ошибок (убрал _Integration и все упоминания о VSIntegration из проекта NemerleAll). Только ругался на версию (я руками поправил с 1.0.0.9999 на 1.0.0.87 — GitVersion не знаю как там должен работать, но не работает). Так что странно, что VS всё равно не собирает Видать, я всё-таки криво собрал


Это не серьезно. Интеграция может работать только на последних версиях сборок компилятора. Не странно, что все валится.

ЗЫ

VS SDK можно скачать в виде iso. Ссылка пробегала где-то на хабре. Думаю гугль ее ищет влет. Попробуй его поставить.

Кроме того VS SDK может не ставиться потому что это не та версия. Нужно поставить SP1 для VS 2010 и уже потом ставить соответствующую версию VS SDK. Если попытаться поставить неверную версию, то будет облом. Может быть именно это и произошло в твоем случае.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: библиотека автоматов состояний Nemerle.Statechart
От: Ziaw Россия  
Дата: 27.07.11 17:12
Оценка: 1 (1)
Здравствуйте, CodingUnit, Вы писали:

CU>Хотел спросить есть ли у сообщества согласие на хостинг библиотеки в snippets, я хотел назвать Nemerle.Statechart.


Вот я сейчас крамолу скажу, но, имхо, лучше ее сделать отдельным проектом. Проекты в снипетах просто забываются. При случае, даже некуда пальцем ткнуть, сказав вот есть проект на немерле (ибо многие небезосновательно считают снипеты просто пачкой недоделанных сэмплов, в которых сам черт ногу сломит).

А так у нее будет собственный репо, со своим Readme.md, своим хозяином и возможностью ее форкать, создавать issues и видеть, что ее кто-то развивает. Или не развивает. Но можно легко скачать ее, собрать и посмотреть. Отдельный собственный проект провоцирует на написание какой-никакой доки лежащей прямо в проекте. Ее можно добавить в снипеты как submodule и никуда она не потеряется. Да и вообще надо больше проектов на nemerle, хороших и разных, чтобы интересующиеся могли их найти на гитхабе по языку. О ней можно рассказать в блоге и дать ссылку на репо, а не папку в одном большом каталоге репо компилятора. В конце концов, глядя на нее человек может заинтересоваться языком, а глядеть на нее в репозитарии немерла левый человек просто не будет.

Вобщем я знаю, Влад не одобрит, но решать тебе. Думай сам. Библиотека явно интересная и заслуживает отдельного проекта. Да и это: https://github.com/languages/Nemerle не дело, доказывай потом, что на nemerle, кроме компилятора, можно что-то написать.
Re: библиотека автоматов состояний Nemerle.Statechart
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.07.11 18:55
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>Хотел спросить есть ли у сообщества согласие на хостинг библиотеки в snippets, я хотел назвать Nemerle.Statechart.


Все будут только "за".

Только делать теперь это нужно через создание fork-а и размещения пул-реквеста на github. Тут рядом это все описано. Почитай, плиз.
http://www.rsdn.ru/forum/nemerle/4336310.1.aspx
Автор: Ziaw
Дата: 09.07.11


CU>еще не достает до полноты:

CU> -terminal pseudostate
CU> -do activity
CU> -choice
CU> -junction
CU> -fork and join pseudostates
CU> -orthogonal regions
CU> -local and external transitions
CU> -deffered events

Еще бы понимать что все это значит .

CU>Что скажет сообщество на сей творческий порыв


Скажет — давай! Только к этому делу еще нужно качественное описание и побольше примеров.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: библиотека автоматов состояний Nemerle.Statechart
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.07.11 22:51
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Вот я сейчас крамолу скажу, но, имхо, лучше ее сделать отдельным проектом. Проекты в снипетах просто забываются.


Да ладно. Много забытых? Проекты забываются когда их забрасывают.

Z>При случае, даже некуда пальцем ткнуть, сказав вот есть проект на немерле (ибо многие небезосновательно считают снипеты просто пачкой недоделанных сэмплов, в которых сам черт ногу сломит).


Z>А так у нее будет собственный репо, со своим Readme.md, своим хозяином и возможностью ее форкать, создавать issues и видеть, что ее кто-то развивает. Или не развивает. Но можно легко скачать ее, собрать и посмотреть. Отдельный собственный проект провоцирует на написание какой-никакой доки лежащей прямо в проекте.


Если это библиотека претендующая на поставку в составе немерала, то до релизного состояния ей самое место в сниппетах.

Z> Ее можно добавить в снипеты как submodule и никуда она не потеряется.


ОК. Добавь какой-нибудь проект в сниппеты в виде submodule. Поглядим как это выглядит.

Z>Да и вообще надо больше проектов на nemerle, хороших и разных, чтобы интересующиеся могли их найти на гитхабе по языку.


Да кто же спорит то? Все согласны. Но отдельный проект имеет как преимущества, так и недостатки. Такие проекты нельзя использовать как тесты и рано или поздно они могут перестать компилироваться на текущей версии.

Z>О ней можно рассказать в блоге и дать ссылку на репо, а не папку в одном большом каталоге репо компилятора. В конце концов, глядя на нее человек может заинтересоваться языком, а глядеть на нее в репозитарии немерла левый человек просто не будет.


Все это можно и нужно делать без оглядки на то где находится проект.
Более того! Намного важнее довести проект до релизного состояния (когда его можно будет полноценно использовать).

Проблема большинства проектов не в том, что они не там находятся, в том что они так и не выходят из стадии экспеременов на коленке.

Z>Вобщем я знаю, Влад не одобрит, но решать тебе. Думай сам. Библиотека явно интересная и заслуживает отдельного проекта. Да и это: https://github.com/languages/Nemerle не дело, доказывай потом, что на nemerle, кроме компилятора, можно что-то написать.


Я не ретроград. Пока что этой библиотеке самое место в сниппетах. Но если идея с сабмоудями прокатит, то почему бы и нет?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: библиотека автоматов состояний Nemerle.Statechart
От: Ziaw Россия  
Дата: 28.07.11 00:00
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Да ладно. Много забытых? Проекты забываются когда их забрасывают.


Забыть о проекте на своем гитхаб-аккаунте сложнее. Особенно если фоловеры есть и баги подкидывают.

VD>Если это библиотека претендующая на поставку в составе немерала, то до релизного состояния ей самое место в сниппетах.


А зачем она в составе стандартной поставки немерла? Это явно не библиотека общего назначения. Впрочем, если надо сабмодуль поможет.

VD>ОК. Добавь какой-нибудь проект в сниппеты в виде submodule. Поглядим как это выглядит.


Ок. Я только одну проблему вижу.

VD>Да кто же спорит то? Все согласны. Но отдельный проект имеет как преимущества, так и недостатки. Такие проекты нельзя использовать как тесты и рано или поздно они могут перестать компилироваться на текущей версии.


Какие проекты в снипетах сейчас используются как тесты? Имхо только те, которые в состав инсталятора входят. Так они в любом случае будут собираться с с инсталятором.

VD>Все это можно и нужно делать без оглядки на то где находится проект.


Что делать? Писать и закрывать баги в репо немерла? Или страницу в вики создавать?

VD>Проблема большинства проектов не в том, что они не там находятся, в том что они так и не выходят из стадии экспеременов на коленке.


Это другая проблема.

VD>Я не ретроград. Пока что этой библиотеке самое место в сниппетах. Но если идея с сабмоудями прокатит, то почему бы и нет?


Прокатит, если проект самодостаточен и не ссылается на другие проекты в снипетах.
Re[4]: библиотека автоматов состояний Nemerle.Statechart
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.07.11 14:07
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Забыть о проекте на своем гитхаб-аккаунте сложнее. Особенно если фоловеры есть и баги подкидывают.


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

Z>А зачем она в составе стандартной поставки немерла? Это явно не библиотека общего назначения. Впрочем, если надо сабмодуль поможет.


Библиотек общего назначения не бывает. Библиотеки всегда решают какую-то задачу.

КА могут применяться чуть ли не для решения любой задачи. Это скорее вопрос знаний и дизайна. Не применяют их обычно из-за того, что в нетривиальных случаях их реализация сложнее чем другие подходы. Если же такая библиотека будет в стандартной поставке, то это по любому будет удобно потребителям.

VD>>ОК. Добавь какой-нибудь проект в сниппеты в виде submodule. Поглядим как это выглядит.


Z>Ок. Я только одну проблему вижу.


Какую?

Z>Какие проекты в снипетах сейчас используются как тесты?


Почти все. Они же собираются переодически.

Z>Имхо только те, которые в состав инсталятора входят. Так они в любом случае будут собираться с с инсталятором.


Ну, и на фиг нужно их выносить в отдельные репозитории?

Z>Что делать? Писать и закрывать баги в репо немерла? Или страницу в вики создавать?


И то, и другое, и третье.


VD>>Проблема большинства проектов не в том, что они не там находятся, в том что они так и не выходят из стадии экспеременов на коленке.


Z>Это другая проблема.


Не-а. Это основная проблема. Остальное — мелочи.

VD>>Я не ретроград. Пока что этой библиотеке самое место в сниппетах. Но если идея с сабмоудями прокатит, то почему бы и нет?


Z>Прокатит, если проект самодостаточен и не ссылается на другие проекты в снипетах.


Ну, попробуй на каком-нить мелком проекта для начала.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: библиотека автоматов состояний Nemerle.Statechart
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.07.11 14:07
Оценка:
Здравствуйте, VladD2, Вы писали:

Z>>Прокатит, если проект самодостаточен и не ссылается на другие проекты в снипетах.


VD>Ну, попробуй на каком-нить мелком проекта для начала.


Если будет все ОК, то можно будет и другие проекты вынести.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: библиотека автоматов состояний Nemerle.Statechart
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.07.11 15:51
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>Идея написания библиотеки работы с конечными автоматами на Nemerle пришла давно, вот здесь началась развиваться тема на форуме:

CU>http://rsdn.ru/forum/nemerle/3716028.aspx
Автор: CodingUnit
Дата: 24.02.10


Я тебе написал там на твой пул-реквест пару замечений.

Исправь их и можно будет замерджить.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: библиотека автоматов состояний Nemerle.Statechart
От: Ziaw Россия  
Дата: 29.07.11 04:48
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Да ладно. Погляди когда в твои рельсы последний раз комит был.


8го июня. Там проблема в использовании MVC3 и VS2010.

VD>Библиотек общего назначения не бывает. Библиотеки всегда решают какую-то задачу.




Z>>Какие проекты в снипетах сейчас используются как тесты?


VD>Почти все. Они же собираются переодически.


Кем?

Z>>Прокатит, если проект самодостаточен и не ссылается на другие проекты в снипетах.


VD>Ну, попробуй на каком-нить мелком проекта для начала.


Ок.
Re[6]: библиотека автоматов состояний Nemerle.Statechart
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.07.11 10:13
Оценка:
Здравствуйте, Ziaw, Вы писали:

VD>>Да ладно. Погляди когда в твои рельсы последний раз комит был.


Z>8го июня.


А до этого сколько коммитов не было? Я ссылки на проект давал, а мне отвечали, что он заброшен.

Z>Там проблема в использовании MVC3 и VS2010.


Что за проблема? Могу попробовать подсобить в ее решении.

Вообще, поддержку MVC3 и Разора надо сделать. Хотя на мой взгляд — это все вариации на тему каменного топора, но с политической точки зрения это делать нужно. Вебом занимаются 90% народа. Так что это первое на чем новички могут пробовать язык.

VD>>Библиотек общего назначения не бывает. Библиотеки всегда решают какую-то задачу.


Z>


Ага. И никак иначе. Бывают конечно сборники вроде дотнтной библиотеки, но по факту они состоят и множества специализированных.

Z>>>Какие проекты в снипетах сейчас используются как тесты?


VD>>Почти все. Они же собираются переодически.


Z>Кем?


Мной, например. Да большая часть проектов в станадартных тестах задействована.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: библиотека автоматов состояний Nemerle.Statechart
От: CodingUnit Россия  
Дата: 03.08.11 16:44
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Ziaw, Вы писали:


Z>>А зачем она в составе стандартной поставки немерла? Это явно не библиотека общего назначения. Впрочем, если надо сабмодуль поможет.


VD>Библиотек общего назначения не бывает. Библиотеки всегда решают какую-то задачу.


VD>КА могут применяться чуть ли не для решения любой задачи. Это скорее вопрос знаний и дизайна. Не применяют их обычно из-за того, что в нетривиальных случаях их реализация сложнее чем другие подходы. Если же такая библиотека будет в стандартной поставке, то это по любому будет удобно потребителям.


Я с Владом полностью согласен такая библиотека хороша была бы в стандартной поставке, КА могут применяться где угодно, я без них сейчас не мыслю сложной разработки, в boost есть подобная библиотека, а boost это практически добавление к стандартной библиотеке c++, которая хорошо стандартизириуется и имеет высокое качество.

Z>>Что делать? Писать и закрывать баги в репо немерла? Или страницу в вики создавать?


VD>И то, и другое, и третье.


Я пока не хочу особо широко распространяться о библиотеке сейчас хорошо бы протестировать ее и дать Nemerle сообществу как инструмент, может быть в будущем, посмотрим... Размещения в сниппеты будет более чем достаточно.

Сегодня продолжу обсуждение возможностей библиотеки и автоматного подхода. Хочу заметить что используя автоматы можно моделировать объекты реального мира, в прошлый раз обсуждали модель телефона, таким образом можно моделировать что угодно, например: чайник, светофор, лифт, кодовая панель, телевизор, автомат продажи еды, банкомат, собака, вплоть до создания робота выполняющего разные действия. Программа тоже может являтся автоматом, gui реагирует на воздействия пользователя, кнопки должны включаться выключаться в определенной последовательности. Сегодня я покажу как можно автоматизировать часть логики приложения и gui на простом примере, этот пример есть в тестах библиотеки.

Задача такова, всем известны приложения типа word, которые отслеживают изменения в файлах и не дают выйти из приложения если файл не был сохранен, gui при этом тоже реагирует и если файл открыт то его название пишется в заголовке окна, если изменен часто выводится * после имени файла, такую логику можно пытаться писать влоб, но отлаживать такой код будет сложно, долго придется выслеживать ошибки, чтобы логика соответствовала, которые еще могут в будущем проявится неожиданно, можно нанять штат тестеров и исправлять логику, а можно пойти автоматным подходом и нарисовать диаграмму состояний, она должна выглядеть примерно так:


Логика такова:

1) При запуске приложения оно входит в состояние Ожидание через переход из начального псевдосостояния при входе в состояние выключаются кнопки сохранения, в заголовке отображается название программы

2) Далее пользователь может либо открыть файл либо создать новый, если он открывает файл, то срабатывает переход из состояния Не Нужно Сохранение, по открытию и если файл открыт успешно, выходит из состояния Ожидание при этом запускается выходное действие включается кнопка сохранения, заходит в состояние Сохраненный через начальное состояние в Не Нужно Сохранение, при этом при входе в состояние Сохраненный в надписи начинает отображаться имя файла и запоминается последний сохраненный файл

3) Далее пользователь может открывать новые файлы и логика будет повторяться если программа была в состоянии Сохраненный никаких предупреждений писаться не будет

4) Далее пользователь производит некоторые действия в программе и изменяет данные так что они разняться с файлом это событие изменение, которое запускает переход из Сохраненный в Измененный при этом автомат выходит из состояния Сохраненный входит в Нужно Сохранение запускает действие при входе кнопка сохранения включается всегда в этом состоянии, поскольку файл нуждается в сохранении, при этом в надписи отображается звездочка (*) рядом с именем файла что означает что данные изменены.

5) В этом состоянии пользователь может принудительно сохранить файл тогда автомат перейдет в состояние Сохраненный, если он выберет Новый файл или Открыть файл, то программа ему сообщит что файл нуждается в сохранении и даст вопрос о сохранении, при этом пользователь может отвергнуть или согласится или отменить процедуру, если он выберет Новый Файл и соглашается на сохранение то данные сохраняются и создается новый файл, при этом автомат перейдет в состояние Новый Файл который также требует чтобы данные были сохранены, в надписи при этом отображается не имя файла а некое имя представляющее новые данные

6) Если пользователь запросит выход из приложения то оно будет вести себя в зависимости от текущего состояния, если оно было сохранено то ничего не будет сказано, если было в состоянии Нужно Сохранение то будет запрошено сохранение

7) Далее все повторяется в зависимости от того что делает пользователь в приложении

Как видите логика легко описывается в рантайме если диаграмма продумана логика начинает работать сразу не требует никакой отладки и доводки, поиска ошибок, если что то не так работает то надо переосмыслить диаграмму и может стоить добавить действие при входе или перенести переход во внешнее состояние и все магически начинает работать

На языке библиотеки подобный автомат можно представить так, более подробный пример смотри в тестах (когда будет принят пуллреквест):

[statechart(<#

// флаги auto_initial автоматически добавляет в композитное состояние начальный переход в первое подсостояние
// transition_completed_events — генерирует обработчик который оповещает о том что произошло событие (нужно при отладке)
flags : auto_initial transition_completed_events;

0 => Ожидание; // начальный переход

state НенужноСохранение
{

$> / СохранениеВыкл; // действие при входе

НовыйФайл => НужноСохранение;
ОткрытФайл =>@; // переход в себя

state Сохранен
{
$> / НадписьИмяФайла ПоследнийФайлТек; // действие при входе 2 действия
Сохранение =>@; // переход в себя
Изменение => Измененный;
}

state Ожидание
{
$> / СохранениеВсеВыкл НадписьНазваниеПрограммы;
$< / СохранениеКакВкл;
}

}

state НужноСохранение
{
$> / СохранениеВкл;
ОткрытФайл, Сохранение => НенужноСохранение;
НовыйФайл =>@;

state Новый
{
$> / НадписьФайл ПоследнийФайлПустой;
}

state Измененный
{
$> / НадписьИзменен;
}

}

#>
)]
public class FileFsm
{
}

Далее генерируется на основе описания класс автомата, который можно использовать во внешнем коде. Вот как выглядит класс в рефлекторе:





Здесь показано тело класса Transition — это методы переходов они выполняют действия и выдают результирующее состояние,
также там видны события для действий, чтобы автомат делал что либо полезное к его событиям подключают внешние действия, типа как вывод в строку заголовка окна,
также есть стандартные методы определения состояния IsInState(st), Initiate() — запуск автомата




здесь показаны вложенные классы состояний, они представляют из себя варианты, в них генерируются виртуальные методы обработки событий
вот так выглядит тело одного из методов




вот так выглядит функция перехода

начальный



обычный



тело класса, события




это тело запуска события



метод Switch просто проверяет результат на null и присваивает текущей переменной cur_state если произошел переход

Вот вообщем и весь автомат, осталось в библиотеке реализовать семантику параллельных состояний, кое какие псевдосостояния и полезные функции, аттрибуты, флаги, опции, сейчас уже можно строить неплохие автоматы на ней.

На этом обсуждение закончу, потом дам больше примеров и описаний, до новых встреч.



от макросов до вариантов
и массой всяких преимуществ
благодаря nemerle-братству
программеров жизнь стала лучше
Re[7]: библиотека автоматов состояний Nemerle.Statechart
От: CodingUnit Россия  
Дата: 03.08.11 17:14
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Ziaw, Вы писали:


VD>>>Да ладно. Погляди когда в твои рельсы последний раз комит был.


Хочу задать вопрос по архитектуре автомата, встала задача сделать внутреннюю активность то есть параллельную деятельность осуществляемую в автомате, специфика в том что асинхронное действие надо прерывать когда автомат захочет.
Я начал реализовывать через поток Thread, но код тяжеловат каждый раз приходится запускать создавая новый объект Thread и останавливать через Abort Join, есть возможности в библиотеке Rx Extensions, но не очень хорошо ссылаться на внешнюю библиотеку, может известны другие более экономичные подходы для реализации отменяемых асинхронных действий?



от макросов до вариантов
и массой всяких преимуществ
благодаря nemerle-братству
программеров жизнь стала лучше
Re[8]: библиотека автоматов состояний Nemerle.Statechart
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.08.11 01:23
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>Хочу задать вопрос по архитектуре автомата, встала задача сделать внутреннюю активность то есть параллельную деятельность осуществляемую в автомате, специфика в том что асинхронное действие надо прерывать когда автомат захочет.

CU>Я начал реализовывать через поток Thread, но код тяжеловат каждый раз приходится запускать создавая новый объект Thread и останавливать через Abort Join, есть возможности в библиотеке Rx Extensions, но не очень хорошо ссылаться на внешнюю библиотеку, может известны другие более экономичные подходы для реализации отменяемых асинхронных действий?

Такие вещи нужно реализовывать на базе пула потоков. В .net 4 есть библиотека упрощающая подобные задачи (см. класс Task). Пул потоков позволяет не тратить время на создание потоков и распределяет работу между имеющимися процессорами, так как старается выделять столько процессоров сколько нужно для их загрузки (ни больше, и не меньше).

Поток лучше не прерывать исключением, а использовать идеологию токенов отмены (cancellation token). По сути это навортоты над простым приемом — предаем в функцию ссылку на некий флаг и проверяем его все время. Если он поднят, то завершаем выполнение.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: библиотека автоматов состояний Nemerle.Statechart
От: FDSC Россия consp11.github.io блог
Дата: 05.08.11 19:12
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU> Текущие возможности библиотеки таковы


Не собирается что-то проект из сниппетов (966 ошибок). Там что-то надо сделать, чтоб собрался?
Re[2]: проблема с билдом в VS2010
От: FDSC Россия consp11.github.io блог
Дата: 05.08.11 20:27
Оценка:
Здравствуйте, FDSC, Вы писали:

FDS>Здравствуйте, CodingUnit, Вы писали:


CU>> Текущие возможности библиотеки таковы


FDS>Не собирается что-то проект из сниппетов (966 ошибок). Там что-то надо сделать, чтоб собрался?


Через MSBuild билдится нормально, только GitVеrsion не работает
Re[3]: проблема с билдом в VS2010
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.08.11 03:20
Оценка:
Здравствуйте, FDSC, Вы писали:

FDS>>Не собирается что-то проект из сниппетов (966 ошибок). Там что-то надо сделать, чтоб собрался?


FDS>Через MSBuild билдится нормально, только GitVеrsion не работает


Данная библиотека испльзует возможности которые доступны только при сборке компилятора из исходников (т.е. использует компилятор последней версии).
variant_option я добавил совсем недавно.

Собрать компилятор из исходников довольно просто. Нужно только предварительно поставить VS 2010 SP1 и VS SDK 2010. Далее остается только скачать исходники и запустить DevBuildQuick-4.cmd.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: проблема с билдом в VS2010
От: FDSC Россия consp11.github.io блог
Дата: 06.08.11 10:43
Оценка:
Здравствуйте, VladD2, Вы писали:


VD>Собрать компилятор из исходников довольно просто. Нужно только предварительно поставить VS 2010 SP1 и VS SDK 2010. Далее остается только скачать исходники и запустить DevBuildQuick-4.cmd.



Влад, я собрал компилятор без VS SDK (у меня пиратка и SDK не ставится), вроде бы без ошибок (убрал _Integration и все упоминания о VSIntegration из проекта NemerleAll). Только ругался на версию (я руками поправил с 1.0.0.9999 на 1.0.0.87 — GitVersion не знаю как там должен работать, но не работает). Так что странно, что VS всё равно не собирает Видать, я всё-таки криво собрал
Re[6]: проблема с билдом в VS2010
От: FDSC Россия consp11.github.io блог
Дата: 06.08.11 12:46
Оценка:
Здравствуйте, VladD2, Вы писали:


VD>Кроме того VS SDK может не ставиться потому что это не та версия. Нужно поставить SP1 для VS 2010 и уже потом ставить соответствующую версию VS SDK. Если попытаться поставить неверную версию, то будет облом. Может быть именно это и произошло в твоем случае.


Ага, оказалось, что у меня SP1 поставлен, а SDK, наоброт, старой версии.

Запустил DevBuildQuick-4.cmd — прошло без ошибок (правда с какими-то предупреждениями), но всё равно в VS нефига ничего не собирается с огромным кол-вом ошибок, гит на pull пишет

c:\Program Files (x86)\Git\bin\git.exe pull --progress "origin" +refs/heads/master
From https://github.com/rsdn/nemerle
* branch master -> FETCH_HEAD
Done
Already up-to-date.
Re[7]: проблема с билдом в VS2010
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.08.11 14:05
Оценка:
Здравствуйте, FDSC, Вы писали:

FDS>Ага, оказалось, что у меня SP1 поставлен, а SDK, наоброт, старой версии.


FDS>Запустил DevBuildQuick-4.cmd — прошло без ошибок (правда с какими-то предупреждениями), но всё равно в VS нефига ничего не собирается с огромным кол-вом ошибок, гит на pull пишет


FDS>c:\Program Files (x86)\Git\bin\git.exe pull --progress "origin" +refs/heads/master

FDS>From https://github.com/rsdn/nemerle
FDS> * branch master -> FETCH_HEAD
FDS>Done
FDS>Already up-to-date.

Похоже ты что-то там направил.


Я не знаток командной строки гита. Пользуюсь Гит Эксеншон-ом. С его помощью можно нажать кнопку Commit, в появившемся диалоговом окне выделить все измененные файлы (в левом, верхнем списке) и выбрать в контекстном меню пункт "Reset file changes". Это восстановит все файлы в исходное состояние.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: проблема с билдом в VS2010
От: FDSC Россия consp11.github.io блог
Дата: 06.08.11 14:11
Оценка:
Здравствуйте, VladD2, Вы писали:


VD>Похоже ты что-то там направил.



VD>Я не знаток командной строки гита. Пользуюсь Гит Эксеншон-ом. С его помощью можно нажать кнопку Commit, в появившемся диалоговом окне выделить все измененные файлы (в левом, верхнем списке) и выбрать в контекстном меню пункт "Reset file changes". Это восстановит все файлы в исходное состояние.


Я им тоже пользуюсь. Я прямо удалил все файлы из рабочей копии — это гораздо более надёжно, чем "Reset file changes" (у меня, по крайней мере, не всегда правильно работает эта штука). Ревизии у меня rsdn-овске, последние, правленных файлов быть не должно (проверил на NemerleAll.nproj — он стал обычным, а не таким, как я его правил)
Re[9]: проблема с билдом в VS2010
От: FDSC Россия consp11.github.io блог
Дата: 06.08.11 16:17
Оценка:
После удаления Nemerle из VS2010 и полной его пересборки с установлением заново ошибок стало гораздо меньше: видимо, старая версия просто так не перезатёрлась, а я об этом не подумал.

Но тесты всё равно не компилировались до тех пор, пока не удалил и не передобавил снова референсы на snippets\Nemerle.Statechart\Tests\fsmtest\Reference\Sanford.StateMachineToolkit.dll и snippets\Nemerle.Statechart\Tests\fsmtest\Reference\CommonLib.Fsm.dll

Странно, но, в принципе, всё заработало. Спасибо за помощь.
Re[10]: проблема с билдом в VS2010
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.08.11 22:48
Оценка:
Здравствуйте, FDSC, Вы писали:

FDS>После удаления Nemerle из VS2010 и полной его пересборки с установлением заново ошибок стало гораздо меньше: видимо, старая версия просто так не перезатёрлась, а я об этом не подумал.


Странно. Возможно какой-то вирус побаловался.

FDS>Но тесты всё равно не компилировались до тех пор, пока не удалил и не передобавил снова референсы на snippets\Nemerle.Statechart\Tests\fsmtest\Reference\Sanford.StateMachineToolkit.dll и snippets\Nemerle.Statechart\Tests\fsmtest\Reference\CommonLib.Fsm.dll


Это вполне возможно. Автор не очень опытный. Может что-то не заметил. Сделай диф проектных файлов (с оригиналом). Может будет ясно что там не так.

FDS>Странно, но, в принципе, всё заработало. Спасибо за помощь.


На здоровье.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: библиотека автоматов состояний Nemerle.Statechart
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.08.11 19:50
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>Создал пул реквест с новыми фичами, реализовал:


CU>- поддержку do активности в состоянии на базе Task из .net 4

CU>- разные флаги к этой фиче чтобы можно было настраивать
CU>- terminate узел (см. описание Terminate)
CU>- провел некоторые оптимизации в анализаторе и генераторе, убрал обработчики действий в соотв. им вх/вых действия
CU>- сделал пример с gui для работы с файлами

Залил.

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

Что за странные операторы "^|><"?
Конструкции вроде:
def (run_body, stop_body) = if (conc)
                            {

лучше переносить так:
def (run_body, stop_body) = 
  if (conc)
  {

иначе они очень сильно уезжают вбок.

CU>ЗЫ: Если вы вклинитесь в теорию диаграмм состояний, то вам будет очень просто решать сложные задачи. Надеюсь эта библиотека поможет эффективно вам решить их.


В наше время мало придумать хорошую идею. И даже мало ее хорошо реализовать. (особенно если идея не тривиальная)
Нужно еще ее хорошенько подать.

По-моему для данного проекта нужно написать хорошую статью описывающую библиотеку и демонстрирующую примеры ее использования.
Под "хорошей" я понимаю:
1. Внятную.
2. Доступную для чтения непосвященным читателям.
3. Изобилующую простыми, короткими и понятными примерами.
4. Не затянутую и не скучную.

Собственно, если такая статья будет, то мы с удовольствием опубликуем ее на www.rsdn.ru и в RSDN Magazine (русскую весрию). И если, будет английская версия, то еще и на www.nemerle.org (а можно еще и на www.codeproject.com).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: библиотека автоматов состояний Nemerle.Statechart
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.08.11 21:05
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>К сожалению показать как это все работает в реальном времени не представляется возможнным (нужен прибор и программа),


Ну, почему же? Показать очень даже можно. Для этого нужно всего лишь записать скрин-каст. Для этого есть ряд программ которые ищутся в гугле (или на торрентах ).
Результатом будет авишник демонстрирующий поведение интерфейса и объяснение автора.

CU>но поверьте на слово, логика

CU>пользовательского интерфейса программы выглядит очень интересно и умно за счет этих включений, выключений контролов в нужное время, индикаторов
CU>обмена, изменяющихся сообщений состояния, что называется реактивный пользовательский интерфейс.

А нельзя ли как-то соединить конечные автоматы и реактивный пользовательский интерфейс чтобы вообще не писать код для UI?
Ну, скажем прямо в автомат ввести описание контролов для WPF/WinForms. Или еще как-то.
На мой взгляд — это могло бы оказаться очень востребовано.

CU>И на отладку этого дела я потратил очень малое время,вся отладка сводилась к правильному пониманию диаграммы и введения ее соответствия в коде, чтобы все обработчики были подключены и запускали нужные действия.


На счет диаграммы... На чем ты ее рисуешь? И возможно ли автоматически строить описание на немерле по таким диаграммам? А то получается лишнее действие — переписывание диаграмм в код. По сути ведь код — это другое представление для диаграмм (а диаграммы для кода). Можно рассматривать запись диаграммы в код как сериализацию диаграммы.

CU>При этом возможности приложения последовательно наращиваются, сначала не было истории, появилась, потом добавляется состояние FlashWorking которого не было, и так

далее, все это довольно легко расширяемо и быстро перенастраивается.

Ага. Но не хватает прямой связи с GUI-ём.

CU>Дальше после компиляции, надо будет правильно подключить обработчики к действиям, для входных, выходных действий, связать событие в пользовательском интерфейсе с запуском событий автомата, привязать активности и сторожевые условия к объектам программы и пользовательскому интерфейсу и все. Вся эта сложная логика начинает работать, не знаю сколько бы ушло время на отладку без конечного автомата, но уж точно в несколько раз больше чем создание диаграммы состояний и перенос ее в описание автомата библиотеки.


А если бы можно было бы описать связь с контралами прямо в диаграмме и сделать сериализацию прямо в код, то вообще было бы идеально!

CU>В будущем расскажу о других возможностях библиотеки, ...


Это здорово, но лучше делать это в отдельной статье (а то и в серии статей). А то ветка эта со временем затеряется и мало кто про нее вспомнит. А найти ее будет не так то и просто.
Так что предлагаю скачать с нашего сайта ... и писать уже в нем.

CU>далее планируется работа с параллельными состояниями, которые дают еще один пласт мощи для написания сложных систем,

CU>но реализация их в библиотеке не так проста как обычных последовательных состояний, поэтому я трачу на них больше времени и отложил на реализацию после основных функций.

ЗЫ

Еще раз настоятельно прошу перевести весь русский в коде на английский. И если вдруг в файле появляется русский, то его обязательно нужно сохранять в виде UTF-8 с BOM. Иначе многие текстовые редакторы и вьюеры вместо русского будут показывать абракадабру. Например, вот что отображается в файле snippets\Nemerle.Statechart\Tests\fsmtest\gui_file_test\Program.n, если смотреть его вьером Тотал Командера или редактором Scintila:
fsm.NewDialog =  ()  => MessageBox.Show("Новый файл", "Новый файл", MessageBoxButtons.OKCancel) == DialogResult.OK;
fsm.OpenFileAction =  file => MessageBox.Show($"Открытие файла $file", "Открытие файла", MessageBoxButtons.OKCancel) == DialogResult.OK;
fsm.SaveFileAction =  file => MessageBox.Show($"Файл $file сохранен", "Сохранение файла", MessageBoxButtons.OKCancel) == DialogResult.OK;
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: библиотека автоматов состояний Nemerle.Statechart
От: CodingUnit Россия  
Дата: 12.08.11 10:58
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, CodingUnit, Вы писали:


CU>>Создал пул реквест с новыми фичами, реализовал:


CU>>- поддержку do активности в состоянии на базе Task из .net 4

CU>>- разные флаги к этой фиче чтобы можно было настраивать
CU>>- terminate узел (см. описание Terminate)
CU>>- провел некоторые оптимизации в анализаторе и генераторе, убрал обработчики действий в соотв. им вх/вых действия
CU>>- сделал пример с gui для работы с файлами

VD>Надо бы доперевести все комментарии и русскоязычные названия методов на английский.

хорошо сделаю

CU>>ЗЫ: Если вы вклинитесь в теорию диаграмм состояний, то вам будет очень просто решать сложные задачи. Надеюсь эта библиотека поможет эффективно вам решить их.


VD>В наше время мало придумать хорошую идею. И даже мало ее хорошо реализовать. (особенно если идея не тривиальная)

VD>Нужно еще ее хорошенько подать.

VD>По-моему для данного проекта нужно написать хорошую статью описывающую библиотеку и демонстрирующую примеры ее использования.

VD>Под "хорошей" я понимаю:
VD>1. Внятную.
VD>2. Доступную для чтения непосвященным читателям.
VD>3. Изобилующую простыми, короткими и понятными примерами.
VD>4. Не затянутую и не скучную.

VD>Собственно, если такая статья будет, то мы с удовольствием опубликуем ее на www.rsdn.ru и в RSDN Magazine (русскую весрию). И если, будет английская версия, то еще и на www.nemerle.org (а можно еще и на www.codeproject.com).


Это интересная идея, попробую это сделать когда реализую главную фичу, параллельные состояния, тогда будет о чем сказать и серьезно конкурировать с другими библиотеками.
Re[11]: библиотека автоматов состояний Nemerle.Statechart
От: CodingUnit Россия  
Дата: 12.08.11 11:53
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, CodingUnit, Вы писали:


CU>>К сожалению показать как это все работает в реальном времени не представляется возможнным (нужен прибор и программа),


VD>Ну, почему же? Показать очень даже можно. Для этого нужно всего лишь записать скрин-каст. Для этого есть ряд программ которые ищутся в гугле (или на торрентах ).

VD>Результатом будет авишник демонстрирующий поведение интерфейса и объяснение автора.

попробую это сделать как буду на работе...


VD>А нельзя ли как-то соединить конечные автоматы и реактивный пользовательский интерфейс чтобы вообще не писать код для UI?

VD>Ну, скажем прямо в автомат ввести описание контролов для WPF/WinForms. Или еще как-то.
VD>На мой взгляд — это могло бы оказаться очень востребовано.

наверное можно, хотя конечно автомат дает абстрагирование компонента автомата от реализации, через события, автомат может подключаться к разным реализациям интерфейса и технологиям вывода и использоваться с разными объектами программы. Хотя можно наверное совместить автомат с формой, наследовав класс автомата от формы. При этом то что обычно делается в отдельном классе как соединение формы с автоматом (см. Program.n в GuiFileFsm) то есть присоединие обработчиков можно ввести в описании автомата в метаатрибуте, для этого можно придумать синтаксис. С wpf не знаю, я не очень разбираюсь в его архитектуре, может мудрецы что нибудь посоветуют?

CU>>И на отладку этого дела я потратил очень малое время,вся отладка сводилась к правильному пониманию диаграммы и введения ее соответствия в коде, чтобы все обработчики были подключены и запускали нужные действия.


Мало того, после этого код очень надежен, уровень качества приложения очень высок, уж в каких ситуациях программа не бывала, но за счет автоматизма очень надежно себя ведет, никаких ошибок не возникало, только к модулям которые не относятся к автомату.

VD>На счет диаграммы... На чем ты ее рисуешь? И возможно ли автоматически строить описание на немерле по таким диаграммам? А то получается лишнее действие — переписывание диаграмм в код. По сути ведь код — это другое представление для диаграмм (а диаграммы для кода). Можно рассматривать запись диаграммы в код как сериализацию диаграммы.


Есть редактор UML Sparx Enterprise Architect Proffesional, я пользуюсь им, он может генерить стандартный XMI, тот же XML,
вот файл здесь
Я вообще планировал автоматический импорт из диаграммы через xml. Только думаю как лучше сделать, может быть сначала преобразовать в стандарт Statechart Xml который тоже планировалось импортировать, через какую нибудь трансформацию, чтение напрямую наверное нетривиально даже через Linq to xml.

CU>>При этом возможности приложения последовательно наращиваются, сначала не было истории, появилась, потом добавляется состояние FlashWorking которого не было, и так

VD>далее, все это довольно легко расширяемо и быстро перенастраивается.

VD>Ага. Но не хватает прямой связи с GUI-ём.


VD>А если бы можно было бы описать связь с контралами прямо в диаграмме и сделать сериализацию прямо в код, то вообще было бы идеально!


наверное можно для этого часть можно описать через спец. синтаксис присоединения к обработчикам и установки свойств, часть написать в виде действий в теле класса

VD>Это здорово, но лучше делать это в отдельной статье (а то и в серии статей). А то ветка эта со временем затеряется и мало кто про нее вспомнит. А найти ее будет не так то и просто.

VD>Так что предлагаю скачать с нашего сайта ... и писать уже в нем.
тут наверное какое то нехорошее слово было ^^ или какой то софт который нужен для написания. В чем ее надо писать для рсдн?

VD>Еще раз настоятельно прошу перевести весь русский в коде на английский. И если вдруг в файле появляется русский, то его обязательно нужно сохранять в виде UTF-8 с BOM. Иначе многие текстовые редакторы и вьюеры вместо русского будут показывать абракадабру. Например, вот что отображается в файле


даже не знаю как это могло получиться без BOM, я вроде ничего не менял, глюк... но исправил.

В этот раз очерчу возможности библиотеки и поговорю об ограничениях, для чего же может использоваться библиотека.
Как я говорил основное назначение ввести абстракцию поведения в автомат и использовать его как компонент внутри приложения, при этом хорошо можно описывать логику графический интерфейса, модели реальный и виртуальных объектов, разные протоколы типа Tcp/Ip, Modbus которые не совсем просты, пишутся на автоматах. Автоматизация поведения классов.

При этом структура автомата должна быть статической то есть известна на этапе компиляции, что то добавить в рантайме сейчас нельзя, хотя такие автоматы я не встречал и не знаю как их строить в реальных задачах, другие библиотеки дают возможность добавлять что то в рантайме, но за счет этого они очень медленны, я показал в тестах сравнение двух библиотек, посылал 50000 событий в мой и аналогичный автомат на другой библиотеке разница по времени обработки составила больше 7 раз. Когда обычный применением автоматов явлется их статическое описание, которое надо обрабатывать на этапе компиляции. Может быть можно реализовать автомат и динамический но делать это специальным синтаксисом, чтобы это не было по умолчанию потому что эта задача не стандартная.
Применять автомат как он применяется например в Nemerle.Peg нельзя, там автомат строится во времени работы макроса, там он именно динамический, библиотека же работает по статичному описанию.

Сейчас автомат работает через виртуальные функции и строит для каждого состояния свой класс, это хорошо для больших иерархических автоматов, но может быть не совсем удобно для маленьких плоских автоматов, которые например в yield генерируются через switch, но это вопрос реализации думаю можно провести специальную оптимизацию для плоских автоматов и строить их через match прямо в теле метода запуска события.
Еще думал надо провести оптимизацию чтобы вынести повторяющиеся последовательности действий (в разных методах), в свой метод, такие могут иметь место, но думаю как реализовать такой алгоритм, нужно как то найти повторения как это обычно делает программист во время рефакторинга и выделяет для них свой метод?

Еще есть один нюанс реализации, как определять в каком состоянии находится автомат, сначала я строил их на наследовании и тогда можно через is узнать какой тип имеет текущее состояние, включая родители. Но потом понял что лучше делать на вариантах при этом наследования не будет, тогда какому состоянию принадлежит текущее можно узнавать через битовую маску, идентификатор который присваивается каждому состоянию. Каждое состояние имеет свой независимый установленный бит, внутреннее состояние имеет свой бит и установленные все от родительских состояний, тогда если например
на вложенном Stop из предыдущего примера провести & с состоянием которое тестируется, то есть:


state Test
{
 id = 0b0001;

 state Sub1
 {
  id = 0b0011;
 }

 state Sub2
 {
   id = 0b0101;

   state Sub3
   {
     id = 0b1101;
   }
 }
}

тогда IsInState(st : State) : bool
      {
        (cur_state.get_id() & st.get_id()) == st.get_id()
      }

дает res для следующих комбинаций:
cur_state | test | res
Sub1 Test true
Sub2 Test true
Sub1 Sub2 false
Sub3 Sub2 true
Sub1 Sub3 false
Sub3 Test true


но при этом так как для каждого состояния определяется свой бит, то в uint вмещается 32 состояния максимум, в ulong 64, для большего количества идентификатор надо составлять из структуры и классов с полями int и хранить их как идентификатор. Может быть существует другой целочисленный метод определения через какие нибудь хэш коды, является ли текущее состояние тестовым, которое может быть и родителем его?

Еще вопрос было бы хорошо встроить определение ошибок как в в Peg чтобы например был автоматический переход к строчке где в автомате присутствует ошибка, как это сделать?
Re[12]: библиотека автоматов состояний Nemerle.Statechart
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.08.11 14:15
Оценка:
Здравствуйте, CodingUnit, Вы писали:

Не надо так много цитировать.

CU>Это интересная идея, попробую это сделать когда реализую главную фичу, параллельные состояния, тогда будет о чем сказать и серьезно конкурировать с другими библиотеками.


Что до параллельных состояний, то думаю, что интересным будет не только реализация этого дела на разных потоках, но и реализация на базе кооперативной многозадачности. Ведь многие автоматы отрабатывают по сообщению и засыпают до следующего сообщения. Возможно имеет смысл реализовать подобный сценарий. Создать единую очередь сообщений для автоматов и разбирать ее в общем цикле, передавая сообщения соответствующим автоматам.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: проблема с билдом в VS2010
От: russianfacepalm  
Дата: 12.08.11 14:19
Оценка:
Можно мне тоже вопрос про билд версии для 4-го Framework'а?
Пытался собрать вчера, вечно падало на сборке интеграции.

Ругалось, что не хватает Microsoft.VisualStudio.Web.

Я когда ставил студию, выбрал только нужные компоненты, и не выбирал инструменты для Web разработки. Когда ставил SP1 и SDK, те, очевидно, не добавляли компоненты для Web'а, и в итоге я не смог сбилдить проект.

Вопрос: используется ли где-нибудь в интеграции сабжевый неймспейс?
Re[12]: библиотека автоматов состояний Nemerle.Statechart
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.08.11 15:17
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>наверное можно, хотя конечно автомат дает абстрагирование компонента автомата от реализации, через события, автомат может подключаться к разным реализациям интерфейса и технологиям вывода и использоваться с разными объектами программы. Хотя можно наверное совместить автомат с формой, наследовав класс автомата от формы. При этом то что обычно делается в отдельном классе как соединение формы с автоматом (см. Program.n в GuiFileFsm) то есть присоединие обработчиков можно ввести в описании автомата в метаатрибуте, для этого можно придумать синтаксис.


Можно еще подумать о реализации некоторого WinForms-контрола который бы соединял отдельно описанный автомат с формой. Кидаешь такой контрол на форму. Выбираешь в свойствах автомат... А далее у контролов появляются виртуальные свойства связанные с автоматом (как, например, у контрола ToolTip). Настройка этих свойств и будет задавать нужные обработчики событий.

Еще можно подумать над интеграцией с биндингом WinForms. Он несколько убог, но возможно из этого что-то выйдет. Тогда вообще можно было бы обходиться почти без программирования на уровне GUI.

CU>С wpf не знаю, я не очень разбираюсь в его архитектуре, может мудрецы что нибудь посоветуют?


WPF основан на реактивной модели. Биндинг в нем — это основной способ связи GUI и логики приложения. В WPF используется паттерн MVVM. В этом паттерне состояние "формы" ассоциируется со специальным объектом — модель представления. Почитай о нем. Ведь по сути автомат может и быть таким объектом.

CU>Мало того, после этого код очень надежен, уровень качества приложения очень высок, уж в каких ситуациях программа не бывала, но за счет автоматизма очень надежно себя ведет, никаких ошибок не возникало, только к модулям которые не относятся к автомату.


Ну, MVVM в не очень сложных случаях ведет себя тоже надежно. Кроме того для него не нужно рисовать диаграм и т.п. Почитай об этом паттерне. Возможно получится совместить его и автоматный подход.

VD>>На счет диаграммы... На чем ты ее рисуешь? И возможно ли автоматически строить описание на немерле по таким диаграммам? А то получается лишнее действие — переписывание диаграмм в код. По сути ведь код — это другое представление для диаграмм (а диаграммы для кода). Можно рассматривать запись диаграммы в код как сериализацию диаграммы.


CU>Есть редактор UML Sparx Enterprise Architect Proffesional, я пользуюсь им, он может генерить стандартный XMI, тот же XML,

CU>вот файл здесь

Это хорошо. Только лучше пользоваться простым zip-ом. А то не у всех установлен rar или 7z. А серьезной экономии это все равно не даст.

CU>Я вообще планировал автоматический импорт из диаграммы через xml. Только думаю как лучше сделать, может быть сначала преобразовать в стандарт Statechart Xml который тоже планировалось импортировать, через какую нибудь трансформацию, чтение напрямую наверное нетривиально даже через Linq to xml.


Если Statechart Xml — это общепризнанный стандарт, то правильным подходом было бы трансформировать этот доморощенный формат в Statechart Xml с помощью XSLT, а потом уже написать с помощь XLinq (Linq to xml) чтение этого формата.

Код чтения Statechart Xml можно оформить в качестве отдельного макроса. Сделать это совсем не сложно. В качестве примеров могут служить макросы Resource и Settings.
Это позволит автоматически обновлять код при изменении xml-файла.

VD>>А если бы можно было бы описать связь с контралами прямо в диаграмме и сделать сериализацию прямо в код, то вообще было бы идеально!

CU>наверное можно для этого часть можно описать через спец. синтаксис присоединения к обработчикам и установки свойств, часть написать в виде действий в теле класса

+1. Но можно и с помощью внешнего контрола, как я описал выше.

VD>>Так что предлагаю скачать с нашего сайта ... и писать уже в нем.

CU>тут наверное какое то нехорошее слово было ^^ или какой то софт который нужен для написания. В чем ее надо писать для рсдн?

Я хотел дать ссылку на RSDN Authoring Pack
Автор(ы): Брусенцев Виталий, Чистяков Владислав Юрьевич
Дата: 22.06.2011
Статья описывает шаблон для Microsoft Word предназначенный для верстки статей и преобразования их в формат RSDN ML. В статье рассматриваются вопросы использования шаблона.
, но забыл.

CU>В этот раз очерчу возможности библиотеки и поговорю об ограничениях, для чего же может использоваться библиотека.


Боюсь, что до этой ветки мало кто дочитает. Еще раз советую оформить все в виде статьи.

CU>...Применять автомат как он применяется например в Nemerle.Peg нельзя, там автомат строится во времени работы макроса, там он именно динамический, библиотека же работает по статичному описанию.


На самом деле граница между "динамическим" и "статическим" очень эфемерна. Nemerle.Peg работает во время компиляции и значит его автомат так же статичен. Просто строится он по другой модели — описанию языка в формате PEG.

Так же не нужно сбрасывать со щитов то, что один макрос может сгенерировать код другого. Это так же придает динамику (в определенном смысле). Так макрос чтения XML-файла может сгенерировать макро-атрибут с описанием автомата.

CU>Сейчас автомат работает через виртуальные функции и строит для каждого состояния свой класс, это хорошо для больших иерархических автоматов, но может быть не совсем удобно для маленьких плоских автоматов, которые например в yield генерируются через switch,


Главное, что это не эффективно. Создание экземпляров сразу же тратит много ресурсов (памяти и процессорного времени). Для того же парсера — это неприемлемая роскошь.

CU>но это вопрос реализации думаю можно провести специальную оптимизацию для плоских автоматов и строить их через match прямо в теле метода запуска события.


+1
Думаю, что это будет очень важно для применений где критична производительность. Плюс это ускорит получаемые автомат еще во много раз. Что опять же будет конкурентным преимуществом.

CU>Еще думал надо провести оптимизацию чтобы вынести повторяющиеся последовательности действий (в разных методах), в свой метод, такие могут иметь место, но думаю как реализовать такой алгоритм, нужно как то найти повторения как это обычно делает программист во время рефакторинга и выделяет для них свой метод?


Думаю, что это не самое актуальное занятие. Хотя макросы позволяют анализировать код. Так что потенциально это возможно.

CU>Еще есть один нюанс реализации, как определять в каком состоянии находится автомат, сначала я строил их на наследовании и тогда можно через is узнать какой тип имеет текущее состояние, включая родители. Но потом понял что лучше делать на вариантах при этом наследования не будет, тогда какому состоянию принадлежит текущее можно узнавать через битовую маску, идентификатор который присваивается каждому состоянию.


Связсь между вариантами и битовыми масками не понял. Варианты в немерле прождают объекты. Если для вхождений не нужно хранить некоторого состояния, то лучше использовать enum-ы. Они представляются целыми типами данных, работа с которым очень быстра.

CU>Каждое состояние имеет свой независимый установленный бит, внутреннее состояние имеет свой бит и установленные все от родительских состояний, тогда если например на вложенном Stop из предыдущего примера провести & с состоянием которое тестируется, то есть:...


С битовыми масками может получиться проблема. Если состояний много, то битовая маска может стать слишком толстой. Хотя битовые операции, несомненно, это самый быстрая реализация.
Мне кажется тут нужно вводить зависимость от количества состояний. Если состояний меньше 64, то использовать битовую маску. Иначе что-то другое.

CU>но при этом так как для каждого состояния определяется свой бит, то в uint вмещается 32 состояния максимум, в ulong 64, для большего количества идентификатор надо составлять из структуры и классов с полями int и хранить их как идентификатор. Может быть существует другой целочисленный метод определения через какие нибудь хэш коды, является ли текущее состояние тестовым, которое может быть и родителем его?


Во-первых, можно иметь несколько битовых переменных. Код проверок генерируется, а значит не беда если будет не самым простым в понимании.

Хэши хорошо работают на огромном числе элементов. Плюс хэш-таблицы потребляют довольно много памяти.

Учитывая что битовые маски для состояний будут заранее известны, можно генерировать весьма эффективный код на базе нескольких битовых полей.

CU>Еще вопрос было бы хорошо встроить определение ошибок как в в Peg чтобы например был автоматический переход к строчке где в автомате присутствует ошибка, как это сделать?


Запоминать местоположения (Location-ы) частей автомата, а при выявлении ошибок вызвать:
Message.Error(Location, "текст сообщения об ошибке");

В стандартной библиотеке макросов, есть уйма примеров этого.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[12]: проблема с билдом в VS2010
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.08.11 15:58
Оценка:
Здравствуйте, russianfacepalm, Вы писали:

R>Ругалось, что не хватает Microsoft.VisualStudio.Web.

R>Вопрос: используется ли где-нибудь в интеграции сабжевый неймспейс?

Естественно. В соответствующих шаблонах проектов и их поддержке.
Вообще-то мог бы просто сделать поиск по файлам.

R>Я когда ставил студию, выбрал только нужные компоненты, и не выбирал инструменты для Web разработки. Когда ставил SP1 и SDK, те, очевидно, не добавляли компоненты для Web'а, и в итоге я не смог сбилдить проект.


Студию лучше ставить всю. Никогда не знаешь, что может понадобиться завтра.
Полная студия 2010 занимает 2.1 Ггб. Еще 0.1 Ггб занимает SDK. Итого 2.2 Ггб. На так уж и много по современным меркам.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: библиотека автоматов состояний Nemerle.Statechart
От: CodingUnit Россия  
Дата: 17.08.11 16:45
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, CodingUnit, Вы писали:



VD>Можно еще подумать о реализации некоторого WinForms-контрола который бы соединял отдельно описанный автомат с формой. Кидаешь такой контрол на форму. Выбираешь в свойствах автомат... А далее у контролов появляются виртуальные свойства связанные с автоматом (как, например, у контрола ToolTip). Настройка этих свойств и будет задавать нужные обработчики событий.


Это интересная идея, стоит написать такой контрол, займусь этим в порядке приоритета очереди...

VD>Еще можно подумать над интеграцией с биндингом WinForms. Он несколько убог, но возможно из этого что-то выйдет. Тогда вообще можно было бы обходиться почти без программирования на уровне GUI.


CU>>С wpf не знаю, я не очень разбираюсь в его архитектуре, может мудрецы что нибудь посоветуют?


VD>WPF основан на реактивной модели. Биндинг в нем — это основной способ связи GUI и логики приложения. В WPF используется паттерн MVVM. В этом паттерне состояние "формы" ассоциируется со специальным объектом — модель представления. Почитай о нем. Ведь по сути автомат может и быть таким объектом.


хорошо почитаю...

CU>>Мало того, после этого код очень надежен, уровень качества приложения очень высок, уж в каких ситуациях программа не бывала, но за счет автоматизма очень надежно себя ведет, никаких ошибок не возникало, только к модулям которые не относятся к автомату.


VD>Ну, MVVM в не очень сложных случаях ведет себя тоже надежно. Кроме того для него не нужно рисовать диаграм и т.п. Почитай об этом паттерне. Возможно получится совместить его и автоматный подход.


Я согласен что в целом системы работают надежнее на современных подходах, но все же цели и возможности автоматов и MVVM разные, MVVM это более интерфейс связи, он позволяет связать свойства формы с объектами, но этого мало. В автоматах я показываю что практически любая сложная логика может быть заменена и упрощена с помощью автомата, MVVM тут будет только мостом чтобы эта логика работала, все же мозги можно сделать качественно в автомате, в MVVM наращивать таким образом логику мы не можем, поскольку она будет навороченная, куча if нет жесткой диаграммы с которой можно свериться как с эталоном, поэтому подходы надо совмещать но не останавливаться на одном

VD>>>На счет диаграммы... На чем ты ее рисуешь? И возможно ли автоматически строить описание на немерле по таким диаграммам? А то получается лишнее действие — переписывание диаграмм в код. По сути ведь код — это другое представление для диаграмм (а диаграммы для кода). Можно рассматривать запись диаграммы в код как сериализацию диаграммы.


CU>>Я вообще планировал автоматический импорт из диаграммы через xml. Только думаю как лучше сделать, может быть сначала преобразовать в стандарт Statechart Xml который тоже планировалось импортировать, через какую нибудь трансформацию, чтение напрямую наверное нетривиально даже через Linq to xml.


VD>Если Statechart Xml — это общепризнанный стандарт, то правильным подходом было бы трансформировать этот доморощенный формат в Statechart Xml с помощью XSLT, а потом уже написать с помощь XLinq (Linq to xml) чтение этого формата.


XMI это тоже стандартный формат, так называемый Diagram Interchange format, но он имеет много специфичных для редактора элементов, которые он может потом импортировать с успехом, но которые нужно просто игнорировать, поэтому лучше его трансформировать

VD>>>А если бы можно было бы описать связь с контралами прямо в диаграмме и сделать сериализацию прямо в код, то вообще было бы идеально!

CU>>наверное можно для этого часть можно описать через спец. синтаксис присоединения к обработчикам и установки свойств, часть написать в виде действий в теле класса

VD>+1. Но можно и с помощью внешнего контрола, как я описал выше.


VD>На самом деле граница между "динамическим" и "статическим" очень эфемерна. Nemerle.Peg работает во время компиляции и значит его автомат так же статичен. Просто строится он по другой модели — описанию языка в формате PEG.


Да и автомат строится несколько по иному в объектном виде и его можно потом анализировать в Peg, в библиотеке же он ориентирован на использование уже в запускаемом виде а не в виде объектного дерева, хотя и оно есть на этапе работы макроса, просто она не задумана пока на такое применение, добавить что то после работы макроса будет невозможно, хотя может быть если найдутся случаи когда это действительно нужно можно сделать какие нибудь динамические таблицы которые будут в реальном времени перестраиваться, но лучше этим не заниматься, обычно статичного описания более чем достаточно

VD>Так же не нужно сбрасывать со щитов то, что один макрос может сгенерировать код другого. Это так же придает динамику (в определенном смысле). Так макрос чтения XML-файла может сгенерировать макро-атрибут с описанием автомата.


В принципе можно создать где нибудь дерево, (для этого правда надо будет его открыть для внешнего кода) и подавать его напрямую в компилятор автоматов, который его может анализировать и генерировать, если продумать как его можно будет при этом использовать то можно добавить какие нибудь функции для работы в таком виде

CU>>Сейчас автомат работает через виртуальные функции и строит для каждого состояния свой класс, это хорошо для больших иерархических автоматов, но может быть не совсем удобно для маленьких плоских автоматов, которые например в yield генерируются через switch,


VD>Главное, что это не эффективно. Создание экземпляров сразу же тратит много ресурсов (памяти и процессорного времени). Для того же парсера — это неприемлемая роскошь.


экземпляры создаются только один раз при создании автомата и хранятся в единичном экземпляре в полях, ведь их конечное множество, при переходе в состояние просто выдается ссылка на объект который был создан однажды, к тому же состояния являются вариантами и оптимизируются через константный объект при создании экземпляров компилятором (спасибо за статью в которой описывается эта возможность вариантов)

CU>>но это вопрос реализации думаю можно провести специальную оптимизацию для плоских автоматов и строить их через match прямо в теле метода запуска события.


VD>+1

VD>Думаю, что это будет очень важно для применений где критична производительность. Плюс это ускорит получаемые автомат еще во много раз. Что опять же будет конкурентным преимуществом.

Вполне возможно даст некоторый прирост но не существенный, виртуальные функции это просто вызов через указатель в таблице, от match с множеством case это не сильно отличается

CU>>Еще думал надо провести оптимизацию чтобы вынести повторяющиеся последовательности действий (в разных методах), в свой метод, такие могут иметь место, но думаю как реализовать такой алгоритм, нужно как то найти повторения как это обычно делает программист во время рефакторинга и выделяет для них свой метод?


VD>Думаю, что это не самое актуальное занятие. Хотя макросы позволяют анализировать код. Так что потенциально это возможно.


CU>>Еще есть один нюанс реализации, как определять в каком состоянии находится автомат, сначала я строил их на наследовании и тогда можно через is узнать какой тип имеет текущее состояние, включая родители. Но потом понял что лучше делать на вариантах при этом наследования не будет, тогда какому состоянию принадлежит текущее можно узнавать через битовую маску, идентификатор который присваивается каждому состоянию.


VD>Связсь между вариантами и битовыми масками не понял. Варианты в немерле прождают объекты. Если для вхождений не нужно хранить некоторого состояния, то лучше использовать enum-ы. Они представляются целыми типами данных, работа с которым очень быстра.


нет пока нужны именно объекты, просто сначала можно было определить что класс является типом или его потомком через наследование, но это возможно только без вариантов, с вариантами конечно лучше, потому что они оптимизируются и использовать их проще, но тогда нужны битовые маски в принципе выйти за 32 или 64 состояния очень непросто, это какие то ультра применения

VD>С битовыми масками может получиться проблема. Если состояний много, то битовая маска может стать слишком толстой. Хотя битовые операции, несомненно, это самый быстрая реализация.

VD>Мне кажется тут нужно вводить зависимость от количества состояний. Если состояний меньше 64, то использовать битовую маску. Иначе что-то другое.

именно так сейчас я и делаю, сначала long потом структура из нескольких int потом классы с множеством полей int

я смотрел книгу "алгоритмические трюки" каких только там изворотов нет с битами, может есть алгоритм и для такой операции эффективный, мне самый простой пришел в голову

CU>>Еще вопрос было бы хорошо встроить определение ошибок как в в Peg чтобы например был автоматический переход к строчке где в автомате присутствует ошибка, как это сделать?


VD>Запоминать местоположения (Location-ы) частей автомата, а при выявлении ошибок вызвать:

VD>
VD>Message.Error(Location, "текст сообщения об ошибке");
VD>

VD>В стандартной библиотеке макросов, есть уйма примеров этого.

а переход к коду в автомате как сделать, в вышеприведенном коде как я понимаю высвечиться ошибка, в заголовке но не будет переход к ней?
nemerle.statechart
Re[3]: [Nemerle.Statechart] примеры и описания
От: FDSC Россия consp11.github.io блог
Дата: 23.08.11 18:42
Оценка:
Здравствуйте, CodingUnit

Ты не мог бы пояснять обозначения на схемах, а то написано много, а понять ничего не возможно, и что это за стандарт такой и где взять его описание (жел., на русском) то же.
Re[5]: [Nemerle.Statechart] примеры и описания
От: FDSC Россия consp11.github.io блог
Дата: 24.08.11 14:15
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>Если что задавай вопросы, отвечу.


Спасибо, стало значительно понятней. Есть одно замечание: не хватает описания тех простейших схем, приведённых тобой в диаграммах, в твоём синтаксисе рядом со схемами — чтобы можно было просто сравнить схему и её описание. Очень трудно в итоге их сличать. Если пишешь документацию, лучше чтобы они были рядом.

Кроме этого, совершенно непонятно, что за строка

Extern => Lab2 TermProject FinalTest; // разделение fork переход сразу в три состояния

На диаграмме такой нет. Видимо, здесь ошибка, нужно:

Extern => Lab1 TermProject FinalTest;


Непонятно, почему есть
initial => FinalTest;

но нет таких же в других параллельных состояниях

Не понятно, что будет с автоматом, если в него вошли заново: можно ли его преднамеренно оставить в том же состоянии, можно ли его преднамеренно сбросить. Можно ли определить метку, двигающуюся по автомату, можно ли определить стандартный подавтомат, который будет работать по одной и той же схеме на части вершин (например, показывать состояние однотипных подпроцессов: автомат утверждения договора в одной фирме может быть использован два раза в автомате общего утверждения договора между двумя фирмами; интересно, возможно ли это нормально смоделировать, если фирм заранее неизвестное количество, т.е. имеется неизвестное количество однотипных параллельных процессов).


P.S. Вообще, стрелки => кажутся для этого синтаксиса лишними, хотя, может быть, на сложных автоматах это уже не так.
P.P.S. Честно говоря, довольно жутко выглядят подавтоматы, которые используют систему гобальную имён. Не поймёшь по ним, это переход на состояние во-вне, или переход на состояние подавтомата.
Re[6]: [Nemerle.Statechart] примеры и описания
От: CodingUnit Россия  
Дата: 24.08.11 14:59
Оценка:
Здравствуйте, FDSC, Вы писали:

FDS>Здравствуйте, CodingUnit, Вы писали:


CU>>Если что задавай вопросы, отвечу.


FDS>Спасибо, стало значительно понятней. Есть одно замечание: не хватает описания тех простейших схем, приведённых тобой в диаграммах, в твоём синтаксисе рядом со схемами — чтобы можно было просто сравнить схему и её описание. Очень трудно в итоге их сличать. Если пишешь документацию, лучше чтобы они были рядом.


FDS>Кроме этого, совершенно непонятно, что за строка


FDS>Extern => Lab2 TermProject FinalTest; // разделение fork переход сразу в три состояния


Это событие я добавил, вот здесь описал:

тут довавил fork переход в диаграмме обучения сразу в три состояния ко 2й лабораторке для определенного студента и выход из первых лабороторок, если студент выбыл.


FDS>На диаграмме такой нет. Видимо, здесь ошибка, нужно:


FDS>Extern => Lab1 TermProject FinalTest;


нет все верно, Extern — это событие если студент экстерном хочет сдать все сразу, и переходит ко 2й, смысл здесь лишь в том как работает fork псевдосостояние, оно дает вход в любые состояния в разных регионах параллельного состояния, это его синтаксис, то есть переход в несколько.


FDS>Непонятно, почему есть

FDS>initial => FinalTest;

Здесь показан альтернативный синтаксис для определения начального перехода, он может быть 0 => state или initial =>, есть мысли о другом синтаксисе?

FDS>но нет таких же в других параллельных состояниях


нет потому что здесь я явно указал куда хочу сделать переход, а в остальных случаях они определяются автоматически через флаг в начале описания автомата

flags : auto_initial;



FDS>Не понятно, что будет с автоматом, если в него вошли заново:

такого не бывает, система находится в одном из состояний, начинает жить от некоего начального и продолжает в других, изменение состояния связано только с переходом как реакция на событие, других входов в состояние быть не может, такова абстракция, если автомат инициализируется заново, то должен входить в свое начальное состояние, состояние может переходить само в себя

FDS>можно ли его преднамеренно оставить в том же состоянии, можно ли его преднамеренно сбросить.

он остается всегда в каком то состоянии, сбрасывать автомат нет смысла, он просто должен жить, если сбросить, то его надо будет инициализировать, при этом он начнет жить с начального состояния как я сказал выше

FDS>Можно ли определить метку, двигающуюся по автомату,

для чего и что это за метка такая, как она должна выглядеть? автомат и так имеет текущее состояние это и есть метка, в параллельном состоянии их несколько, если нужно продумать автомат как он живет, это можно сделать на рисунках и помечать как нужно, есть неплохие редакторы советую Sparx Enterprise Architect (платный) и Visual Paradigm for UML (есть Community Edition)

FDS>можно ли определить стандартный подавтомат, который будет работать по одной и той же схеме на части вершин (например, показывать состояние однотипных подпроцессов: автомат утверждения договора в одной фирме может быть использован два раза в автомате общего утверждения договора между двумя фирмами; интересно, возможно ли это нормально смоделировать, если фирм заранее неизвестное количество, т.е. имеется неизвестное количество однотипных параллельных процессов).

если неизвестное количество, то здесь речь идет о динамическом автомате, структура которого неизвестна на этапе компиляции, библиотека расчитана на статичные описания автоматов, динамически расширяемые я пока не планировал создавать, но в принципе если найдутся подобные применения, может стоит подумать как их сделать. Стандартные подавтоматы переиспользуемые в другом, я планировал сделать

FDS>P.S. Вообще, стрелки => кажутся для этого синтаксиса лишними, хотя, может быть, на сложных автоматах это уже не так.

Эти стрелки необходимы, поскольку парсеру требуется узнать где заканчивается список событий и где начинается обозначение конца перехода, событий может быть несколько, также там могут быть сторожевые условия и действия при переходе, которых может быть несколько, для этого парсеру обязательно нужен спец. разделитель

FDS>P.P.S. Честно говоря, довольно жутко выглядят подавтоматы, которые используют систему гобальную имён. Не поймёшь по ним, это переход на состояние во-вне, или переход на состояние подавтомата.

У тебя есть мысли как это сделать лучше? глобальные имена используются и в языках на которых мы пишем, можно конечно использовать и прямую спецификацию имени, чтобы уточнить путь, это поддерживается например можно написать так A.B это будет обозначение подсостояния B в A
Re[7]: [Nemerle.Statechart] примеры и описания
От: FDSC Россия consp11.github.io блог
Дата: 24.08.11 15:33
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>нет все верно, Extern — это событие если студент экстерном хочет сдать все сразу, и переходит ко 2й, смысл здесь лишь в том как работает fork псевдосостояние, оно дает вход в любые состояния в разных регионах параллельного состояния, это его синтаксис, то есть переход в несколько.


Тогда надо его указывать на диаграмме, чтобы было стопроцентрое соответствие: иначе пример бесполезен.


FDS>>Непонятно, почему есть

FDS>>initial => FinalTest;

CU>Здесь показан альтернативный синтаксис для определения начального перехода, он может быть 0 => state или initial =>, есть мысли о другом синтаксисе?


Дело в том, что переход осуществляется только для FinalTest, а лабораторные работы не инициализируются. Вопрос в этом. А синтаксис, честно говоря, я бы вообще другой сделал бы Так что не в этом дело.

FDS>>но нет таких же в других параллельных состояниях


CU>нет потому что здесь я явно указал куда хочу сделать переход, а в остальных случаях они определяются автоматически через флаг в начале описания автомата

CU>

CU>flags : auto_initial;


Опять же, с точки зрения обучения нужно или и там и там использовать флаги, или и там, и там ставить всё вручную (или комментировать не обязательный код, если хочешь показать, что он могу бы быть, но не нужен)

Про запомненное состояние автомата я неверно спросил.
Верно как-то так: можно ли в автомат переходить не в состояние, а посылать ему сигнал? Т.е. переходим в сам автомат, находящийся в некотором состоянии (последнее, из которого он вышел вовне) и у него сразу же какое-то событие случается? (применений не знаю, просто интересно можно или нет)

FDS>>Можно ли определить метку, двигающуюся по автомату,

CU>для чего и что это за метка такая, как она должна выглядеть? автомат и так имеет текущее состояние это и есть метка

Да нет. Представь себе, что это что-то типа сети петри: если метка есть, переход в одно состоянии при некотором сигнале, если метки нет — то и переход в другое состояние или перехода нет (ну, это я просто спрашиваю, грубо говоря, как раз на счёт того, только ли это конечный автомат).

CU>если неизвестное количество, то здесь речь идет о динамическом автомате, структура которого неизвестна на этапе компиляции, библиотека расчитана на статичные описания автоматов, динамически расширяемые я пока не планировал создавать, но в принципе если найдутся подобные применения, может стоит подумать как их сделать. Стандартные подавтоматы переиспользуемые в другом, я планировал сделать


Понял, спасибо. Я просто для интереса спросил, чтобы понять, что можно, а что нет.

FDS>>P.P.S. Честно говоря, довольно жутко выглядят подавтоматы, которые используют систему гобальную имён. Не поймёшь по ним, это переход на состояние во-вне, или переход на состояние подавтомата.

CU>У тебя есть мысли как это сделать лучше? глобальные имена используются и в языках на которых мы пишем, можно конечно использовать и прямую спецификацию имени, чтобы уточнить путь, это поддерживается например можно написать так A.B это будет обозначение подсостояния B в A

Ну, лично мое мнение, не претендую на верность совершенно, что лучше выглядело бы так

state TakingClass
{
Extern => Incomplete.Lab2 Incomplete.TermProject Incomplete.FinalTest;
=> Incomplete; // переход из ничего — инициализация

state Incomplete
{
_ =>> Passed; // обозначаем для невнимательных, что здесь переход идёт вовне
=> Lab1 TermProject FinalTest;

[----------] // лишняя граница, т.к. "_" работает синхронно

state Lab1
{
lab_done => Lab2;
}

extern state Lab2
{
lab_done => ;
}

[----------]

state TermProject
{
project_done => ;
}

[----------]
state FinalTest
{
pass => ;
fail =>> Failed; // переход во вне
}
}

state Passed
{
}

state Failed
{
}
}

А если бы при этом ещё и был indentation-синтаксис — было бы вообще прекрасно. Но это чисто моё мнение, мне автоматы очень редко надобятся.
Re[8]: [Nemerle.Statechart] примеры и описания
От: CodingUnit Россия  
Дата: 24.08.11 15:58
Оценка:
Здравствуйте, FDSC, Вы писали:

FDS>Здравствуйте, CodingUnit, Вы писали:


CU>>нет все верно, Extern — это событие если студент экстерном хочет сдать все сразу, и переходит ко 2й, смысл здесь лишь в том как работает fork псевдосостояние, оно дает вход в любые состояния в разных регионах параллельного состояния, это его синтаксис, то есть переход в несколько.


FDS>Тогда надо его указывать на диаграмме, чтобы было стопроцентрое соответствие: иначе пример бесполезен.


на диаграмме не стал, потому что пример взят из справочника, как картинка, перерисовывать я не стал, а добавить переход хотел

FDS>>>Непонятно, почему есть

FDS>>>initial => FinalTest;

FDS>Дело в том, что переход осуществляется только для FinalTest, а лабораторные работы не инициализируются. Вопрос в этом. А синтаксис, честно говоря, я бы вообще другой сделал бы Так что не в этом дело.

там работает auto_initial, если указан явный то auto_initial пропускает его и оставляет какой есть

FDS>>>но нет таких же в других параллельных состояниях


CU>>нет потому что здесь я явно указал куда хочу сделать переход, а в остальных случаях они определяются автоматически через флаг в начале описания автомата

CU>>

CU>>flags : auto_initial;


FDS>Опять же, с точки зрения обучения нужно или и там и там использовать флаги, или и там, и там ставить всё вручную (или комментировать не обязательный код, если хочешь показать, что он могу бы быть, но не нужен)

я просто показал разные варианты применения

FDS>Про запомненное состояние автомата я неверно спросил.

FDS>Верно как-то так: можно ли в автомат переходить не в состояние, а посылать ему сигнал? Т.е. переходим в сам автомат, находящийся в некотором состоянии (последнее, из которого он вышел вовне) и у него сразу же какое-то событие случается? (применений не знаю, просто интересно можно или нет)
это возможно через действия, смотри предыдущие сообщения, при входе в состояние оно может запускать действие, которое посылает в автомат событие, хотя сейчас события синхронны и если запустить событие когда он еще осуществляет переход, то он сначала будет реагировать на это событие, а потом завершит переход в состояние, то есть получится не совсем что нужно, для этого наверное надо делать очередь асинхронных событий, это я тоже планировал и посылать их так

FDS>>>Можно ли определить метку, двигающуюся по автомату,

CU>>для чего и что это за метка такая, как она должна выглядеть? автомат и так имеет текущее состояние это и есть метка

FDS>Да нет. Представь себе, что это что-то типа сети петри: если метка есть, переход в одно состоянии при некотором сигнале, если метки нет — то и переход в другое состояние или перехода нет (ну, это я просто спрашиваю, грубо говоря, как раз на счёт того, только ли это конечный автомат).

я в сетях петри не разбираюсь, в семантике UML есть псевдосостояния, которые реализуют похожее поведение, есть synch псевдосостояние, которое ожидает некое количество переходов в себя и только после этого осуществляет переход, есть choice и junction, они осуществляют динамический и статический выбор пути перехода в зависимости от условий, только то что есть в семантике автомата UML я собираюсь реализовывать

CU>>У тебя есть мысли как это сделать лучше? глобальные имена используются и в языках на которых мы пишем, можно конечно использовать и прямую спецификацию имени, чтобы уточнить путь, это поддерживается например можно написать так A.B это будет обозначение подсостояния B в A


FDS>Ну, лично мое мнение, не претендую на верность совершенно, что лучше выглядело бы так


FDS>state TakingClass

FDS>{
FDS> Extern => Incomplete.Lab2 Incomplete.TermProject Incomplete.FinalTest;
FDS> => Incomplete; // переход из ничего — инициализация

синтаксис с Incomplete разрастается и выглядит больно наворочено на глаз, кто пишет код из диаграммы разве не поймет какое состояние он хочет указать? без прямой спецификации

FDS> state Incomplete

FDS> {
FDS> _ =>> Passed; // обозначаем для невнимательных, что здесь переход идёт вовне
разный синтаксис для типов переходов возможен, я думал делать local и external переходы с разным синтаксисом, думаю можно сделать синтаксис чтобы явно указывать куда переход во вне или внутри состояния, тогда это будет еще дополнительная проверка на правильность если состояние окажется не тем куда задумывался переход

FDS> => Lab1 TermProject FinalTest;

здесь не понял откуда предполагается fork переход, он уже есть во вне из того состояния внутрь параллельного, это дупликация


FDS> [----------] // лишняя граница, т.к. "_" работает синхронно


FDS> state Lab1

FDS> {
FDS> lab_done => Lab2;
FDS> }

FDS> extern state Lab2

FDS> {
FDS> lab_done => ;
FDS> }
по моему не очевидно, цель перехода должна быть указана явно, иначе это может быть ошибкой, переход может быть не только в конечные состояния, но
и в другие типы псевдосостояний, например H (для history) и остальные, и => без конца может дать проблему в парсере

FDS> [----------]


FDS> state TermProject

FDS> {
FDS> project_done => ;
FDS> }

FDS> [----------]

FDS> state FinalTest
FDS> {
FDS> pass => ;
FDS> fail =>> Failed; // переход во вне
FDS> }
FDS> }

FDS> state Passed

FDS> {
FDS> }

FDS> state Failed

FDS> {
FDS> }
FDS>}

FDS>А если бы при этом ещё и был indentation-синтаксис — было бы вообще прекрасно. Но это чисто моё мнение, мне автоматы очень редко надобятся.

можно подумать про indentation
Re[9]: [Nemerle.Statechart] примеры и описания
От: FDSC Россия consp11.github.io блог
Дата: 24.08.11 17:00
Оценка:
Здравствуйте, CodingUnit, Вы писали:

FDS>>Опять же, с точки зрения обучения нужно или и там и там использовать флаги, или и там, и там ставить всё вручную (или комментировать не обязательный код, если хочешь показать, что он могу бы быть, но не нужен)

CU>я просто показал разные варианты применения

Ну вот это плохо, что ты сделал — запутывает. Надо тогда комментировать этот код, что он не обязателен

CU>я в сетях петри не разбираюсь, в семантике UML есть псевдосостояния, которые реализуют похожее поведение, есть synch псевдосостояние, которое ожидает некое количество переходов в себя и только после этого осуществляет переход, есть choice и junction, они осуществляют динамический и статический выбор пути перехода в зависимости от условий, только то что есть в семантике автомата UML я собираюсь реализовывать


Нет, через псевдосостояния я так понимаю это не реализовать.
Грубо говоря, не помешала бы какая-то возможность прикрепить к потоку на графе состояний объект — метку. Я не знаю, сложно ли это сделать, если легко, то лучше сделать, даже если выходит за UML, если сложно, тогда, конечно, увы.

Привожу пример:

Есть автомат из трёх состояний
0 — начальное
если нет метки — перейти по сигналу в 1
если есть метка и она попадает под "условие1", то перейти в 2
иначе — перейти в 3
1
Поставить метку с "условие1"
Перейти в 0 при сигнале
2
Если нет метки — фатальная ошибка
Изменить метку на "условие2"
Перейти в 0 при сигнале

Т.е., грубо говоря, к потоку прикрепляется объект или несколько, которые затем модифицируется (в идеале тут ещё нужны стандартные условия и функции модификации, чтобы можно было просто описывать введённые пользователем понятия, например, количества меток и условия перехода по количеству меток без функций). При этом, идеально, если возможно будет все состояния сделать параллельными. Тогда это уже не просто автомат, но, по-сути, заготовка для сети петри, а то и заодно и сама размеченная сеть петри.


FDS>>state TakingClass

FDS>>{
FDS>> Extern => Incomplete.Lab2 Incomplete.TermProject Incomplete.FinalTest;
FDS>> => Incomplete; // переход из ничего — инициализация

CU>синтаксис с Incomplete разрастается и выглядит больно наворочено на глаз, кто пишет код из диаграммы разве не поймет какое состояние он хочет указать? без прямой спецификации


Диаграммы может и не быть, или она может быть на такая, как программируется автомат. Ты сам ввёл лишний переход, которого не было на диаграмме, что уж говорить о реальном проекте.
С моей точки зрения — лучше навернуть или указать что-то такое
Extern => Incomplete(Lab2 TermProject FinalTest);

Просто если автоматами описывать логику работы, то очень быстро запутаешься, что куда переходит, особенно если не ты этот автомат начинал делать.

FDS>> state Incomplete

FDS>> {
FDS>> _ =>> Passed; // обозначаем для невнимательных, что здесь переход идёт вовне
CU>разный синтаксис для типов переходов возможен, я думал делать local и external переходы с разным синтаксисом, думаю можно сделать синтаксис чтобы явно указывать куда переход во вне или внутри состояния, тогда это будет еще дополнительная проверка на правильность если состояние окажется не тем куда задумывался переход

Ну значит это точно надо, раз мы оба подумали

FDS>> => Lab1 TermProject FinalTest;

CU>здесь не понял откуда предполагается fork переход, он уже есть во вне из того состояния внутрь параллельного, это дупликация

Это явное описание инициализации, т.к. флаг автоматической инициализации я убрал. Т.е. когда мы запишем инициализацию => Incomplete; то эта строка будет указывать как бы состояния по-умолчанию.

CU>по моему не очевидно, цель перехода должна быть указана явно, иначе это может быть ошибкой, переход может быть не только в конечные состояния, но

CU>и в другие типы псевдосостояний, например H (для history) и остальные, и => без конца может дать проблему в парсере

Ну, просто это более долго писать Про проблему в парсере я понимаю, хотя в целом такой переход можно поставить первой веткой выбора, чтобы проблем не было (конечно, если в других ветках не ожидается ";" внутри описания).


FDS>>А если бы при этом ещё и был indentation-синтаксис — было бы вообще прекрасно. Но это чисто моё мнение, мне автоматы очень редко надобятся.

CU>можно подумать про indentation

Было бы очень неплохо. Хотя не знаю, насколько это PEG осилит

Просто тогда это было бы несколько более приятно читать, как мне кажется. Грубо говоря, то, что я хочу, выглядело бы так


state TakingClass
  $0
    Incomplete

  Extern
    Incomplete
      Lab2
      TermProject
      FinalTest

  Incomplete
    _
      Passed:>  // :> - описываем, что это внешний идентификатор
    $0
      Lab1
      TermProject
      FinalTest

    [---]
      Lab1:>  // :> это состояние связано с начальным состоянием автомата
        lab_done здесь можно через пробел и другие состояния указывать
          Lab2
      Lab2:>> // :>> описываем видимость с двойным выходом наружу - на внешний автомат
        lab_done
          $0
    [---]
      TermProject:>
        project_done
          $0
    [---]
      FinalTest
        pass
          $0
        fail
          Failed:>

  Passed

  Failed

Но это, конечно, моё видение.
Re[10]: [Nemerle.Statechart] примеры и описания
От: CodingUnit Россия  
Дата: 24.08.11 17:22
Оценка:
Здравствуйте, FDSC, Вы писали:

FDS>Здравствуйте, CodingUnit, Вы писали:


FDS>Ну вот это плохо, что ты сделал — запутывает. Надо тогда комментировать этот код, что он не обязателен

ну постараюсь исправиться, сам пост вряд ли уже можно отредактировать

CU>>я в сетях петри не разбираюсь, в семантике UML есть псевдосостояния, которые реализуют похожее поведение, есть synch псевдосостояние, которое ожидает некое количество переходов в себя и только после этого осуществляет переход, есть choice и junction, они осуществляют динамический и статический выбор пути перехода в зависимости от условий, только то что есть в семантике автомата UML я собираюсь реализовывать


FDS>Нет, через псевдосостояния я так понимаю это не реализовать.

FDS>Грубо говоря, не помешала бы какая-то возможность прикрепить к потоку на графе состояний объект — метку. Я не знаю, сложно ли это сделать, если легко, то лучше сделать, даже если выходит за UML, если сложно, тогда, конечно, увы.

FDS>Привожу пример:


FDS>Есть автомат из трёх состояний

FDS>0 — начальное
FDS> если нет метки — перейти по сигналу в 1
FDS> если есть метка и она попадает под "условие1", то перейти в 2
FDS> иначе — перейти в 3
FDS>1
FDS> Поставить метку с "условие1"
FDS> Перейти в 0 при сигнале
FDS>2
FDS> Если нет метки — фатальная ошибка
FDS> Изменить метку на "условие2"
FDS> Перейти в 0 при сигнале

тут мне кажется подойдет choice / junction псевдосостояния, они могут иметь прикрепленные сторожевые условия, переход осуществляется туда где условие истинно, к этому условию можно прикрепить что угодно функцию, делегат, главное чтобы отрезок возвращал bool, в этой функции можно делать что угодно и расчитывать пути как вздумается, если эта вещь будет переиспользуемая то можно подумать о введении синтаксиса. Пока это похоже на динамический доступ к переходам, его можно имитировать как я сказал

FDS>Т.е., грубо говоря, к потоку прикрепляется объект или несколько, которые затем модифицируется (в идеале тут ещё нужны стандартные условия и функции модификации, чтобы можно было просто описывать введённые пользователем понятия, например, количества меток и условия перехода по количеству меток без функций). При этом, идеально, если возможно будет все состояния сделать параллельными. Тогда это уже не просто автомат, но, по-сути, заготовка для сети петри, а то и заодно и сама размеченная сеть петри.


в пределах семантики UML я думаю можно сделать довольно много из того что ты сказал, автомат представляет собой класс, поэтому можно переопределять сторожевые условия и события, junction и choice я собирался добавлять, которые также можно будет переопределять в классе

CU>>синтаксис с Incomplete разрастается и выглядит больно наворочено на глаз, кто пишет код из диаграммы разве не поймет какое состояние он хочет указать? без прямой спецификации


FDS>Диаграммы может и не быть, или она может быть на такая, как программируется автомат. Ты сам ввёл лишний переход, которого не было на диаграмме, что уж говорить о реальном проекте.

FDS>С моей точки зрения — лучше навернуть или указать что-то такое
FDS>Extern => Incomplete(Lab2 TermProject FinalTest);
так выглядит лучше, надо подумать про такой синтаксис

FDS>Просто если автоматами описывать логику работы, то очень быстро запутаешься, что куда переходит, особенно если не ты этот автомат начинал делать.


FDS>Ну значит это точно надо, раз мы оба подумали

я пометил себе добавить такую возможность

FDS>>> => Lab1 TermProject FinalTest;

CU>>здесь не понял откуда предполагается fork переход, он уже есть во вне из того состояния внутрь параллельного, это дупликация
у меня в каждом регионе независимое начальное состояние, которое должно указываться там же, эта запись конфликтует с синтаксисом fork перехода

CU>>по моему не очевидно, цель перехода должна быть указана явно, иначе это может быть ошибкой, переход может быть не только в конечные состояния, но

CU>>и в другие типы псевдосостояний, например H (для history) и остальные, и => без конца может дать проблему в парсере

FDS>Ну, просто это более долго писать Про проблему в парсере я понимаю, хотя в целом такой переход можно поставить первой веткой выбора, чтобы проблем не было (конечно, если в других ветках не ожидается ";" внутри описания).

на два символа дольше, но не очевидно куда хотел быть переход, кстати конечные состояния не так часто используются чтобы делать для них такой экстравагантный синтаксис, для final можно сделать синтаксис в один символ, только надо подумать какой выбрать

FDS>>>А если бы при этом ещё и был indentation-синтаксис — было бы вообще прекрасно. Но это чисто моё мнение, мне автоматы очень редко надобятся.

CU>>можно подумать про indentation

FDS>Было бы очень неплохо. Хотя не знаю, насколько это PEG осилит


FDS>Просто тогда это было бы несколько более приятно читать, как мне кажется. Грубо говоря, то, что я хочу, выглядело бы так



FDS>
FDS>state TakingClass
FDS>  $0
FDS>    Incomplete

FDS>  Extern
FDS>    Incomplete
FDS>      Lab2
FDS>      TermProject
FDS>      FinalTest

FDS>  Incomplete
FDS>    _
FDS>      Passed:>  // :> - описываем, что это внешний идентификатор
FDS>    $0
FDS>      Lab1
FDS>      TermProject
FDS>      FinalTest

FDS>    [---]
FDS>      Lab1:>  // :> это состояние связано с начальным состоянием автомата
FDS>        lab_done здесь можно через пробел и другие состояния указывать
FDS>          Lab2
FDS>      Lab2:>> // :>> описываем видимость с двойным выходом наружу - на внешний автомат
FDS>        lab_done
FDS>          $0
FDS>    [---]
FDS>      TermProject:>
FDS>        project_done
FDS>          $0
FDS>    [---]
FDS>      FinalTest
FDS>        pass
FDS>          $0
FDS>        fail
FDS>          Failed:>

FDS>  Passed

FDS>  Failed
FDS>

FDS>Но это, конечно, моё видение.
конечно приятно читать, я пометил сделать такой синтаксис, в парсере по идее не должно быть проблем, надо будет просто потом обрабатывать дерево после парсинга и парсить по другим правилам
Re[11]: [Nemerle.Statechart] примеры и описания
От: FDSC Россия consp11.github.io блог
Дата: 24.08.11 18:16
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>тут мне кажется подойдет choice / junction псевдосостояния, они могут иметь прикрепленные сторожевые условия, переход осуществляется туда где условие истинно, к этому условию можно прикрепить что угодно функцию, делегат, главное чтобы отрезок возвращал bool, в этой функции можно делать что угодно и расчитывать пути как вздумается, если эта вещь будет переиспользуемая то можно подумать о введении синтаксиса. Пока это похоже на динамический доступ к переходам, его можно имитировать как я сказал


Если все состояния сделать параллельными, то не пройдёт, т.к. мы будем иметь автомат с набором состояний, ограниченным не одним из возможных, а всеми из возможных и метка должна будет двигаться по сети, а не быть статической.
Кроме этого, даже если брать один автомат, тогда нужно где-то хранить данные, к нему привязанные. В т.ч. хранить данные для вложенных автоматов.

Вообще, я так подумал, это довольно сложно сделать. По-сути надо тогда синтаксис делать расширяемым, грубо говоря, с возможностью написать нечто типа некоторое_слово[параметры] и затем передать это через рефлексию в функцию с именем некоторое_слово со списком параметров, которые она сама будет парсить. И при этом это уже тогда получается автомат сам, наверное, надо менять, чтобы количество параллельных состояний было ограниченным лишь количеством объявленных состояний.

CU>у меня в каждом регионе независимое начальное состояние, которое должно указываться там же, эта запись конфликтует с синтаксисом fork перехода


Странно, конечное состояние, общее для параллельных регионов, есть, а начального нет... по идее, должно быть такое состояние, а эта запись тогда есть fork-переход из него. Ну раз нет, значит не надо, но вообще, гораздо проще его было бы задать как я написал, чем задавать отдельно вручную для каждого региона (если отключить флаг автоматического определения начального состояния).

CU>на два символа дольше, но не очевидно куда хотел быть переход, кстати конечные состояния не так часто используются чтобы делать для них такой экстравагантный синтаксис, для final можно сделать синтаксис в один символ, только надо подумать какой выбрать


Я так понял, что final — это ещё одна форма записи конечного состояния. Это не так?
Согласен, экономия в пару символов ничего особенного не даёт.

CU>конечно приятно читать, я пометил сделать такой синтаксис, в парсере по идее не должно быть проблем, надо будет просто потом обрабатывать дерево после парсинга и парсить по другим правилам


Ну да, просто, честно говоря, я не очень понимаю, как такое в PEG правильно сделать — чтоб он табуляции считал.
Re[12]: [Nemerle.Statechart] примеры и описания
От: CodingUnit Россия  
Дата: 26.08.11 11:04
Оценка:
Здравствуйте, FDSC, Вы писали:

FDS>Здравствуйте, CodingUnit, Вы писали:


CU>>тут мне кажется подойдет choice / junction псевдосостояния, они могут иметь прикрепленные сторожевые условия, переход осуществляется туда где условие истинно, к этому условию можно прикрепить что угодно функцию, делегат, главное чтобы отрезок возвращал bool, в этой функции можно делать что угодно и расчитывать пути как вздумается, если эта вещь будет переиспользуемая то можно подумать о введении синтаксиса. Пока это похоже на динамический доступ к переходам, его можно имитировать как я сказал


FDS>Если все состояния сделать параллельными, то не пройдёт, т.к. мы будем иметь автомат с набором состояний, ограниченным не одним из возможных, а всеми из возможных и метка должна будет двигаться по сети, а не быть статической.

FDS>Кроме этого, даже если брать один автомат, тогда нужно где-то хранить данные, к нему привязанные. В т.ч. хранить данные для вложенных автоматов.
Данные хранить можно в классе в котором определяется автомат, но сложные вещи как ты сказал выше без поддержки компилятора библиотеки невозможно, есть библиотеки для работы с сетями петри, посмотри может пригодяться, я же не хотел выходить далеко за семантику UML, какие то простые вещи можно сделать, остальные могут только загрузить автомат

FDS>Вообще, я так подумал, это довольно сложно сделать. По-сути надо тогда синтаксис делать расширяемым, грубо говоря, с возможностью написать нечто типа некоторое_слово[параметры] и затем передать это через рефлексию в функцию с именем некоторое_слово со списком параметров, которые она сама будет парсить. И при этом это уже тогда получается автомат сам, наверное, надо менять, чтобы количество параллельных состояний было ограниченным лишь количеством объявленных состояний.

это все сначала надо продумать как должно быть, может быть и возможно сделать DSL для сетей петри, и удобную библиотеку, но я в них не разбираюсь и не знаю как их реализовывать в библиотеке

CU>>у меня в каждом регионе независимое начальное состояние, которое должно указываться там же, эта запись конфликтует с синтаксисом fork перехода


FDS>Странно, конечное состояние, общее для параллельных регионов, есть, а начального нет... по идее, должно быть такое состояние, а эта запись тогда есть fork-переход из него. Ну раз нет, значит не надо, но вообще, гораздо проще его было бы задать как я написал, чем задавать отдельно вручную для каждого региона (если отключить флаг автоматического определения начального состояния).

конечное состояние не общее а каждое в своем регионе, просто конечные состояния не объявляются явно, а переход в конечное состояние подразумевает что в этом регионе или в этом композитном состоянии объявлено конечное состояние, которое и добавляется закулисами, потому что переход в конечное состояние из других подсостояний по словам стандарта бессмыслен

FDS>Я так понял, что final — это ещё одна форма записи конечного состояния. Это не так?

FDS>Согласен, экономия в пару символов ничего особенного не даёт.
экономии нет, а проблемы в парсере возникают, пусть лучше будет однообразный синтаксис, можно придумать короче если понадобится, меня пока запись $0 устраивает

CU>>конечно приятно читать, я пометил сделать такой синтаксис, в парсере по идее не должно быть проблем, надо будет просто потом обрабатывать дерево после парсинга и парсить по другим правилам


FDS>Ну да, просто, честно говоря, я не очень понимаю, как такое в PEG правильно сделать — чтоб он табуляции считал.

честно говоря и я толком не знаю как реализовывать indentation синтаксис в PEG, но думается можно это сделать если несколько символов пробелов или табуляций считать спец разделителем, получится дерево, которое надо будет потом обработать и преобразовать в конечный вид, кажется так
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.