Простейшие Конечные Автоматы Или Конечные Автоматы В Три Шага



Простейшие конечные автоматы или конечные автоматы в три шага

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

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

Вскоре я наткнулся Эта статья , что подтвердило отсутствие удобных решений.



Что ты сделал потом?

Поскольку задачу нужно было решить быстро (ну как обычно), мой конечный автомат был реализован с помощью словарей, то есть:
  • есть список состояний (Enum)
  • список сигналов (замена классическому входному алфавиту)
  • словарь (карта): состояние-сигнал-состояние
Таким образом, в нужном месте функция «издает сигнал» и в зависимости от текущего состояния и сигнала происходит переход (устанавливается следующее состояние)

Но что дальше?

Это был третий год обучения в университете по специальности «Инженер-программист» и пришло время определиться с темой диплома.

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

Решение: библиотека и графический редактор.

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



Спустя год разработки.



Графический редактор

Реализовано в wpf с использованием Реактивный пользовательский интерфейс .

Здесь мы имеем структуру конечного автомата в виде графа и в виде таблицы переходов.

Накидываем ноды, соединяем их и сохраняем в xml файл.



Простейшие конечные автоматы или конечные автоматы в три шага

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

В конце прикреплю ссылку на репозиторий с документацией в виде гифки.

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

Возможности



Две темы



Простейшие конечные автоматы или конечные автоматы в три шага



Два представления конечного автомата:

  • как график
  • в виде таблицы переходов


Проверка

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


Добавление узлов и соединений



Простейшие конечные автоматы или конечные автоматы в три шага



Отменить действия



Простейшие конечные автоматы или конечные автоматы в три шага



Свертывание и перемещение узлов



Простейшие конечные автоматы или конечные автоматы в три шага



Масштабирование



Простейшие конечные автоматы или конечные автоматы в три шага



Выбор элементов



Простейшие конечные автоматы или конечные автоматы в три шага



Имена состояний и переходов



Простейшие конечные автоматы или конечные автоматы в три шага



Перемещение переходов



Простейшие конечные автоматы или конечные автоматы в три шага



Удаление переходов



Простейшие конечные автоматы или конечные автоматы в три шага



Импорт/Ээкспорт из/в xml

  
  
  
  
  
  
   

<Эxml version="1.0" encoding="utf-8"?> <StateMachine> <States> <State Name="Start" Position="37, 80" IsCollapse="False" /> <State Name="State 1" Position="471, 195.54" IsCollapse="False" /> <State Name="State 2" Position="276, 83.03999999999999" IsCollapse="False" /> </States> <StartState Name="Start" /> <Transitions> <Transition Name="Transition 2" From="State 2" To="State 1" /> <Transition Name="Transition 1" From="Start" To="State 2" /> </Transitions> </StateMachine>



Сохранение диаграммы в формате PNG/JPEG.



Простейшие конечные автоматы или конечные автоматы в три шага

Библиотека Мы реализуем конечный автомат в три этапа:
  1. Мы создаем конечный автомат и инициализируем его структуру файлом, сохраненным из редактора.



    StateMachine stateMachine = new StateMachine("scheme.xml");

  2. Основную логику мы описываем в методах, которые потом «навешиваем» на события, которых достаточно.



    stateMachine.GetState("State1").

    OnExit(Action1); stateMachine.GetState("State2").

    OnEntry(Action2); stateMachine.GetTransition("Transition1").

    OnInvoke(Action3); stateMachine.OnChangeState(Action4);

  3. Запустим.



    stateMachine.Start(parameters);

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

А как насчет переходов? Для перехода внутри функции, обрабатывающей вход/выход в состоянии, мы вызываем:

StateMachine.InvokeTransition("Transition1", parameters);

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

  • Параметры переходов и состояний.

  • Данные — это словарь данных, который хранится внутри StateMachine и используется для обмена данными между состояниями.

Полный список возможностей и подробную документацию можно найти в репозитории, также оставлю ссылку.

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

Возможности:

  • Начальное состояние
  • Государственные события входа и выхода
  • Выполнить событие для перехода
  • Варианты перехода
  • Параметры для ввода/вывода состояния
  • Событие изменения состояния
  • Данные для обмена между государствами
  • Событие изменения данных
  • Импорт/Ээкспорт из/в xml
  • Ведение журнала
Будущее проекта Диссертация была защищена отлично, но отказываться от проекта не хотелось бы.

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

Так же если найдете ошибки или есть другие идеи - пишите, буду очень рад!

Библиотека.

Возможные улучшения:

  1. Асинхронность
  2. Таймеры
  3. Вложенные конечные автоматы
  4. Магия работы с элементами диаграммы
О последнем пункте я расскажу подробнее.

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

И работа с ними выглядит следующим образом:

stateMachine.GetState("State1");

Я бы хотел, чтобы это было так

stateMachine.State1;

Скажу сразу, что динамический не подойдет, потому что вам еще нужно запомнить название.

Вероятно, это требует какой-то генерации кода, но я пока не нашел решения.



Графический редактор.

Возможные улучшения:

  1. Локализация
  2. Шейдеры для рисования элементов схемы.

  3. Вложенные конечные автоматы
  4. Автоматическое распределение узлов — волшебная кнопка для авторазметки элементов на холсте
  5. Кросс-платформенный — Перевод проекта на АвалонияUI
выводы
  • Мы создаем конечную машину в три шага и в любой момент можем визуально отобразить и отредактировать структуру машины.

  • Дальнейшее развитие проекта
Ссылки Графический редактор, исходники на GitHub: SimpleStateMachineNodeEditor Библиотека, исходники на GitHub: SimpleStateMachineLibrary Теги: #программирование #C++ #.

NET #конечный автомат #Конечный автомат #SimpleStateMachine

Вместе с данным постом часто просматривают: