Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Стили и методы программирования. Учебное пособие для СПО
.pdf
"Cat mews"
"You see an animal"
"You see your property"
"You see something"
"Cat purrs"
"Animal is close to you"
"You test your property"
"You take the thing"
"You identified this thing"
"You are pleased by your property"
"You send the animal off"
"Cat turns"
;; Loading of file E:\clisp-2000-03-06\myclasses.lsp is finished.
T
Пример 8.6.2. Результат загрузки программы 8.6.1
Видно, что упорядоченность классов по отношению наследования
позволяет выстраивать целые последовательности действий при
вызове одного метода.
Поскольку в CLOS нет ни механизмов скрытия конкретных
представлений, ни механизмов замены прямого доступа к данным на
функции, ни других характерных особенностей ООП, мы видим еще
один пример того, как модным словом (в данном случае ООП)
прикрывается другая, не менее интересная сущность: начатки
планирования действий по структуре типов данных. В связи с этим
стоит напомнить блестящий эксперимент планирования вычислений
по структуре данных, в настоящий момент (судя по всему, временно)
забытый: эстонскую систему PRIZ [28
].
Неадекватное теоретизирование мешает увидеть и развить реальные
достоинства системы и закрепляет слабые места.
1)
И уж точно первый из выживших, поскольку Plankalk l Цузе умер
вместе с его машинами.
2)
А для предотвращения хакерских трюков и нежелательно!
3)
Любезно предоставленный Л. Городней (ИСИСО РАН и НГУ)
4)
Как сделано в системе TEX-LATEX.
5)
Примером, иллюстрирующим ситуацию, может служить XML,
Стили и методы программированияНепейвода Н.Н.
141

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

Автоматное программирование: анализ задачи
Термин "автоматное программирование" принадлежит, насколько нам
известно, А.А. Шалыто. Во всяком случае, ему принадлежит заслуга его
развития вопреки моде и мнению большинства.
Автоматные задачи
Многие программистские задачи удобно решать с помощью методов,
формализацией которых могут служить таблицы состояний и переходов
(напр., их собрание см. в [32]
и на сайте ссылка: http://is.ifmo.ru).
Пример 9.1.1. Модель изменяющейся системы.
Пусть мы моделируем динамическую либо экологическую систему, у
которой в различных областях принципиально разное поведение.
Вместо того, чтобы совмещать внутри одного и того же программного
модуля анализ, какой области принадлежит точка, и вычисление
следующего состояния системы, мы можем написать несколько простых
модулей моделирования поведения системы в каждой из областей
(единственная проверка, которая при этом может понадобиться, вышли
мы при очередном шаге моделирования за границы области или нет).
Как отдельный модуль строится глобальная управляющая программа,
которая проверяет, в каком состоянии находится система, и вызывает
соответствующий вычислительный модуль.
В данном случае выигрыш не столько в длине программы, сколько в ее
обозримости и модифицируемости (хотя именно эти важнейшие
качества программы начинающие программисты чаще всего
недооценивают). Но если при входе в новую область нужно проделать
ряд организационных действий (в каждой области различных), а уже в
зависимости от их результата выбрать дальнейшую траекторию
системы, то описание в виде автомата становится все более
выигрышным.
Если при анализе задачи удается выявить набор состояний
описываемого процесса, условия перехода между состояниями и
действия, ассоциированные с состояниями, то задачу уместно решать
методами таблиц состояний. При анализе таких методов можно
Стили и методы программированияНепейвода Н.Н.
143

применять конечные автоматы Мура.
Теоретически автомат Мура представляется как матрица переходов,
строками которой служат состояния автомата, а столбцами - входные
символы
1)
. В качестве входных символов на практике можно
рассматривать результаты проверки некоторых условий. Неявное в
теории, но важнейшее на практике содержимое каждого состояния
автомата - процедура, приводящая к глобальному изменению состояния
вычислительной системы. Такие процедуры назовем действиями.
Таблицы автоматов часто также представляются в виде графов, что
особенно удобно, когда не все возможные переходы между состояниями
реализуемы. См., напр., рис. 9.1
, где представлены и таблица, и граф.
Рис. 9.1. Таблица состояний. Граф переходов.
Здесь состояния идентифицируются порядковыми номерами, а
воздействия - буквами.
На таблице состояний или на ее графовом аналоге все действия
предполагаются по умолчанию глобальными, и каждое действие
соединено с распознаванием, какое из перечисленных на выходящих из
него ребрах условий выполнено. В зависимости от того, какое из них
выполнено, автомат переходит в соответствующее состояние, которому
опять-таки, если оно не заключительное, сопоставлено действие и
распознавание.
Имеется вариация понятия автоматов, порождающая другой метод
Стили и методы программированияНепейвода Н.Н.
144

автоматного программирования. В теории автомат Мили отличается
тем, что результат, записываемый на выходную ленту автомата, может
зависеть от выбранного перехода. На практике действия в таблице
состояний и переходов могут ассоциироваться либо с состояниями (с
вершинами графа, автомат Мура ), либо с переходами (с дугами графа,
автомат Мили ). Ниже Вы увидите примеры, когда при
программировании естественно возникают оба этих варианта
2)
. Модель
вычислений автомата Мили лучше использовать, если проверки в
каждом состоянии по существу различны, а модель автоматов Мура если проверки по существу однородны, как в примере 9.1.1.Метод
программирования, когда действия сопоставляются переходам, назовем
преобразованиями на переходах (сокращенно просто "на переходах "),
метод, когда действия производятся в состояниях, назовем
преобразованиями в состояниях (сокращенно просто "в состояниях ").
Заметим, что естественно рассматривать таблицы состояний и
переходов как недетерминированные, поскольку после выполнения
действия вполне может оказаться истинно сразу несколько условий,
соответствующих выходящим ребрам.
Внимание!
В данном случае мы видим один из неистощимых источников ошибок в
программах, который впервые заметил Д. Грис. Если по сути задачи нам
все равно, какое из действий будет выполнено, а язык (как те
стандартные языки, на которых обычно работают) заставляет
детерминировать переходы, либо ранжировав их по порядку, либо
принудительно сделав их условия логически противоречивыми, то при
изменении программы часто возникают трудности. Они связаны с тем,
что после изменения детерминировать-то надо было по-другому, но уже
нельзя различить, какие из условий существенны, а какие вставлены
лишь для детерминации.
Как было показано в нашем примере, таблицы переходов и состояний
являются естественным способом программирования для модуля,
имеющего дело с глобальными операциями над некоторой средой (эти
глобальные операции сами, как правило, программируются в другом
стиле). Для автоматного программирования характерно go to, и здесь
оно на месте.
Стили и методы программированияНепейвода Н.Н.
145

Есть много конкретных методик автоматного программирования,
укладывающихся в рамки двух главных методов. Автоматное
программирование хорошо демонстрирует то, как варьируются
практические методы решения логически и математически, вроде бы,
однородных задач. Небольшое изменение в ресурсных ограничениях - и,
хотя старые методы, как правило, остаются уместными, но лучше
перейти к другим.
Основные структуры автоматного программирования
Информационное пространство всех блоков и процедур при
автоматном программировании в первом приближении одно и то же:
состояния системы, моделируемой совокупностью программных
действий. Но на самом деле многие блоки либо процедуры работают с
подсистемами. Подсистемы, ввиду их автономности, могут иметь
характеристики, прямо недоступные для общей системы, и
ограниченный доступ к общему системному пространству данных.
Более того, подсистемы могут общаться прямо, в обход иерархически
вышестоящей системы (см. рис. 9.2
). Таким образом, структура
информационного пространства при автоматном программировании в
общих чертах соответствует той, которая навязывается современными
системами с развитой модульностью
3)
. В системах модульности есть
понятия, предоставляемые для пользования другими модулями, есть
модули, которые автоматически получают доступ ко всем понятиям
дружественного модуля, и есть интерфейсы между модулями.
Стили и методы программированияНепейвода Н.Н.
146

Рис. 9.2. Информационное пространство систем
Светло-серые области - традиционный общий контекст системы и
подсистемы. Темно-серые иллюстрируют, что доступность может быть
односторонней, и не только по иерархии. Одна из систем может влиять
на часть информационного пространства другой, а та может лишь
пассивно следить, что натворил коллега. Области, связанные
двусторонними стрелками, иллюстрируют прямое общение в обход
иерархии.
Исторически первой моделью автоматного программирования,
использованной как на практике, так и для теоретических
исследований, было представление программы в виде блок-схемы (см.,
напр., рис. 9.3
), узлы которой являлись состояниями. Узлы блок-схемы
делятся на пять типов:
начальная вершина, в которую нет входов и где производится
инициализация переменных либо состояния вычислительной
системы;
действия, при которых исполняется вызов процедуры либо
оператор и после которых автомат однозначно переходит в
Стили и методы программированияНепейвода Н.Н.
147

следующее состояние ;
распознаватели, проверяющие значение переменной либо
предиката и затем передающие управление по разным адресам;
соединения, в которые имеется несколько входов и один выход;
выход, попав в который, программа заканчивает работу.
Рис. 9.3. Блок-схема
Представление программ в виде блок-схем было целесообразно для
многих классов программ, писавшихся в машинных кодах без средств
автоматизации программирования. Блок-схемы тогда были основным
средством планирования разработки программ и их документирования.
Традиционные блок-схемы - предмет изучения, в частности,
теоретического программирования (см. книги Котова [16]
, [17]).
Таблицы переходов концептуально противоречат такому
фундаментальному понятию программирования, как присваивание. В
блок-схеме произвольной формы исключительно трудно проследить,
как будет изменяться значение переменной, какие существуют
Стили и методы программированияНепейвода Н.Н.
148

зависимости между данными переменными, и т. п.
Действия в автоматном программировании глобальны, а условия
локальны. Проверка условия не изменяет состояния всей системы (ни
одного из ее параметров или характеристик), она лишь переводит саму
программу в то или иное состояние.
Это подтверждает и анализ практических систем, для моделирования
которых удобно применять автоматное программирование. Например,
открытие или закрытие одного вентиля в трубопроводной системе
изменяет все потоки в системе, а проверка - открыт ли вентиль локальная операция. Изменение температуры рабочего вещества в
системе опять-таки влияет на все ее характеристики, а измерить эту
температуру можно, сняв показания всего одного датчика.
Здесь мы сталкиваемся с необходимостью четко различать внешние
понятия, описывающие систему, которая связана с решаемой
программой задачей, и внутренние понятия самой программы. Для
системы в целом безразличны состояния автомата, который ее
моделирует либо взаимодействует с ней. Для нее важно, какие
изменения в ней самой происходят. Таким образом, состояние памяти
вычислительной системы вполне может рассматриваться как внешняя
характеристика по отношению к программе, которая в ней работает.
Необходимость одновременного и согласованного рассмотрения
внешних и внутренних характеристик приводит к тому, что, когда
внутренние характеристики раздробляются и детализируются
(например, при соединении стиля автоматного программирования с
присваиваниями), программист начинает путаться, согласованность
понятий исчезает и возникают ошибки.
Внимание!
Если пользоваться произвольными таблицами переходов, то надо
позаботиться о том, чтобы присваивания встречались как можно реже,
в идеале обойтись без них совсем либо присваивать лишь значения
переменным, которые немедленно после этого используются в качестве
основания для выбора в операторе типа case.
Граф состояний и переходов, называемый также таблицей переходов —
Стили и методы программированияНепейвода Н.Н.
149

нагруженный ориентированный граф G. Каждой вершине графа G
сопоставлено наименование состояния, а каждой дуге — условие.
Условие AB, сопоставленное дуге, ведущей из a в b, содержательно
интерпретируется следующим образом. При выполнении AB в
состоянии a управление передается состоянию b (или же в другом
смысле осуществляется переход по данной дуге).
Когда граф состояний и переходов используется для документирования
программы, наименования состояний, как правило, совпадают с
именами процедур, выполняющихся в данном состоянии.
Программные представления графа состояний
Отметим, что программные представления графа состояний сильно
зависят от динамики данного графа. Стоит выделить четыре подслучая.
1. Состояния и таблица переходов жестко заданы постановкой
задачи (например, такова задача синтаксического анализа). В этом
случае лучшее программное представление переходов между
состояниями - go to, независимо от размера таблицы.
2. Состояния и таблица переходов пересматриваются, но
фиксированы между двумя модификациями задачи. При
небольших размерах таблицы по-прежнему предпочтительней
всего реализация через переходы, а при достаточно больших необходима ее декомпозиция, в связи с чем часто целесообразно
представление состояний объектами.
3. Состояния и таблица переходов динамически порождаются перед
выполнением данного модуля и фиксированы в момент его
выполнения. Лучший способ реализации - задание таблицы
переходов в виде структуры данных и написание
интерпретирующей программы для таких таблиц.
4. "Живая таблица": модифицируется в ходе исполнения. Пока что
дать методологические советы для таких таблиц мы не можем,
хотя очевидно, что, несмотря на внешнюю рискованность, такой
путь чрезвычайно выигрышен для многих систем адаптивного
реагирования. Заранее нужно обговорить, что модули,
перестраивающие таблицу, и модули, исполняющие ее, должны
быть как можно более жестко разделены.
Стили и методы программированияНепейвода Н.Н.
150
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
