В данной статье под термином «конечный автомат» подразумевается алгоритм, который может находиться в одном из небольшого количества состояний. «Состояние» - это некое условие, определяющее заданную взаимосвязь входных и выходных сигналов, а также входных сигналов и последующих состояний. Смышленый читатель сразу отметит, что конечные автоматы, описанные в данной статье, это автоматы Мили. Автомат Мили – это конечный автомат, где выходные сигналы являются функциями текущего состояния и входного сигнала, в отличие от автомата Мура, в котором выходные сигналы – это функции только состояния. В обоих случаях последующее состояние – это функция текущего состояния и входного сигнала.
Рассмотрим пример простого конечного автомата. Представьте, что в текстовой строке вам нужно распознать последовательность символов «//». На рисунке 1 показано, как это выполняется при помощи конечного автомата. Первое появление слеша не дает выходного сигнала, но приводит к тому, что автомат переходит во второе состояние. Если во втором состоянии автомат не находит слеша, он возвращается к первому, поскольку необходимо наличие 2-х слешей подряд. Если второй слеш найден, автомат выдает сигнал «готово».
Выясните, что необходимо заказчику.
Составьте диаграмму перехода состояний
Закодируйте «скелет» конечного автомата без детализации операций перехода.
Убедитесь, что переходы функционируют правильно.
Конкретизируйте детали переходов.
Проведите тест.
Пример конечного автомата
Рассмотрим более интересный пример конечного автомата - программу, контролирующую втягивание и выдвижение шасси самолета. Хотя у большинства самолетов эта процедура выполняется при помощи электрогидравлического управляющего механизма (просто потому, что на борту отсутствует компьютер), в некоторых случаях, например в беспилотных летательных аппаратах, стоит использовать программное управление.
Для начала разберемся с оборудованием. Шасси самолета состоит из передней опоры, основного левого шасси и основного правого шасси. Они приводятся в действие гидравлическим механизмом. Гидравлический насос с электроприводом подает давление на силовой исполнительный механизм. При помощи программного обеспечения насос включается или выключается. Компьютер регулирует положение клапана направления - «вниз» или «вверх», чтобы позволить давлению поднять или опустить шасси. Каждая из опор шасси имеет концевой выключатель: один из них закрывается, если шасси поднято, другой - если оно зафиксировано в положении «вниз». Чтобы определить, находится ли самолет на земле, концевой выключатель на стойке передней опоры замыкается, если вес самолета приходится на переднюю опору. Средства управления пилота состоят из верхнего/нижнего рычага шасси и трех лампочек (по одной на каждую опору), которые могут выключаться, загораться зеленым (положение «вниз») или красным светом (положение «переход»).
А теперь перейдем к разработке конечного автомата. Первый, и самый сложный шаг – это понять реальные ожидания заказчика. Одним из преимуществ конечного автомата состоит в том, что он заставляет программиста продумывать все возможные случаи и, как следствие, получать от заказчика всю требуемую информацию. Почему я считаю это самым сложным этапом? А сколько раз вам давали описание задачи подобное этому: не задвигайте шасси, если самолет находится на земле.
Безусловно, это важно, но заказчик считает, что на этом все заканчивается. А как насчет остальных случаев? Достаточно ли задвигать шасси в тот момент, когда самолет отрывается от земли? Что, если самолет подскочит на кочке на взлетно-посадочной полосе? Что, если пилот переведет рычаг переключения скоростей в положение «вверх» во время парковки и, как следствие, начнет взлетать? Должно ли шасси в этом случае подняться?
Одним из преимуществ мышления в терминах конечного автомата является то, что вы можете быстро нарисовать диаграмму перехода состояний на проекционной доске, прямо перед заказчиком, и пройти весь процесс вместе с ним. Принято такое обозначение перехода состояний: «событие, которое явилось причиной перехода»/«выходной сигнал как результат перехода». Если бы мы разрабатывали только то, о чем изначально просил заказчик («не задвигать шасси, если самолет находится на земле»), то мы бы получили автомат, изображенный на рисунке 2.
При составлении диаграммы перехода состояний (или любого другого алгоритма) помните о следующем:
Компьютеры работают очень быстро по сравнению с механической аппаратурой
Инженер-механик, который объясняет, что требуется сделать, возможно, не знает о компьютерах и алгоритмах всего того, что знаете вы. И это тоже положительный момент, в противном случае, вы бы не потребовались!
Как поведет себя ваша программа, если сломается механическая или электрическая деталь?
Конечный автомат, основанный на том, что действительно требуется заказчику, показан на рисунке 3. Здесь мы хотим воспрепятствовать втягиванию шасси самолета до тех пор, пока он точно не будет в воздухе. Для этого после открытия переключателя приземления автомат в течение нескольких секунд находится в ожидании. Мы также хотим реагировать на нарастающий фронт рычага пилота, а не на уровень, что позволит избежать проблем, если кто-то подвинет рычаг, пока самолет находится на парковке. Втягивание или выдвижение шасси занимает несколько секунд, и мы должны быть готовы к ситуации, что пилот в процессе этой операции передумает и переместит рычаг в противоположном направлении. Также обратите внимание, что если самолет снова приземлится, пока мы находимся в состоянии «Waiting for takeoff», таймер перезапустится и втягивание шасси произойдет, только если самолет будет находиться в воздухе в течение 2-х секунд.
Реализация конечного автомата
Листинг 1 – это моя реализация конечного автомата изображенного на рисунке 3. Давайте обсудим некоторые детали кода.
/*листинг 1*/
typedef enum {GEAR_DOWN = 0, WTG_FOR_TKOFF, RAISING_GEAR, GEAR_UP, LOWERING_GEAR} State_Type;
/*Этот массив содержит указатели на функции, вызываемые в определенных состояниях*/
void (*state_table)() = {GearDown, WtgForTakeoff, RaisingGear, GearUp, LoweringGear};
State_Type curr_state;
InitializeLdgGearSM();
/*Сердце автомата – этот бесконечный цикл. Функция, соответствующая
Текущему состоянию, вызывается один раз в итерацию */
while (1) {
state_table();
DecrementTimer();
void InitializeLdgGearSM(void )
curr_state = GEAR_DOWN;
/*Остановка аппаратуры, выключение лампочек и т.д.*/
void GearDown(void )
/* Переходим в состояние ожидания, если самолет
Не на земле и поступила команда поднять шасси*/
if ((gear_lever == UP) && (prev_gear_lever == DOWN) && (squat_switch == UP)) {
curr_state = WTG_FOR_TKOFF;
prev_gear_lever = gear_lever;
void RaisingGear(void )
if ((nosegear_is_up == MADE) && (leftgear_is_up == MADE) && (rtgear_is_up == MADE)) {
curr_state = GEAR_UP;
/*Если пилот изменил свое решение, перейти в состояние «опускание шасси»*/
if (gear_lever == DOWN) {
curr_state = LOWERING_GEAR;
void GearUp(void )
/*если пилот передвинул рычаг в положение «вниз»,
Переходим в состояние «опускание шасси»*/
if (gear_lever == DOWN) {
curr_state = LOWERING_GEAR;
void WtgForTakeoff(void )
/* Ожидание перед поднятием шасси.*/
if (timer <= 0.0) {
curr_state = RAISING_GEAR;
/*Если мы снова коснулись или пилот поменял решение – начать все заново*/
if ((squat_switch == DOWN) || (gear_lever == DOWN)) {
curr_state = GEAR_DOWN;
/* Don"t want to require that he toggle the lever again
This was just a bounce.*/
prev_gear_lever = DOWN;
void LoweringGear(void )
if (gear_lever == UP) {
curr_state = RAISING_GEAR;
if ((nosegear_is_down == MADE) && (leftgear_is_down == MADE) &&(rtgear_is_down == MADE)) {
curr_state = GEAR_DOWN;
Во-первых, вы можете заметить, что функциональность каждого состояния реализуется отдельной Си функцией. Конечно, можно было бы реализовать автомат, используя оператор switch с отдельным case `ом для каждого состояния, однако это может привести к очень длинной функции (10-20 строк кода на 1 состояние для каждого из 20-30 состояний). Также это может привести к ошибкам, если будете изменять код на конечных стадиях тестирования. Возможно, вы никогда не забывали оператор break в конце case`a, но со мной такие случаи бывали. Код одного состояния никогда не попадет в код другого, если для каждого состояния у вас будет отдельная функция.
Чтобы избежать применения оператора switch, я использую массив указателей на функции состояний, а переменную, используемую в качестве индекса массива, объявляю типа enum.
Для простоты оборудование ввода-вывода, ответственное за считывание состояния переключателей, включение и выключение насосов и т.д., представлено в виде простых переменных. Предполагается, что данные переменные представляют собой «магические адреса», связанные с оборудованием невидимыми средствами.
Другая очевидная вещь - в этот момент код не играет особой роли. Он просто переходит от одного состояния к другому. Это важный промежуточный этап и его не следует игнорировать. Кстати, было бы неплохо добавить операторы печати, заключенные между директивами условной компиляции (#ifdef DEBUG .. #endif), которые бы выводили текущее состояние и значения входных сигналов.
Залог успеха кроется в коде, который вызывает переход состояний, т.е. определяет, что произошел ввод данных.
Если код правильно проходит через все состояния, следующим этапом становится написание «начинки» кода, то есть именно того, что производит выходной сигнал. Помните, что каждый переход имеет входной сигнал (событие, которое вызвало его) и выходной сигнал (аппаратное устройство ввода-вывода, как в нашем примере). Зачастую это полезно зафиксировать в виде таблицы перехода состояний.
В таблице перехода состояний одна строка приходится на один переход состояния.
При кодировании конечного автомата старайтесь сохранить его силу – ярко выраженное соответствие между требованиями заказчика и кодом. Вероятно, придется скрыть подробности касательно оборудования в другом уровне функций, например, для того, чтобы код конечного автомата максимально походил на таблицу перехода состояний и диаграмму перехода состояний. Подобная симметрия помогает предотвратить ошибки и объясняет то, почему конечные автоматы являются такой важной частью арсенала программиста встраиваемых систем. Конечно, вы могли бы добиться того же эффекта путем установки флажков и бесконечного множества вложенных операторов if, однако при этом будет очень сложно отслеживать код и сравнивать его с пожеланиями заказчика.
Фрагмент кода в листинге 2 расширяет функцию RaisingGear(). Обратите внимание, что код для функции RaisingGear() стремится к зеркальному отображению 2-х рядов таблицы переходов для состояния Raising Gear.
void RaisingGear(void )
/*После того, как все переключатели подняты, переходим в состояние «шасси поднято»*/
if ((nosegear_is_up == MADE) && (leftgear_is_up == MADE) && (rtgear_is_up == MADE)) {
pump_motor = OFF;
gear_lights = EXTINGUISH;
curr_state = GEAR_UP;
/*Если пилот передумал, начать втягивание шасси*/
if (gear_lever == DOWN) {
pump_direction = DOWN;
curr_state = GEAR_LOWERING;
Помните о том, что следует избегать скрытых состояний. Скрытое состояние появляется тогда, когда по причине лени вы пытаетесь добавить условное субсостояние вместо того, чтобы добавить конкретное состояние. Например, если ваш код обрабатывает один и тот же входной сигнал разными способами (т.е. инициирует разные переходы состояний) в зависимости от режима, то он является скрытым состоянием. В этом случае я бы задумался, а не следует ли разбить данное состояние на два? Применение скрытых состояний сводит на нет все преимущество использования конечного автомата.
В качестве тренировки вы можете расширить конечный автомат, который мы только что рассмотрели, добавив таймаут к циклу втягивания или выдвижения шасси, т.к. инженер-механик не хочет, чтобы гидравлический насос работал дольше 60 секунд. Если цикл заканчивается, пилот должен быть предупрежден переключением зеленой и красной лампочки, и он должен иметь возможность снова переместить рычаг, чтобы повторить попытку. Также вы можете спросить гипотетического инженера-механика, как сказывается на насосе изменение направления на противоположное во время его работы, потому что это происходит в 2-ух случаях, когда пилот передумывает. Конечно, механик скажет, что негативно. Тогда как бы вы изменили конечный автомат, чтобы быстро остановить насос при изменении направления?
Тестирование конечного автомата
Прелесть кодирования алгоритмов в виде конечных автоматов состоит в том, что план проведения теста почти автоматически пишется сам. Все, что вам нужно сделать – это пройти через каждый переход состояния. Я обычно делаю это с маркером в руках, вычеркивая стрелки на диаграмме перехода состояний по мере того, как они успешно проходят тест. Это хороший способ избежать «скрытых состояний» - в тестах они упускаются чаще, чем конкретные состояния.
Это требует значительного терпения и большого количества кофе, так как даже конечный автомат средних размеров может иметь до 100 различных переходов. Кстати, количество переходов – это отличный способ измерить сложность системы. Последнее определяется требованиями заказчика, а конечный автомат делает очевидными объемы тестирования. При менее организованном подходе объем требуемого тестирования может оказаться таким же внушительным, но вы об этом просто не узнаете.
Очень удобно использовать в коде операторы печати, выводящие текущее состояние, значения входных и выходных сигналов. Это позволяет вам с легкостью наблюдать то, что выражает «Золотое Правило Тестирования Программ»: проверяйте, что программа выполняет задуманное, а также то, что она не делает ничего лишнего. Другими словами, получаете ли вы только те выходные сигналы, которые вы ожидаете, и что еще происходит помимо этого? Нет ли «затруднительных» переходов состояний, т.е. состояний, которые случайно проходят, только для одного повтора цикла? Меняются ли выходные сигналы, когда вы этого не ожидаете? В идеале выходные сигналы ваших printfs должны заметно напоминать таблицу перехода состояний.
Наконец - и это касается любого встроенного ПО, а не только ПО, основанного на конечных автоматах - будьте очень осторожны при первом запуске ПО на реальном оборудовании. Очень легко ошибиться с полярностью сигналов – «Ой, я думал, что «1» означает поднять шасси, а «0» - опустить его». Во многих случаях, мой помощник по оборудованию применял временный «куриный переключатель» для защиты ценных компонентов, пока не был уверен, что мое ПО перемещает предметы в правильном направлении.
Запуск
Когда все требования заказчика выполнены, я могу запускать конечный автомат подобной сложности через пару дней. Практически всегда автоматы выполняют то, что я хочу. Самое сложное – это, конечно, точно понять, чего хочет заказчик и убедиться, что заказчик сам знает, чего он хочет. Последнее занимает значительно больше времени!
Мартин Гомез – программист Лаборатории Прикладной Физики при Университете Джона Хопкинса. Занимается разработкой ПО для обеспечения полетов исследовательских космических кораблей. Проработал в области разработки встраиваемых систем в течение 17 лет. Мартин – бакалавр наук в области аэрокосмического инжиниринга и магистр в области электроинжиниринга (университет Корнелл).
Результат работы автомата определяется по его конечному состоянию.
Существуют различные варианты задания конечного автомата. Например, конечный автомат может быть задан с помощью пяти параметров: , где:
Автомат начинает работу в состоянии q 0 , считывая по одному символу входной строки. Считанный символ переводит автомат в новое состояние из Q в соответствии с функцией переходов. Если по завершении считывания входного слова (цепочки символов) автомат оказывается в одном из допускающих состояний, то слово «принимается» автоматом. В этом случае говорят, что оно принадлежит языку данного автомата. В противном случае слово «отвергается».
Конечные автоматы широко используются на практике, например в синтаксических , лексических анализаторах , и тестировании программного обеспечения на основе моделей .
Другие способы описания
- Диаграмма состояний (или иногда граф переходов ) - графическое представление множества состояний и функции переходов. Представляет собой нагруженный однонаправленный граф , вершины которого - состояния КА, ребра - переходы из одного состояния в другое, а - символы, при которых осуществляется данный переход. Если переход из состояния q1 в q2 может быть осуществлен при появлении одного из нескольких символов, то над дугой диаграммы (ветвью графа) должны быть надписаны все они.
- Таблица переходов - табличное представление функции δ. Обычно в такой таблице каждой строке соответствует одно состояние, а столбцу - один допустимый входной символ. В ячейке на пересечении строки и столбца записывается действие, которое должен выполнить автомат, если в ситуации, когда он находился в данном состоянии на входе он получил данный символ.
Детерминированность
Конечные автоматы подразделяются на детерминированные и недетерминированные.
Детерминированный конечный автомат
- Детерминированным конечным автоматом (ДКА) называется такой автомат, в котором для каждой последовательности входных символов существует лишь одно состояние, в которое автомат может перейти из текущего.
- Недетерминированный конечный автомат (НКА) является обобщением детерминированного. Недетерминированность автоматов достигается двумя способами:
Существуют переходы, помеченные пустой цепочкой ε | Из одного состояния выходит несколько переходов, помеченных одним и тем же символом |
---|---|
Если рассмотреть случай, когда автомат задан следующим образом: , где:
Тогда появляется третий признак недетерминизма - наличие нескольких начальных (стартовых) состояний у автомата .
Существует теорема, гласящая, что «Любой недетерминированный конечный автомат может быть преобразован в детерминированный так, чтобы их языки совпадали» (такие автоматы называются эквивалентными). Однако, поскольку количество состояний в эквивалентном ДКА в худшем случае растёт экспоненциально с ростом количества состояний исходного НКА, на практике подобная детерминизация не всегда возможна. Кроме того, конечные автоматы с выходом в общем случае не поддаются детерминизации.
В силу последних двух замечаний, несмотря на бо́льшую сложность недетерминированных конечных автоматов, для задач, связанных с обработкой текста, преимущественно применяются именно НКА.
Автоматы и регулярные языки
Для автомата можно определить язык (множество слов) в алфавите Σ, который он представляет - так называются слова, при вводе которых автомат переходит из начального состояния в одно из состояний множества F.
Специализированные языки программирования
- Язык последовательных функциональных схем SFC (Sequential Function Chart) - графический язык программирования широко используется для программирования промышленных логических контроллеров (ПЛК).
В SFC программа описывается в виде схематической последовательности шагов, объединенных переходами.
Разработка моделей с использованием конечных автоматов
Конечные автоматы позволяют построить модели систем параллельной обработки, однако, чтобы изменить число параллельных процессов в такой модели требуется внести существенные изменения в саму модель. Кроме того, попытка разработки сложной модели на конечном автомате приведет к быстрому росту числа состояний автомата, что в итоге сделает разработку такой модели крайне утомительным занятием. Как было отмечено выше последнюю проблему можно решить, если использовать недетерминированный автомат.
Примечания
См. также
- Секвенциальная логика (Последовательностная логика)
Ссылки
- Теория автоматов / Э. А. Якубайтис, В. О. Васюкевич, А. Ю. Гобземис, Н. Е. Зазнова, А. А. Курмит, А. А. Лоренц, А. Ф. Петренко, В. П. Чапенко // Теория вероятностей. Математическая статистика. Теоретическая кибернетика. - М.: ВИНИТИ, 1976. - Т. 13. - С. 109–188. - URL http://www.mathnet.ru/php/getFT.phtml?jrnid=intv&paperid=28&what=fullt&option_lang=rus
- Применение конечных автоматов для решения задач автоматизации
- Пример реализации конечного автомата на языке Python для фреймворка Django
Wikimedia Foundation . 2010 .
- Кейнс, Джон Мейнард
- Диаграмма состояний (теория автоматов)
Смотреть что такое "Конечный автомат" в других словарях:
конечный автомат - КА Вычислительная модель, описывающая автомат с конечным числом состояний. КА широко применяются в программировании, например в лексических анализаторах компиляторов. конечный автомат Спецификация последовательности… …
Конечный автомат - математическая модель устройства с конечной памятью. Конечный автомат перерабатывает множество входных дискретных сигналов в множество выходных сигналов. Различают синхронные и асинхронные конечные автоматы. По английски: Finite state machine См … Финансовый словарь
конечный автомат - baigtinis automatas statusas T sritis automatika atitikmenys: angl. finite automaton; finite state machine vok. endlicher Automat, m; Finalautomat, m rus. конечный автомат, m pranc. automate final, m; automate fini, m; automate terminal, m;… … Automatikos terminų žodynas
КОНЕЧНЫЙ АВТОМАТ - автомат, у к рого множество состояний, а также множество входных и выходных сигналов являются конечными. К. а. может быть моделью технич. устройства (ЭВМ, релейное устройство) либо биол. системы (идеализир. нервная система животного). Важными… … Большой энциклопедический политехнический словарь
конечный автомат в модульном исполнении - — [Я.Н.Лугинский, М.С.Фези Жилинская, Ю.С.Кабиров. Англо русский словарь по электротехнике и электроэнергетике, Москва, 1999 г.] Тематики электротехника, основные понятия EN finite modular automaton … Справочник технического переводчика
конечный автомат доступности - (МСЭ Т Y.1711). Тематики электросвязь, основные понятия EN availability state machineASM … Справочник технического переводчика
Конечный автомат с памятью - Конечный автомат с памятью математическая модель устройства, поведение которого зависит как от входных условий, так и от предыдущего состояния. Для описания конечного автомата с памятью используются языки операторных схем, регулярных… … Википедия
детерминированный конечный автомат - — [Я.Н.Лугинский, М.С.Фези Жилинская, Ю.С.Кабиров. Англо русский словарь по электротехнике и электроэнергетике, Москва, 1999 г.] Тематики электротехника, основные понятия EN finite deterministic automaton … Справочник технического переводчика
Автомат Мура - (автомат второго рода) в теории вычислений конечный автомат, выходное значение сигнала в котором зависит лишь от текущего состояния данного автомата, и не зависит напрямую, в отличие от автомата Мили, от входных значений. Автомат Мура назван … Википедия
Сегодня мы поговорим о автоматах, но отнюдь не тех что держат в руках солдаты российской армии. Речь пойдет о таком интересном стиле программирования микроконтроллеров как автоматное программирование. Точнее это даже не стиль программирования а целая концепция, благодаря которой программист микроконтроллеров может значительно облегчить свою жизнь. Благодаря которой многие задачи представленные перед программистом решаются гораздо легче и проще, избавляя программиста от головной боли. Кстати автоматное программирование зачастую называют SWITCH-технологией.
Хочу заметить что стимулом написания этого поста послужил цикл статей о SWITCH-технологии Владимира Татарчевского. Цикл статей называется «Применение SWITCH-технологии при разработке прикладного программного обеспечения для микроконтроллеров» Так что в этом статье я постараюсь по большей части привести пример рабочего кода и его описание.
Кстати я запланировал ряд статей посвященных программированию, в которых буду подробно рассматривать приемы программирования под микроконтроллеры АВР, не пропустите …. Ну что ж поехали!
Программа последовательно выполняет команды заложенные программистом. Для обычной компьютерной программы совершенно нормально когда программа отработала и остановила свое исполнение, выводя при этом результаты своей работы на монитор.
Программа под микроконтроллер не может просто закончить свое исполнение. Вот представьте себе, что вы включили плеер или магнитофон. Вы нажали кнопочку power, выбрали желаемую композицию, и наслаждаетесь музыкой. Однако когда музыка прекратила трепать барабанную перепонку вашего уха, плеер завис и никак не реагирует на нажатие кнопочек а тем более на ваши танцы с бубном.
А что здесь такого? Все нормально — контроллер, тот что в недрах вашего плеера просто закончил выполнение своей программы. Вот видите неудобненько как-то получается.
Так вот отсюда мы делаем вывод, что программа под микроконтроллер просто не должна останавливаться. По сути своей она должна представлять собой бесконечный цикл — только в этом случае наш плеер работал бы правильно. Дальше я вам покажу какие бывают конструкции программного кода под микроконтроллеры, это даже не конструкции а некоторые стили программирования.
Стили программирования.
«Стили программирования» — звучит как-то непонятно, ну да ладно. Что я хочу этим сказать?Представим, что человек никогда до этого не занимался программированием, то есть вообще полный чайник.
Этот человек прочел много книг по программированию, изучил все основный конструкции языка. Он насобирал информации по крупицам, благо сейчас доступ к информации неограничен. Все это хорошо, но как будут выглядеть его первые программы? Мне кажется что он не будет мудрствовать, а пойдет по пути от простого к сложному.
Так вот эти стили и являются ступеньками ведущими от простого уровня к более сложному, но и в тоже время более эффективному.
Поначалу я не задумывался о каких-то конструктивных особенностях программы. Я просто формировал логику программы — чертил блок-схему и писал код. От чего постоянно натыкался на грабли. Но это было первое время когда я не парился и использовал стиль «простое зацикливание», затем стал применять прерывания, далее были автоматы и пошло поехало…
1. Простое зацикливание. Программа в этом случае зацикливается без каких-либо премудростей и в этом есть свои плюсы и минусы. Плюс лишь в простоте подхода, не нужно выдумывать хитрые конструкции, пишешь так как думаешь (постепенно роя себе могилу).
Void main(void) { initial_AL(); //инициализация периферии while(1) { Leds_BLINK(); //функция светодиодной мигалки signal_on(); //функция включения сигнала signal_off(); //функция выключения сигнала l=button(); //переменная отвечающая за нажатие кнопок switch(l) //В зависимости от величины переменной выполняется то или иное действие { case 1: { Deistvie1(); //Вместо функции может быть условный оператор Deistvie2(); //или еще несколько веток switch case Deistvie3(); Deistvie4(); Deistvie5(); }; case 2: { Deistvie6(); Deistvie7(); Deistvie8(); Deistvie9(); Deistvie10(); }; . . . . . . . . } } }
Рабочая точка программы движется по порядку. При этом последовательно выполняются все действия, условия и циклы. Код начинает тормозить, приходится вставлять много лишних условий, усложняя тем самым восприятие.
Все это очень сильно запутывает программу, делая из кода клубок условий. В итоге к этому коду не добавить ни отнять, он становится как монолитный кусок. Конечно когда объем не большой, код поддается модификациям, но чем дальше тем сложнее.
С таким подходом я написал несколько программок, они были не большие и вполне рабочие но наглядность оставляла желать лучшего. Чтобы добавить какое-то новое условие, приходилось перелопачивать весь код, потому, что все было завязано. Это порождало много ошибок и головной боли. Компилятор ругался как только мог, отлаживание такой программы превращалось в ад.
2. Цикл + прерывания.
Отчасти разрулить бесконечный тормозной цикл можно используя прерывания. Прерывания помогают вырваться из порочного круга, помогают не пропустить важного события, добавляют дополнительный функционал (прерывания от таймеров, внешние прерывания).
Допустим на прерывание можно повесить обработку кнопок, или отслеживание важного события. В результате программа становится более наглядной но не менее запутанной.
К сожалению прерывание не спасет от каши, в которую превращается программа. Не удастся разделить на части то, что представляет собой единое целое.
3. Автоматное программирование.
Вот мы и подбираемся к главной теме данной статьи. Программирование в конечных автоматах избавляет программу от недостатков присущих первым двум примерам. Программа становится проще, ее легко модифицировать.
Программа написанная в автоматном стиле похожа на переключатель, который в зависимости от условий переключается в то или иное состояние. Количество состояний программисту изначально известно.
В грубом представлении это как выключатель освещения. Есть два состояния включено и выключено, и два условия включить и выключить. Ну а обо всем по порядку.
Реализация многозадачности в switch-технологии.
Микроконтроллер способен управлять нагрузкой, моргать светодиодами, отслеживать нажатие клавиш и многое другое. Но как все это делать одновременно? Для решения этого вопроса существует множество решений. Самый простой из них я уже упоминал это использование прерываний.
В процессе работы программы, когда происходит прерывание, контроллер отвлекается от выполнения кода программы и кратковременно выполняет другой кусок программы за который отвечает прерывание. Прерывание отработает, тогда рабочая точка программы продолжит с того места, с которого контроллер прервался на прерывание (само слово говорит о том что контроллер прерывается).
Другой способ реализации многозадачности это использование операционных систем. Да действительно стали уже появляться маленькие ОСьки, которые можно применить на маломощном контроллере. Но зачастую этот способ получается несколько избыточным. Ведь зачем расходовать ресурсы контроллера излишней работой когда вполне можно обойтись малой кровью.
В программах написанных по switch — технологии подобная «иллюзия» многозадачности получается благодаря системе обмена сообщений. Я написал «иллюзия», потому, что так и есть на самом деле, ведь программа физически не может в одно и тоже время выполнять различные участки кода. О системе обмена сообщениями я расскажу немного дальше.
Система обмена сообщениями.
Разрулить многочисленные процессы и создать иллюзию многозадачности можно используя систему обмена сообщениями.
Допустим нам нужна программа в которой идет переключение светодиода. Вот у нас есть два автомата, назовем их LEDON -автомат ответственный за включение светодиода и автомат LEDOFF — автомат ответственный за выключение светодиода.
Каждый из автоматов имеет два состояния, то есть автомат может быть в активном состоянии так и неактивном состоянии, как рубильник либо включено, либо выключено.
При активации одного автомата происходит зажжение светодиода, при активации другого светодиод гасится. Рассмотрим небольшой пример:
Int main(void) { INIT_PEREF(); //инициализация периферии (светодиоды) InitGTimers(); //инициализация таймеров InitMessages(); //инициализация механизма обработки сообщений InitLEDON(); //инициализация автомата LEDON InitLEDOFF(); //инициализация автомата LEDOFF SendMessage(MSG_LEDON_ACTIVATE); //активируем автомат LEDON sei(); //Разрешаем прерывания //Главный цикл программы while(1) { ProcessLEDON(); //итерация автомата LEDON ProcessLEDOFF(); //итерация автомата LEDOFF ProcessMessages(); //обработка сообщений }; }
В строках 3 -7 происходят различные инициализации поэтому нас это сейчас не особо интересует. А вот дальше происходит следующее: перед запуском главного цикла (while(1)), мы отправляем сообщение автомату
SendMessage(MSG_LEDON_ACTIVATE)
ответственному за зажжение светодиода. Без этого маленького шажка наша шарманка не заработает. Далее главный бесконечный цикл while выполняет основную работу.
Небольшое отступление:
Сообщение имеет три состояния. А именно состояние сообщение может быть неактивно, установлено но неактивно и активное состояние.
Получается, что сообщение изначально было неактивно, когда мы отправили сообщение, оно получило состояние «установлено но неактивно». И это дает нам следующее. При последовательном выполнении программы автомат LEDON сообщение не получает. Происходит холостая итерация автомата LEDON при котором сообщение просто не может быть принято. Так как сообщение имеет состояние «установлено но неактивно» программа продолжает свое выполнение.
После того как все автоматы в холостую протикают, очередь доходит до функции ProcessMessages(). Эта функция всегда ставится в конце цикла, после выполнения всех итераций автоматов. Функция ProcessMessages(), просто переводит сообщение из состояния «установлено но неактивно» в состояние «активно».
Когда бесконечный цикл выполняет второй круг, картина уже становится совершенно другая. Итерация автомата ProcessLEDON уже не будет холостой. Автомат сможет принять сообщение, перейдет в зажженное состояние и также в свою очередь отправит сообщение.Оно будет адресовано автомату LEDOFF и жизненный цикл сообщения повторится.
Хочу заметить, что сообщения которые имеют состояние «активно», при встрече с функцией ProcessMessages уничтожаются. Поэтому сообщение может быть принято только одним автоматом. Есть еще один тип сообщений — это широковещательные сообщения, но я их рассматривать не буду, в статьяхТатарчевского они также хорошо освещены.
Таймеры
С помощью правильной организации обмена сообщениями мы можем контролировать порядок работы конечных автоматов, но только лишь сообщениями нам не обойтись.
Наверное вы заметили, что предыдущий фрагмент программы, приведенный в качестве примера, не будет работать так, как задумано. Автоматы будут обмениваться сообщениями, светодиоды будут переключаться, вот только мы этого не увидим. Мы увидим только тускло горящий светодиод.
Все потому, что мы не продумали грамотную отработку задержек. Ведь нам не достаточно попеременного включения-выключения светодиодов, светодиод должен задерживаться в каждом состоянии, допустим на секунду.
Алгоритм будет следующим:
Можно кликнуть чтобы увеличить
Забыл дописать на этой блок схеме, что когда таймер дотикал, конечно же выполняется действие — зажжение светодиода или его гашение.
1. Входим в состояние посредством принятия сообщения.
2. Проверяем показания таймера/счетчика, если дотикало, то выполняем действие, иначе просто отправляем сообщение самому себе.
3. Отправляем сообщение следующему автомату.
4. Выход
В следующем входе все повторяется.
Программа по SWITCH-технологии. Три шага.
А давайте напишем программу в конечных автоматах и для этого нам нужно будет проделать всего три простых шага. Программа будет простой но именно с простых вещей стоит начинать. Нам подойдет программа с переключающимся светодиодом. Это очень хороший пример, так не будем изобретать ничего нового.
Программу я буду составлять на языке СИ, но это совсем не значить что в конечных автоматах нужно писать только на Си, вполне можно использовать любой другой язык программирования.
Программа будет у нас модульной и поэтому будет разбита на несколько файлов. Модули у нас будут следующие:
- Модуль основного цикла программы содержит файлы leds_blink.c, HAL.c, HAL.h
- Модуль таймеров содержит файлы timers.c, timers.h
- Модуль обработки сообщений содержит файлы messages.c, messages.h
- Модуль автомата 1 содержит файлы ledon.c, ledon.h
- Модуль автомата 2 содержит файлы ledoff.c , ledoff .h
Шаг 1.
Создаем проект и сразу подключаем к нему файлы наших статичных модулей:timers.c, timers.h, messages.c, messages.h.
Файл leds_blink.c модуля основного цикла прогарммы.
#include "hal.h" #include "messages.h" //модуль обработки сообщений #include "timers.h" //модуль таймеров //Прерывания по таймеру //############################################################################################ ISR(TIMER0_OVF_vect) // переход по вектору прерывания (переполнение таймера счетчика T0) { ProcessTimers(); //Обработчик прерываний от таймера } //########################################################################################### int main(void) { INIT_PEREF(); //инициализация переферии (светодиоды) InitGTimers(); //инициализация таймеров InitMessages(); //инициализация механизма обработки сообщений InitLEDON(); //инициализация автомата LEDON InitLEDOFF(); StartGTimer(TIMER_SEK); //Запуск таймера SendMessage(MSG_LEDON_ACTIVATE); //активируем автомат FSM1 sei(); //Разрешаем прерывания //Главный цикл программы while(1) { ProcessLEDON(); //итерация автомата LEDON ProcessLEDOFF(); ProcessMessages(); //обработка сообщений }; }
В первых строчках происходит подключение к основной программе остальных модулей. Здесь мы видим что подключены модуль таймеров и модуль обработки сообщений. Далее по тексту программы идет вектор прерывания по переполнению.
Со строчки int main (void) можно сказать начинается основная программа. И начинается она с инициализации всего и вся. Здесь инициализируем периферию, то есть задаем начальные значения портам ввода вывода компаратору и всему остальному содержимому контроллера. Все это делает функция INIT_PEREF, здесь ее запускаем, хотя основное ее тело находится в файле hal.c.
Далее мы видим инициализации таймеров, модуля обработки сообщений, инициализации автоматов. Здесь эти функции также просто запускаются, хотя сами функции прописаны в файлах своих модулей. Видите как удобно. Основной текст программы остается легко читаемым и не загромождается избыточным кодом от которого черт ногу сломи.
Основные инициализации закончились теперь нам нужно сделать запуск основного цикла. Для этого отправляем стартовое сообщение, и к тому же заводим наши часики -запускаем таймер.
StartGTimer(TIMER_SEK); //Запуск таймера SendMessage(MSG_LEDON_ACTIVATE); //активируем автомат FSM1
А основной цикл, как я уже и говорил выгладит очень просто. Записываем функции всех автоматов, просто записываем в столбик, без соблюдения очередности. Эти функции являются обработчиками автоматов и находятся в модулях автоматов. Завершает эту автоматную пирамидку функция модуля обработки сообщений. Это я конечно уже рассказывал ранее когда разбирались с системой отправки сообщений. Теперь можно посмотреть как выглядят еще два файла модуля основного цикла программы
Hal.h — это заголовочный файл модуля основного цикла программы.
#ifndef HAL_h
#define HAL_h
#include Как вы могли заметить этот файл по своей сути не содержит ни строчки исполняемого кода — это все макроподстановки и подключение библиотек. Наличие этого файла просто очень хорошо облегчает жизнь, он улучшает наглядность. А вот файл Hal.c — это уже исполняемый файл, и как я уже упоминал, в нем содержится различный инициализации периферии.
#include "hal.h"
void INIT_PEREF(void)
{
//Инициализация портов ввода-вывода
//###################################################################################
Komparator = ViklKomparator; //инициализация компаратора - выключение
DDRD = 1< Ну чтож модуль основного цикла программы я показал теперь нам осталось сделать последний шаг, нам нужно написать модули самих автоматов. Шаг 3.
Нам осталось написать модули конечных автоматов, в нашем случае автомата LEDON и автомата LEDOFF. Для начала приведу текст программы автомата зажигающего светодиод файл ledon.c.
//файл ledon.c
#include "ledon.h"
#include "timers.h"
#include "messages.h"
unsigned char ledon_state; //переменная состояния
void InitLEDON(void)
{
ledon_state=0;
//здесь можно выполнить инициализацию других
//переменных автомата при их наличии
}
void ProcessLEDON(void)
{
switch(ledon_state)
{
case 0: //неактивное состояние
if(GetMessage(MSG_LEDON_ACTIVATE)) //если сообщение есть то оно будет принято
{ //и пойдет проверка таймера
if(GetGTimer(TIMER_SEK)==one_sek) //если таймер засек 1сек то выполняем
{
StopGTimer(TIMER_SEK);
PORTD = 1< Здесь в первых строчках как всегда подключаются библиотеки и объявляются переменные. Далее у нас пошли уже функции, с которыми мы уже встречались. Это функция инициализации автомата InitLEDON и функция уже самого обработчика автомата ProcessLEDON. В теле обработчика уже происходит отработка функций из таймерного модуля и модуля сообщений. А сама логика автомата выполнена на основе конструкции switch-case. И здесь можно заметить что обработчик автомата можно также усложнить добавив несколько переключателей case. Заголовочный файл для автомата будет еще проще:
//файл fsm1
#ifndef LEDON_h
#define LEDON_h
#include "hal.h"
void InitLEDON(void);
void ProcessLEDON(void);
#endif
Здесь подключаем связующий файл hal.h а также указываем прототипы функций. Файл ответственный за выключение светодиода будет выглядеть практически также только в зеркальном отражении, так, что здесь я его выводить не буду — неохота 🙂 Все файлы проекта вы можете скачать вот по этой ссылке ====>>>ССЫЛКА
. Вот всего три шага и наша программа приобрела законченный вид а значит на этом моя миссия на сегодня закончена и пора закругляться. Мне кажется что информация приведенная в этой статье будет для вас очень полезно. Но настоящую пользу она принесет только тогда, когда вы будете применять это знание на практике. Кстати я запланировал ряд интересных проектов которые будут особенно интересны, так что обязательно подпишитесь на новые статьи
. Также я планирую делать рассылку дополнительных материалов, поэтому многие уже подписываются через основную страницу сайта. Подписаться можно и здесь. Ну теперь у меня действительно все, поэтому я желаю вам удачи, прекрасного настроения и до новых встреч. С н/п Владимир Васильев Языком
в алфавите
называется произвольное множество слов
этого алфавита.
Язык
, включающий все слова
в алфавите
(в том числе
и пустое слово
), будем обозначать через . Конечные автоматы часто используются для определения тех или иных свойств слов
,
т.е. для распознавания языков
: автомат, распознающий некоторый язык
L
должен
по произвольному слову
w
ответить на вопрос " ? ". Для решения такой
задачи функция выходов
может быть заменена на проверку того, в какое состояние
переходит автомат после получения входного слова
w
- "принимающее" или
"отвергающее". Определение 4.3
. Детерминированный конечный автомат (ДКА) - распознаватель
- это система вида включающая следующие компоненты: Функцию называют программой
автомата A
и задают как список из m n
команд
вида . Удобно также задавать функцию с помощью описанной выше таблицы
размера n x m
, строки которой соответствуют состояниям из Q
,
а столбцы - символам из входного алфавита
и в которой на пересечении строки q i
и столбца a j
стоит состояние . Как и автоматы-преобразователи
, автоматы- распознаватели
можно представлять
с помощью размеченных ориентированных графов, называемых диаграммами
. Определение 4.4
. Диаграмма ДКА
- это
ориентированный (мульти)граф D A =(Q, E)
с помеченными ребрами,
в котором выделена вершина- начальное
состояние
q 0
из каждой вершины
выходит ребер, помеченных символами
так, что для каждой и каждого символа имеется единственное ребро
из q
в вершину
с меткой a
. Скажем, что представленный последовательностью
ребер путь p=e 1 e 2 ... e t
в диаграмме
несет слово
w=w 1 w 2 ... w t
,
если w i
- это метка ребра e i (1 >= i >= t)
. Если q
- начальная вершина (состояние)
этого пути, а q"
- его заключительная вершина, то будем говорить, что слово
w
переводит q
в q"
. Работа конечного автомата-распознавателя
состоит в чтении входного слова
и изменению состояний в зависимости от его символов. Определение 4.5
. Назовем конфигурацией ДКА
произвольную пару вида (q, w)
, в которой и . На множестве конфигураций
введем отношение перехода за один шаг : Если , то положим для каждого : . Через обозначим рефлексивное и транзитивное замыкание
. Содержательно, означает, что автомат A
, начав работу в состоянии q
на слове
w=w 1 ... w l
, через некоторое конечное число шагов 0 <= k <= l
прочтет первые k
символов слова
w
и перейдет
в состояние q"
, а w" =w k+1 ... w l
- это непрочтенный остаток слова
w
. Определение 4.6
.
ДКА A
распознает (допускает, принимает) слово
w
, если для некоторого Т.е. после обработки слова
w
автомат переходит в принимающее состояние. Язык
L A
, распознаваемый (допускаемый, принимаемый) автоматом
A
, состоит из всех слов
, распознаваемых этим автоматом. Элементы теории автоматов
План:
1. Понятие автомата, принцип работы автомата 2. Способы задания конечных автоматов 3. Общие задачи теории автоматов Теоретические сведения
Человек всегда стремился к тому, что бы облегчить свой труд, заставляя работать на себя некоторые механические устройства без собственного вмешательства. Вначале это были сказки, затем они стали превращаться в обыденные вещи. Автомобиль, телевизор, стиральные машины, целые производства работают без участия человека. Причем, вмешательство человека в большинстве случаев не требуется, а в ряде случаев, такое вмешательство может привести к негативным явлениям. Понятие «автомат», как некоторое устройство, выполняющее определенный вид действий давно трактуется людьми именно так. Понятие автомата, принцип работы автомата
Понятие автомат
рассматривается в двух аспектах: 1. Автомат – устройство
, выполняющее некоторые функции без непосредственно участия человека. Автомат это реальное устройство, понятное, почему и как оно работает, хотя бы для тех людей, которые его сконструировали и изготовили. Автомобиль, трактор, самолет, светофор, телевизор, телефон – все это автоматы. В этом аспекте ЭВМ следует понимать как автомат, который работает по программе, составленной человеком. 2. Автомат – математическое понятие
, обозначающее математическую модель реальных технических устройств. Автомат это абстрактное устройство, непонятно почему и как оно работает и, вообще, почему оно может работать. В этом аспекте автомат есть «черный ящик», который теоретически способен проводить некоторые действия. С точки зрения математики, абсолютно неважно что, как и почему производит те или иные действия. Любой автомат должен иметь некоторое количество входов, некоторое количество выходов и некоторое количество внутренних состояний. Алгебраическая теория автоматов является разделом теоретической кибернетики, который изучает дискретные автоматы с абстрактной алгебраической точки зрения. Общая теория автоматов содержит различные подразделы. В зависимости от предмета изучения она делится на абстрактную теорию автоматов и структурную теорию автоматов. Абстрактная теория автоматов
изучает переходы, совершаемые автоматом, на который воздействуют входные сигналы, а также выходные сигналы как результат этих переходов. Предметом изучения структурной
теории автоматов является структура автомата, а также структура входных и выходных сигналов, например, способы кодирования входных и выходных сигналов и др. Определение конечных автоматов
Автомат
-
абстрактная модель устройства, функционирующего в дискретном времени, которая перерабатывает конечную последовательность входных сигналов и превращает их в конечную последовательность выходных сигналов (реакций). В процессе работы конечного автомата происходит последовательная смена конечного число его внутренних состояний, причем состояние автомата в определенный момент времени однозначно определяется входным и выходным сигналами. Такие автоматы представляют собой основу всей современной вычислительной техники и всевозможных дискретных систем автоматического контроля и управления. Понятие автомата настолько абстрактное, что трудно сказать, когда человек вообще обходился без каких либо автоматов. Под определение автомата подходят любые устройства, в том числе те, которыми первобытные люди охотились или метали камни, защищая свое жилище от неприятеля. Алгоритм
– понятное и
точное формальное предписание исполнителю, однозначно определяющее содержание и последовательность операций, переводящих заданную совокупность исходных данных в искомый результат Считается, что первым программным устройством, созданным человеком, были часы. Часовые механизмы с помощью пружины, приводящей в действие шестеренки и кулачковые механизмы, зубчатые колеса и рычаги, осуществляют ряд определенных действий. Примером такого часового механизма могут быть знаменитые часы на Центральном театре кукол в Москве, где он приводит в действие двенадцать сказочных героев, расположенных на циферблате. Укажем несколько любопытных исторических фактов, связанных с автоматами, как механическими устройствами. 1. Немецкий философ и алхимик Альберт Великий с 1216 по 1246 г., создавал «железного» слугу - автомат, который выполнял в доме обязанности привратника. 2. Астроном Иоганн Мюллер (Региамонтан) (1436-1476) создал механического орла, который приветствовал наклоном головы и движением крыльев въезд в Нюрнберг императора священной Римской империи Максимилиана II. 3. Механик Жак де Вакансон (1709-1782) – автор первого в мире автоматического ткацкого станка. Он создал образ механической утки, точной копии своего живого двойника - плавала, чистила перья, глотала с ладони зерна. Его механический флейтист, исполнявший одиннадцать музыкальных пьес, поражал людей, живших в те далекие годы. 4. Русский изобретатель 19 в. А. М. Гамулецкий создал целый механический кабинет, в котором было множество сконструированных им автоматов. Здесь в том числе была и говорящая голова чародея и амур, играющий на арфе, которые поражали воображение современников. 5. Первый примитивный арифмометр сконструировал в 1641 г. Блез Паскаль. Толчком для открытия были мучения его отца – налогового,
инспектора, который днями и ночами работал с большими вычислениями. Изобретя арифмометр, восемнадцати летний сын избавил отца от сложных вычислений, а миру подарил первый калькулятор, производящий сложение и вычитание чисел. 6. Первый шахматный автомат был построен в 1890 г. испанским инженером Торресом Кеведо. Такой автомат мог разыграть лишь ладейный эндшпиль (король и ладья против короля). 7. Первую вычислительную машину с автоматическим управлением создал Чарльз Баббедж в 1822 г. Он спроектировал арифмометр
, который имел запоминающие и арифметические устройства. Эти устройства стали прототипами аналогичных устройств современным ЭВМ. Виды автоматов.
Автомат можно трактовать как
устройство, выполняющие процессы приема, преобразования и передачи энергии, материалов или информации в соответствии с заложенной в них программой, но без непосредственного участия человека. Любой автомат имеет собственные базовые множества,
которые включают в себя:алфавит входа, алфавит выхода, множество состояний автомата. Характерной особенностью конечного автомата является наличие памяти,
которая определяет состояние автомата в зависимости от времени. Внешним проявлением различных состояний автомата является его реакция на однотипные воздействия (сигналы). В работе конечных цифровых автоматов важным понятием является время.
Автоматы можно классифицировать по различным признакам. 1. По виду деятельности
-
автоматы делятся на: информационные, управляющие и вычислительные. К
информационным автоматам
относятся разнообразные справочные таблицы, информационные табло на стадионах, устройства аварийной сигнализации. К управляющим автоматам
принято относить устройства для управления некоторым процессом, в том числе конкретно: лифтом, конвейером, станком, шлагбаумом. К вычислительным автоматам
относятся микрокалькуляторы, процессоры в ЭВМ и иные устройства, выполняющие вычисления. Однако, строго говоря, многие, автоматы представляют собой настолько сложные системы, что они являются одновременно и вычислительными, и управляющими, и информационными автоматами. 2. Конечные автоматы –
с точки зренияинформатики это такие автоматы, которые представляют собой дискретные преобразователи информации. К ним относятся преобразователи, в которых содержится конечное множество входных и конечное выходных сигналов, а также конечное множество внутренних состояний 3. Цифровые автоматы
- автоматы, которые преобразует цифровую
информацию. В таком автомате входные сигналы задаются в виде конечного множества мгновенных символов: их длительность настолько мала, что ею можно пренебречь. За фиксированное время происходит преобразование входных символов, а на выходе происходит скачкообразный переход из одного состояния в другое состояние. 4. Абстрактные автоматы -
отображающие множество слов входного алфавита Х
во
множество слов выходного алфавита Y.
Абстрактный автомат есть: ~ Математическая
модель, ~ Алгоритм
действия некоторого преобразования кодовых последовательностей, ~ Закон
преобразования входного алфавита в выходной. 5. Синхронные и асинхронные автоматы
.
В зависимости от того, одновременно или последовательно принимаются входной сигнал и сигнал смены состояний, автоматы делятся насинхронные и асинхронные автоматы. В синхронных автоматах
продолжительность входных сигналов и время переходов согласовано между собой. Они используются в вычислительных комплексах, АСУ и т.д. В асинхронных автоматах
продолжительность входных сигналов и время переходов не согласовано между собой. Они зависят от внешних источников - различных событий, а интервал дискретности
является переменным (например, в кодовых замках). В асинхронных автоматах очередное изменение значений входных сигналов может произойти только при условии, что закончился переходный процесс, вызванный предыдущим изменением этих сигналов. 6. Автоматы делятся на конечные и бесконечные автоматы.
Если в основании классификации лежит объем памяти,
то различие заключается в том, имеет ли автомат конечное
или бесконечное
число внутренних состояний. Под бесконечным
автоматом обычно понимают определенную математическую идеализацию представлений об автомате, имеющую бесконечное число состояний. Память такого автомата потенциально может неограниченно возрастать. Например, известные абстрактные автоматы Поста и Тьюринга являются бесконечными автоматами, но сама ЭВМ или ее отдельные части - конечными автоматами. 7. Автоматы делятся на детерминированные и вероятностные автоматы
. Если в основании классификации лежит механизм случайного выбора,
то различают детерминированные и вероятностные (стохастические) автоматы. В детерминированных автоматах
поведение и структура в каждый момент времени однозначно определены текущей входной информацией и состоянием самого автомата в предшествующий момент времени. В вероятностных автоматах эта зависимость связана еще и с некоторым случайным выбором. Вероятностный
автомат - это дискретный преобразователь информации, функционирование которого в каждый момент времени зависит только от состояний памяти и описывается статистическими законами. 8. Универсальный автомат.
В теории автоматов доказано, что для выполнения различных преобразований информации достаточно построить универсальный
автомат с помощью программы и соответствующего кодирования, способный решать любые задачи. Математическая модель цифрового автомата с одним входом задается пятью объектами: X-
конечное множество входных символов, входной алфавит: Х= {x 1 (t), x 2 (t), …, x n (t)}; Y-
конечное множество выходных символов, выходной алфавит: У={y 1 (t), y 2 (t), …, y n (t)}; Q ~
конечное множество состояний автомата: Q= {q 0 (t), q 1 (t), q 2 (t), …, q n (t)}, q 0
- начальное состояние; δ(q, х
)
- функция перехода автомата из одного состояния в другое: (Q
х X)
®Q; λ(q, х
) ~
функция выхода автомата: (Q
x Х) ® Y.
Таким образом, конечный автомат С= (X, Q,
У, δ, λ.) определяется рекуррентными соотношениями q(0) = q 0 , q(t + I) = δ (g(t), х(t)), y(t) = λ (g(t), х(t)), t- дискретизированный момент времен или это есть образ монотонной функции t
:. Т
® N, причем Т -
обычное непрерывное время, N - множество натуральных чисел. Все время работы Т
разбивается на конечное число интервалов, на границе которых происходит изменение состояния автомата. При этом t(Г 0) – показывает число изменений, произошедших до момента времени Г 0 . Примером дискретизации служит обычный кинематограф: время разбито на интервалы длительностью 1/24с. Человеческий глаз воспринимает следование дискретных кадров как непрерывное движение. 9. Синхронные автоматы делятся на автоматы Мили и автоматы Мура
. В зависимости от способа организации функции выхода
синхронные автоматы делятся на автоматы Мили (автоматы I рода) и автоматы Мура(автоматы II рода). В автоматах Мили
- выходной сигнал y
(t)
x
(t)
и состоянием q
(t-
1) автомата в предшествующий момент времени (t-
1). Математической моделью таких автоматов служит система уравнений: q(t) = δ (q(t-1), х(t)) и y(t) = λ (q(t-1), х(t)), В автоматах Мура
выходной сигнал y
(t)
однозначно определяется входным сигналом x
(t)
и состоянием q
(t)
в данный момент времени t. Математической моделью таких автоматов является система: q(t) = δ (q(t-1), х(t)) и y(t) = λ (q(t)), В таких автоматах функция выхода зависит только от состояний автомата в данный момент времени и не зависит от входного сигнала. Таким образом, входная строка такого автомата однократно считывается слева направо, осуществляя поочередный просмотр символов. В определенный момент времени конечный автомат находится в некотором внутреннем состоянии, которое изменяется после считывания очередного символа. Новое состояние можно охарактеризовать считанным символом и текущим состоянием. 10. Комбинационные автоматы
– есть автоматы, в которых выходной символ не зависит от его состояния и определяется лишь текущими входными символами, т.е. в этом автомате все состояния эквивалентны. В таком автомате вырождена функция перехода, она принципиально не важна и в процессе функционирования неизменна. Поэтому минимальный комбинационный автомат имеет лишь одно состояние. 11 Логические
автоматы – есть автоматы у которых входной алфавит состоит из 2 т
двоичных наборов длины т,
а выходной - из 2 n двоичных наборов длины п.
Для логических комбинационных
автоматов функция выхода имеет вид системы п
логических функций от т
переменных.