Данная глава посвящена описанию автоматного программирования в том виде, в котором оно было предложено в работах Автоматное программирование в таком традиционном понимании было названо в этих работах программированием с явным выделением состояний. Более точным названием было бы процедурное программирование с явным выделением состояний, поскольку описываемая разновидность автоматного программирования сочетает в себе концепции автоматного подхода (разделение сложного поведения на логику и семантику, применение конечных автоматов для описания логики) и технику традиционного процедурного программирования. Автоматное программирование невозможно без поддерживающей его графической нотации, поскольку именно графическое описание автоматов позволяет сделать логику системы понятной. Читатель отчасти уже знаком с нотацией графов переходов конечных автоматов. Она была представлена в параграфе 1.3 при описании машины Тьюринга, реализующей функцию инкремент, и использована в разделе 1.4.2 при обсуждении счетного триггера и последовательного двоичного одноразрядного сумматора. В этой главе графы переходов применяются как наглядные иллюстрации уже в параграфе 2.1 при описании основных концепций автоматного проектирования. Подробное описание нотации приведено в параграфе 2.2, который полностью посвящен языку спецификации, применяемому в автоматном программировании. Параграф 2.3 посвящен вопросам реализации автоматов и систем со сложным поведением в целом с использованием традиционных процедурных языков программирования. Наиболее близкий аналог описываемого подхода — метод под названием Statemate, который был предложен Д. Харелом и М. Полити в книге Далее в этой главе приводятся сравнения программирования с явным выделением состояний и метода Statemate по нескольким параметрам. Во избежание неоднозначности опишем вкратце, что понимается в этой книге под процедурным программированием. Легче всего определить эту парадигму от противного: это не декларативное, не функциональное и не объектно-ориентированное программирование, причем с практической точки зрения наиболее важным является последнее противопоставление. Для последующего обсуждения интерес представляют две главные черты процедурного стиля: использование подпрограмм (процедур, функций) в качестве модулей, составляющих архитектуру программной системы, и функциональная декомпозиция сверху вниз как основной метод проектирования. Проектирование сверху вниз начинается с максимально общего и краткого ответа на вопрос «Что делает система?» Далее шаг за шагом описания действий системы уточняются: каждое из них заменяется последовательностью, условием или циклом, в которых участвуют действия, находящиеся на более низком уровне абстракции (рис. 2.1). Процесс заканчивается, когда на очередном шаге описания всех действий оказываются на достаточно низком уровне абстракции, допускающем непосредственную реализацию с помощью примитивов языка программирования или имеющихся библиотек. На этапе реализации все действия превращаются в подпрограммы (процедуры и функции). Подпрограммы, соответствующие действиям более высокого уровня абстракции, вызывают подпрограммы более низкого уровня. Наконец, самый абстрактный ответ на вопрос «Что делает система?» становится главной программой системы.