
- •Глава 6. Симула - универсальный процессо-ориентированный язык моделирования
- •Классы и объекты
- •Декларации класса
- •Подклассы
- •Объекты. Создание и средства доступа к атрибутам объекта
- •2.3. Средства доступа е атрибутам объектов
- •Квазипараллельное выполнение
- •Оператор detach (открепить)
- •Оператор resume (возобновить)
- •Выход через «end» объекта
- •Операторы перехода
- •Обработка упорядоченных множеств
- •Планирование процессов. Системный класс simulation
- •Статистические аспекты языка симула
- •Общая структура программы моделирования
- •Программное моделирование работы карьера
- •Описание классов
- •Текст программы
- •Ввод-вывод в симула
- •Понятие текста
- •Text array таблица [1:n];
- •Создание текстовых объектов
- •Процедуры работы с частью текста
- •Процедуры обработки текстов
- •Взаимное преобразование текстовых и арифметических значений
- •Сравнение текстов
- •Организация ввода – вывода
- •Процедуры ввода
- •Процедуры вывода
- •Контрольные вопросы и задания Литература
Оператор resume (возобновить)
Оператор resume формально является процедурой с одним параметром типа ссылок на объект, квалифицированным некоторым фиктивным классом, объемлющим все классы.
Пусть фактический параметр оператора resume ссылается на некоторый самостоятельный объект Y, являющийся компонентой некоторой квазипараллельной системы S. Согласно правилам языка на Y можно сослаться только изнутри экземпляра блока (назовем его X), являющегося компонентой той же системы S или вложенного в некоторую компоненту этой системы. Экземпляр блока X является в данный момент работающим. Оператор resume производит следующие действия:
ВУ системы S покидает X. В результате сам X и все работающие компоненты на более высоких уровнях системы удаляются из работающей цепочки. ЛУ каждой компоненты останавливается в конце оператора resume;
ВУ системы S входит в Y на текущую позицию его ЛУ. В результате Y и, возможно, последовательность компонент на более высоких уровнях системы становятся работающими.
Если фактический параметр оператора resume не ссылается на самостоятельный объект, то при выполнении оператора выдается сообщение об ошибке.
Выход через «end» объекта
Результат того, что УП выходит через замыкающий символ end объекта, совпадает с действием оператора detach с тем отличием, что объект становится завершенным (а не самостоятельным) и, таким образом, теряет свое ЛУ.
Операторы перехода
Результатом выполнения оператора перехода, передающего управление из данного объекта в некоторую точку вне него, является то, что УП покидает объект, который становится завершенным.
На любой оператор перехода накладывается следующее ограничение: он может передавать управление только в точку программы внутри какого-нибудь работающего экземпляра блока. Из этого ограничения следует, что оператор перехода, передающий управление из самостоятельного объекта, означает также выход из минимального объемлющего блока с префиксом.
Обработка упорядоченных множеств
Для обработки упорядоченных множеств в языке СИМУЛА существует специальный системный класс SIMSET. Рассмотрим этот класс.
Класс SIMSET содержит средства обработки циклических двунаправленных списков, которые называются наборами.
Ссылочные переменные и процедуры, необходимые для манипулирования с наборами, вводятся в стандартных классах, декларированных внутри класса SIMSET, используя эти классы в качестве префиксов. Можно включать соответствующие данные и другие свойства в сами объекты.
Наборы и объекты, которые могут становиться членами наборов, должны иметь ссылки на преемника и предшественника. Поэтому они сделаны объектами подклассов класса LINKAGE.
Наборы представлены объектами, принадлежащими подклассу HEAD класса LINKAGE. Объекты, которые могут быть членами наборов, принадлежат к подклассам класса LINK, который в свою очередь сам является другим подклассом класса LINKAGE.
Переменная SUC является ссылкой на преемника (SUCCESSOR) данного объекта (класса LINKAGE) в наборе, а переменная PRED является ссылкой на предшественника (PREDECESSOR). Значение ссылок SUC и PRED можно получить посредством процедур SUC и PRED, эти процедуры доставляют значение ‘NONE’, если указанный объект не может быть членом никакого набора (т.е. не принадлежит ни к классу LINK, ни к подклассу этого класса).
Атрибуты SUC и PRED можно модифицировать только посредством процедур, определенных внутри классов LINK и HEAD, это помогает пользователю избежать некоторых ошибок при программировании.
Объекты, принадлежащие к подклассам класса LINK, могут становиться членами наборов. В каждый данный момент объект может быть членом только одного набора.
В дополнении к процедурам SUC и PRED имеются еще четыре процедуры, связанные с каждым объектом класса LINK:
OUT, FOLLOW, PREORE И INTO.
Процедура OUT удаляет объект из набора, членом которого он является (если объект имеет членство в наборе). Если объект не состоит ни в каком наборе, то вызов процедуры OUT не влечет за собой никаких последствий.
Процедуры FOLLOW и PREORE удаляют объект из набора, членом которого он является (если объект имеет членство в наборе), и вставляют его в некоторый набор в указанную позицию. Набор и позиция задаются параметром типа REF (LINKAGE). Если этот параметр имеет значение 'NONE’, или не имеет членства в наборе, или не является головой набора, то вызов процедур FOLLOW и PREORE имеет тот же эффект, что и вызов OUT, в противном случае объект включается непосредственно вслед за или непосредственно перед тем объектом класса LINKAGE, на который указывает параметр.
Процедура INTO, которая имеет параметр типа REF (HEAD), удаляет объект из набора, членом которого он является, и включает его в качестве последнего члена в набор, указанный параметром.
Определение класса HEAD.
Объект класса HEAD или подкласса класса HEAD служит для представления набора. Процедуру FIRST можно использовать для того, чтобы получить ссылку на первый член набора, а процедуру LAST – на последний. Логическая процедура EMPTY доставляет значение ‘TRUE’, если набор не имеет членов. Значением процедуры CARDINAL является количество членов набора, процедурой CLEAR можно воспользоваться для удаления всех членов из набора.
Рассмотрим применение наборов и процедур, определенных в классе SIMSET, для отображения и обработки иерархических древовидных структур объектов [1]. Узлы дерева удобно отображать с помощью объектов, которые можно включать в наборы, т.е. объектов, принадлежащих подклассу класса LINK. Ветви дерева, исходящие из некоторого узла, можно представить набором, членами которого являются объекты, соответствующие узлам следующего яруса, связанным с этим узлом. Дополнительная информация, характеризующая узлы дерева, может представляться значениями атрибутов соответствующих им объектов.
Таким образом, объекты, отображающие узлы дерева, могут быть описаны следующей декларацией класса:
LINK ‘CLASS’ УЗЕЛ (НОМЕР); ‘INTEGER’ НОМЕР;
‘BEGIN’ ‘REF’ (HEAD) ВЕТВИ; ‘INTEGER’ M;
ВЕТВИ:- ‘NEW’ HEAD;
‘END’ УЗЕЛ;
В данном примере предполагается, что каждый узел характеризуется дополнительно двумя целыми числами: порядковым номером (атрибут номера) и номером яруса, в котором он находится (атрибут М).
Опишем в виде рекурсивной процедуры один из возможных алгоритмов генерации дерева из К узлов. Алгоритм генерирует узлы дерева в порядке возрастания их номеров и включает каждый из них в набор ветви соответствующего узла верхнего яруса.
1
5
2
3
4
РИС. 2.1.
Нумерация вершин дерева и их генерации производится в направлении “сверху - вниз” и “слева - направо”. Будем считать, что количество ветвей для узла с номером 1 задано в 1-м элементе массива КОЛВЕТВЕЙ [1; К]. Например, для генерации дерева (РИС. 2.1. числа обозначают их порядковые номера).
Элементы массива КОЛВЕТВЕЙ должны иметь такие значения: 2, 2, 0, 0, 0. Введем глобальные переменные КОРЕНЬ и ТН для обозначения корня дерева и текущего номера генерируемого узла. Далее дан фрагмент СИМУЛА-ПРОГРАММЫ, который производит генерацию дерева, узла которого отображаются объектами класса узел:
‘INTEGER’ КОЛВЕТВЕЙ [1; K]; ‘INTEGER’ TH;
‘REF’ (УЗЕЛ) КОРЕНЬ;
‘PROCEDURE’ СВЯЗАТЬ (У); ‘REF’ (УЗЕЛ) У;
‘BEGIN’ ‘INTEGER’ KB; KB:= КОЛВЕТВЕЙ [У, НОМЕР];
‘FOR’ KB:= KB - 1 ‘WHILE’ KB=>0 ‘DO’
‘BEGIN’ ‘REF’ (УЗЕЛ) НОВЫЙ; ТН:= ТН + 1;
НОВЫЙ:- ‘NEW’ УЗЕЛ (ТН);
НОВЫЙ, INTO (У, ВЕТВИ); СВЯЗАТЬ (НОВЫЙ);
‘END’
‘END’ СВЯЗАТЬ;
КОРЕНЬ:- ‘NEW’ УЗЕЛ 1; ТН:- 1; СВЯЗАТЬ (КОРЕНЬ);
В качестве примера обработки иерархических структур рассмотрим процедуру, выполняющую обход всех узлов дерева и помечающую каждый узел целым числом, равным номеру яруса этого узла. Будем считать, что узлы дерева представлены объектами класса УЗЕЛ, и номер яруса нужно занести в атрибут М каждого объекта.
Опишем процедуру ЯРУС (K, L), которая выполняет указанную пометку для узлов поддерева с конем К, распложенным на ярусе L.
‘PROCEDURE’ ЯРУС (K, L); 'REF' (УЗЕЛ) K; ‘INTEGER’ L;
‘BEGIN’ ‘REF’ (УЗЕЛ) Т;
K, M:=L;
T:- K, ВЕТВИ, FIRST;
‘WHILE’ T =/= ‘NONE’ ‘DO’
‘BEGIN’ ЯРУС (T, L+1); T:- T.SUC;
‘END’ ПОМЕТКИ ЯРУСА (L+1);
‘END’ ЯРУС;
Имея процедуру ЯРУС, пометку узлов (РИС. 2.1.) можно выполнить с помощью оператора ЯРУС (КОРЕНЬ.1).