- •4.9.1. Изменяемость
- •4.9.2. Классы операций
- •98 Глава 4
- •4.9.3. Полнота
- •100 Глава 4
- •4.9.5. Операции egual, similar и copy
- •102 Глава 4
- •104 Глава 4
- •5. Исключительные ситуации
- •108 Глава 5
- •110 Глава 5
- •6.2.1. Сигнализация об исключительных ситуациях
- •5.2.2. Обработка исключительных ситуаций
- •112 Глава 5
- •5.2.3. Предложение resignal
- •6.2.4. Необрабатываемые исключительные ситуации
- •114 Глава 5
- •6.2.3. Предложение resignal
- •5.2.4. Необрабатываемые исключительные ситуации
- •116 Глава 5
- •118 Глава 5
- •118 Глава 5
- •120 Глава 5
- •122 Глава 5
- •124 Глава 5
- •128 Глава 6
- •130 Глава 6
- •6.2.1. Реализация итераторов
- •6.2.2. Использование итераторов
- •132 Глава 6
- •134 Глава 6
- •136 Глава 6
- •138 Глава 6
- •140 Глава 7
- •142 Глава 7
- •7.2. Абстракция данных
- •144 Глава 7
- •146 Глава 7
- •148 Глава 7
- •150 Глава 7
- •7.4. Генераторы
- •162 Глава 7
- •154 Глава 7
- •156 Глава 7
- •162 Глава 8
- •164 Глава 8
- •166 Глава 8
- •168 Глава 8
- •170 Глава 9
- •172 Глава 9
- •174 Глава 9
- •176 Глава 9
- •9.1.3. Пример
- •178 Глава 9
- •180 Глава 9
- •182 Глава 9
- •184 Глава 9
- •186 Глава 9
- •188 Глава 9
- •190 Глава 9
- •192 Глава. 9
- •194 Глава 9
118 Глава 5
choose сигнализирует об исключительной ситуации, если ее аргумент пуст. Реализация представлена на рис. 5,4. Заметим, что мы изменили операцию getind, чтобы она сигнализировала об исключительной ситуации not-in, если х не принадлежит s. Этот сигнал перехватывается операцией delete, которая просто маскирует исключительную ситуацию и осуществляет нормальный возврат. Реализация операции member также маскирует исключительную ситуацию.
Реализация операции getind использует исключительную ситуацию bounds, о которой сигнализирует операция fetch для массивов, в случае если она просмотрела все элементы массива. Когда процедура getind получает этот сигнал, она сигнализирует об исключительной ситуации not_in, что является примером распространения исключительной ситуации. Другой пример распространения — процедура choose.
Реализация операции delete иллюстрирует использование необрабатываемых исключительных ситуаций. Если из процедуры getind осуществляется нормальный возврат, мы знаем, что индекс находится внутри заданных границ и что массив не пуст. Следовательно, нет необходимости следить за возникновением исключительной ситуации bounds при вызове операций top, fetch и remh для массивов.
Следующий пример —это упорядоченные списки. Удалив некоторые предложения requires и добавив исключительные ситуации в операциях addel, remel и least, мы получаем более устойчивую спецификацию. Эта результирующая спецификация представлена на рис. 5.5.
Реализация упорядоченных списков показана на рис. 5.6. Некоторые процедуры используют предложение resignal. Например, процедура addel рекурсивно обращается сама к себе по левому и правому поддеревьям; если в каком-то из этих обращений возникает исключительная ситуация dupl, происходит выполнение предложения resignal. Это предложение часто используется в рекурсивных реализациях, как, например, в нашем случае.
В качестве последнего примера рассмотрим процедуру summation, специфицированную и реализованную на рис. 5.7. Заметим, что в предложениях requires и where перечислены исключительные ситуации, связанные с процедурой add. Процедура summation использует списки, определенные на рис. 4.12, 'за исключением того, что процедуры first и rest сигнализируют об исключительной ситуации empty, если список, заданный как аргумент, пуст. Исключительная ситуация empty, возникающая при вызове list$first, маскируется; когда она возникает, все элементы списка уже просмотрены. Исключительные ситуации underflow и overflow распространяются.
Исключительные ситуации
olist=data type [t: type I is create, addel, remel, is_in, empty, least
Requires t имеет операции
It, equal: proctype (t, t) returns (bool), которые определяют упорядочение t
Описание
Упорядоченные списки olist — изменяемые списки элементов. Операции addel и remel модифицируют упорядоченный список. Операция least возвращает наименьший элемент упорядоченного списка,
Операции
create = ргос () returns (olist [t]) effects Возвращает новый, пустой список.
addel = proc (s: olist [t], х: t) signals (dupl)
modifies s
effects Если х принадлежит s, сигнализирует об исключительной ситуации dupl, иначе вставляет х в s.
remel = proc (s: olist [t], х: t) signals (notJii)
modifies s
effects Если х не принадлежит s, сигнализирует об исключительной ситуации not-in, иначе удаляет х из s.
isJn = ргос (s: olist [t], х: t) returns (bool)
effects Возвращает значение true, если s содержит какой-нибудь элемент, равный х, в противном случае возвращает значение false.
empty = ргос (s: olist [t]) returns (bool)
effects Возвращает значение true, если s не содержит элементов, и значение false — в противном случае.
least = proc (s: olist [t]) returns (t) signals (empty) effects Если s пуст, сигнализирует об исключительной ситуации empty, иначе возвращает элемент е из s, такой, что в s не существует элемента, меньшего е (как определяется l$lt).
end olist Рис, 5.5. Спецификация упорядоченных списков.
olist ^cluster [t: type] is create, addel, remel, is-in, least, empty where t has equal, It; proctype (t, t) returns (bool)
node == record [val; t, left, right: olist [t]) rep == variant [some; node, empty; null I
% Типичный упорядоченный список olist есть [el, ...,en] % Функция абстракции есть
% А (г) = [] если г пуст, % == A (n.left) II [n.val ] Ц A (n.right) если г не пуст, % где п == value-some (г)
% Инвариант представления есть % if is-some (r) then % все компоненты n.left < n.val % & n.val < всех компонентов n.right, % где n = value.some (r)
