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

3.2. Спецификации

Очень важно дать абстракциям четкие определения. В про­тивном случае не могут быть достигнуты преимущества, рассмо­тренные в разд. 3.1. Например, мы можем заменить одну реали­зацию абстракции на другую только в том случае, если все то, что поддерживала старая реализация, поддерживает и новая. Элементом, создающим данную зависимость, является абстрак­ция. Следовательно, мы должны знать, что она собой представ­ляет.

Мы будем определять абстракции посредством спецификаций, которые создаются на языке спецификаций, причем последний мо­жет быть как формальным, так и неформальным. Преимущество формальных спецификаций заключается в том, что они имеют точно определенное значение. Неформальные спецификации легче читать и понимать, однако точное их содержание установить затруднительно, поскольку язык неформальных спецификаций точным не является. ^Несмотря на это, неформальные специфика­ции могут быть весьма информативны и составлены таким обра­зом, что читатели без труда поймут их смысловое содержание. В нашей книге мы используем как формальные, так и неформаль­ные спецификации, однако основной акцент делается на нефор­мальных спецификациях. Формальные спецификации будут опи­саны в гл. 10.

Спецификация отлична от любой определяемой ей реализации абстракции. Все реализации сходны между собой, поскольку они реализуют одну и ту же абстракцию. Отличие их заключается в том, что это делается разными способами. Спецификация опре­деляет их схожесть.

3.3. Спецификации процедурных абстракций

Спецификация процедуры состоит из заголовка и описания функции, выполняемого процедурой. Заголовок содержит имя про­цедуры, номер, порядок и типы входных и выходных параметров. Кроме этого, выходные параметры могут, а входные должны быть поименованы. Например, заголовок для процедуры remove, dupis есть

remove_dupls == proc (a: array [int]) а заголовок для процедуры sqrt есть sqrt == proc (x: real) returns (rt: real)

Информация в заголовке чисто синтаксическая; она описывает «форму» процедуры. Это аналогично описанию «формы» математи­ческой функции:

Г: integer -> integer

Ни в одном из случаев смысл действий, выполняемых процеду­рой или функцией, не описывается. Эта информация приводится в семантической части спецификации, в которой смысл выполняе­мых процедурой действий описывается на естественном (разго­ворном) языке, возможно расширенном привычными математиче­скими обозначениями. В этом описании используются имена вход­ных и выходных параметров.

На рис. 3.2 приводится шаблон спецификации для процедуры. Семантическая часть спецификации состоит из трех предложе­ний — requires (требует), modifies (модифицирует) и effects (эф­фекты). Эти предложения должны появляться в указанном ниже порядке, однако предложения requires и modifies обязательными не являются.

рпагпе = proc (...) returns (..,)

requires % этот оператор задает необходимые требования modifies % этот оператор идентифицирует все модифицируемые входные

% данные

effects % этот оператор описывает выполняемые функции

Рис. 3.2. Шаблон спецификации для процедурных абстракций.

Предложение requires задает ограничения, накладываемые на абстракцию. Предложение requires необходимо в том случае, если процедура является частичной, т. е. если ее поведение для некоторых входных значений недетерминировано. Если же про­цедура глобальна, т. е. ее поведение определено для всех вход­ных значений, то предложение requires может быть опущено. В этом случае единственными требованиями, предъявляемыми при обращении к процедуре, являются требования, указанные в заголовке, т. е. число и типы аргументов. Оператор modifies задает список имен входных параметров, модифицируемых про­цедурой. Если входные параметры не указаны, то это предло­жение может быть опущено. Наконец, предложение effects опи­сывает работу процедуры со значениями, не охваченными пред­ложением requires. Оно определяет выходные значения и модифи­кации, производимые над входными параметрами, перечислен­ными в списке modifies. Предложение effects составляется исходя из предположения, что требования предложения requires удов­летворены. Однако в том случае, когда требования в предложе­нии requires не удовлетворены, о поведении процедуры ничего не сообщается.

concat = proc (а., Ь: string) returns (ab: string)

effects по возврату ab есть новая строка, содержащая символы из а (в том порядке, в котором они расположены в а), за которыми следуют символы из b (в том порядке, в котором они расположены в Ь), remove_dupls = proc (a: array [int])

modifies а

effects Удаляет из массива а все повторяющиеся элементы. Нижняя гра^ ница а остается без изменений, однако порядок следования оста­вшихся элементов может измениться. Если, например, перед вы­зовом а == [1: 3, 13, 3, 6], то по возвращению массив а имеет ниж­нюю границу, равную 1, и содержит три элемента 3, 13 и 6, распо­ложенных в некоторой неопределенной последовательности. search == proc(a: array [int], х: int) retunis (i; int) requires массив а упорядочен по возрастанию.

effects Если элемент х принадлежит массиву а, то возвращается значе­ние i такое, что а [i ] = х; в противном случае значение i на еди­ницу больше, чем значение верхней границы массива а.

Рис. 3.3. Спецификация процедурной абстракции.

На рис. 3.3 приведено несколько спецификаций. Процедура concat не модифицирует входные переменные, а процедура ге-move_dupls изменяет входной массив, что отмечено в предложе­нии modifies. Отметим, что в спецификации процедуры remove. dupis дается пример. Наличие примеров облегчает понимание спецификации, и их рекомендуется использовать во всех подхо­дящих случаях.

Процедуры concat и remove_dupls являются общими процеду­рами, поскольку их спецификации не содержат предложений requires. Процедура search является частичной; она выполняет свои функции только в том случае, если входной массив отсорти­рован. Отметим, что предложение effects ничего не говорит о результате работы процедуры в том случае, когда входной мас­сив не отсортирован. В этом случае составитель процедуры может выбрать любой подходящий для него вариант; например, про­цедура search может в этом случае возвращать индекс, выходящий за границы массива, или индекс, лежащий в пределах границ, но не содержащий х, или даже зацикливаться.

Спецификации составляются на языке спецификаций, а не на языке программирования. Следовательно, рассмотренные ранее спецификации написаны не на языке CLU. Кроме этого, специфи­кации обычно принципиально отличаются от программ, поскольку они фокусируют свое внимание на описании самой абстракции, а не ее реализации. Мы вернемся к описанию спецификаций.

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