Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
45
Добавлен:
23.03.2015
Размер:
884 Кб
Скачать

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. Это предложение часто исполь­зуется в рекурсивных реализациях, как, например, в нашем случае.

В качестве последнего примера рассмотрим процедуру sum­mation, специфицированную и реализованную на рис. 5.7. Заме­тим, что в предложениях requires и where перечислены исклю­чительные ситуации, связанные с процедурой add. Процедура summation использует списки, определенные на рис. 4.12, 'за исключением того, что процедуры first и rest сигнализируют об исключительной ситуации empty, если список, заданный как аргумент, пуст. Исключительная ситуация empty, возникающая при вызове list.$first, маскируется; когда она возникает, все элементы списка уже просмотрены. Исключительные ситуации underflow и overflow распространяются.

Исключительные ситуации

olist^data type It; type] is create, addel, remel, ii.in, empty, least

Requires t имеет операции

It, equal: proctype (t, t) returns (bool), которые определяют упорядочение t

empty

Описание

Упорядоченные списки olist — изменяемые списки элементов. Операции addel и remel модифицируют упорядоченный список. Операция least возвращает наи­меньший элемент упорядоченного списка,

Операции

create = ргос ( ) returns (olist [t ]) effects Возвращает новый, пустой список.

addel г= ргос (s: olist [t], х: t) signals (dup!)

modifies s

effects Если х принадлежит s, сигнализирует об исключительной си­туации dupl, иначе вставляет х в s.

remel == ргос (s: olist [t], х: t) signals (notJn)

modifies s

effects Если х не принадлежит s, сигнализирует об исключительной ситуации not_in, иначе удаляет х из s.

is_in = ргос (s: olist [tl, х: t) returns (bool)

effects Возвращает значение true, если s содержит какой-нибудь эле­мент, равный х, в противном случае возвращает значение false.

ргос (s: olist [t]) returns (bool)

effects Возвращает значение true, если s не содержит элементов, и зна­чение false — в противном случае.

least =- ргос (s: olist [t]) returns (t) signals (empty) effects Если s пуст, сигнализирует об исключительной ситуации empty, иначе возвращает элемент е из s, такой, что в s не существует эле­мента, меньшего е (как определяется t$lt).

end olist Рис. 5.5. Спецификация упорядоченных списков.

olist == cluster [t: type] is create, addel, remel, isJn, 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]

% Типичный упорядоченный список olist есть [el, ...,en] % Функция абстракции есть

% A (r) = [] если г пуст, % = A (n.left) [[ [n.val ] \\ A (n.right) % где n = value_some (r)

% Инвариант представления есть % if is_some (r) then % ace компоненты n.left < n.val % & n.val < всех компонентов n.right, % где n == value_some (r)

если если r не пуст,

Соседние файлы в папке POSIBNIK