- •1.Введение
- •1.1.Декомпозиция и абстракция
- •1.2.Абстракция
- •1.2.1.Абстракция через параметризацию
- •1.2.2.Абстракция через спецификацию
- •1.2.3.Виды абстракций
- •3.Процедурная абстракция
- •3.2.Спецификации
- •3.3.Спецификации процедурных абстракций
- •3.4.Реализация процедур
- •3.5.Более обобщенные процедуры
- •3.6.Создание процедурных абстракций
- •3.7.Заключение
- •4.Абстракции данных
- •4.1.Спецификации для абстракций данных
- •4.2.1.Реализация на языке clu
- •4.2.2.Замечания по поводу операций up и down
- •4.3.Использование абстракций данных
- •4.4.Реализация полиномов
- •4.5.Пояснения для понимания реализаций
- •4.5.1.Функция абстракции
- •4.5.2.Инвариант представления
- •4.6.3.Сохранение инварианта представления
- •4.5.4.Изменяемые представления
- •4.6.Параметризованные абстракции данных
- •4.7.Списки
- •4.8.Упорядоченные списки
4.1.Спецификации для абстракций данных
Точно так же, как и для процедур, значение типа не должно задаваться никакой его реализацией. Вместо этого должна иметься определяющая его спецификация. Так как объекты типа используются только вызовом операций, основная часть спецификации посвящена описанию того, что эти операции делают. Общий вид спецификации представлен на рис. 4.1.Он состоит из заголовка, определяющего имя типа и имена его операций, и двух главных секций —секции описания и секции операций.
dnarne = data type is %список операций Списание
%Здесь приводится описание абстракции данных Операции
%Здесь задаются спецификации для всех операцийend dnarne Рис. 4.1.Общий вид спецификации абстракции данных.
Всекции описаниятип описывается как целое. Иногда там дается модель для объектов, т. е. объекты описываются в терминах других объектов —таких, которые по предположению понятны тем, для кого эта спецификация предназначена. Например, стеки могут быть описаны в терминах математических последовательностей. В секции описания должно также говориться, изменяемый или неизменяемый это тип.
Всекции операцийсодержатся спецификации для всех операций. Если операция —процедура, то ее спецификация будет процедурной спецификацией. (Операция также может быть абстракцией через итерацию. Об этом мы будем говорить в гл. 5.) В этих спецификациях могут использоваться концепции, введенные в секции описания. '
На рис. 4.2представлена' спецификация абстракции данныхintset.Наборы целых чисел intset —это неограниченные множества целых чисел с операциями создания нового, пустого набора, проверки данного целого числа на принадлежность данному набору intsetи добавления или удаления элементов. Заметим, что в секции описания мы описали наборы целых чисел в терминах математических наборов. Там же мы отметили, что наборы целых чисел —изменяемые, и перечислили все изменяющие операции. В секции операций мы задали каждую операцию в тер-
минах математических наборов. Заметим, что спецификации операций insertи deleteиспользуют обозначение Spo^,что указывает на значение sпри возврате из операции. Имя входного аргумента без квалификатора postвсегда обозначает значение при вызове операции.
intset = data type is create, insert, delete, member, size, choose Описание
Наборы целых чисел intset —это неограниченные математические множества целых чисел. Наборы целых чисел изменяемые: операции insertи deleteдобавляют и удаляют целые числа из набора,
Операции
create = proc ( ) returns (intset) effectsВозвращает новый, пустой набор intset
insert = proc (s: intset, x: int) modifies s
effectsДобавляет xк элементам s;после добавления —возврат,Spogt==s (J {x},где Spost—это набор вначений в sпри возврате изinsert.
delete == proc (s: intset, x: int)
modifies s effectsУдаляет xиз s(т. е, Spost = s — {x}).
member = proc (s: intset, x: int) returns (bool) effectsВозвращает значение true,если x ^ s,
size = proc (s: intset) returns (int) effectsВозвращает число элементов в s.
choose == proc (s: intset) returns (int) requiresнабор sне пуст.effectsВозвращает произвольный элемент s.
end intset Рис. 4.2.Спецификация типа данных intset.
В этой спецификации мы полагаемся на то, что читателю известно, что такое математические наборы; в противном случае спецификация не будет понятна. В общем случае неформальное описание —слабое место неформальных спецификаций. Разумно, конечно, ожидать, что читатель знаком с определенными математическими концепциями (например, с наборами, последовательностями и целыми числами), однако не все типы могут быть хорошо описаны в терминах таких концепций. Если концепции неадекватны, мы должны описать тип настолько хорошо, насколько возможно, даже с использованием рисунков, но тем не менее все равно остается опасность, что читатель не поймет описания или истолкует его в другом, чем мы имели в виду, смысле. Как мы увидим в гл. 10,этой слабости можно избежать, если использовать формальные спецификации.
На рис. 4.3представлена спецификация типа данных poly. Полиномы poly —это неизменяемые полиномы с целыми коэффициентами. Предоставляются операции для создания одночленного полинома, для сложения, вычитания и умножения полиномов, а также для проверки двух полиномов на равенство.
poly == data type is create, degree, coeff, add, mul, sub, minus, equal Описание
Полиномы poly —это неизменяемые полиномы с целыми коэффициентами,Операции
create ==аргос (с, n: int) returns (poly) requiresп$г О
effectsВозвращает полином сх". Например,poly$create (6.3) == W poly$create (3.0) = 3 poly$create (0, 0) ==О
degree = proc (p: poly) returns (int)
effectsВозвращает степень p,т. e.наибольшую степень при ненулевом коэффициенте. Степень нулевого полинома равна 0.Например,poly$degree(х» + 1) = 2 poly$degree (17) =О
coeff = proc (p: poly, n: int) returns (int) requires n^- 0
effectsВозвращает коэффициент члена pсо степенью n. Возвращает 0,если nбольше степени р. Например,poly$coeff(x»+2х+ 1,4)=0poly$coeff(x»+ 2х+ 1,1)=2
add = proc (p, q: poly) returns (poly) effectsВозвращает полином, являющийся суммой полиномов р и q.
mul = proc (p, q: poly) returns (poly)
effectsВозвращает полином, являющийся произведением полиномов Р и Я-
sub = proc (p, q: poly) returns (poly) effectsВозвращает полином, являющийся разностью полиномов р и q«
minus = proc (p: poly) returns (poly)
effectsВозвращает полином, являющийся разностью полиномов zи р, где z —нулевой полином.
equal^= proc(р, q: poly) returns (bool)
effectsВозвращает значение true,если р и qимеют одинаковые коэффициенты при соответствующих членах, и значение false —в противном случае.
end poly Рис. 4.3.Неформальная спецификация абстракции данных для полиномов.
4.2.Реализация абстракций данных
Для реализации типа данных мы выбираем представление для объектов и реализуем операции в терминах этого представления. Выбранное представление должно предоставлять возможности для довольно простой и эффективной реализации всех операций. Кроме того, если некоторые операции должны выполняться быстро, представление должно предоставлять и эту возможность. Часто представление, обеспечивающее быструю работу некоторых операций, приводит к тому, что другие операции выполняются медленно. В этом случае мы должны использовать несколько различных реализаций одного и того же типа.
Например, возможное представление для объекта intset — это массив целых чисел, где каждое целое число набора intset соответствует элементу массива. Мы должны решить —должен ли каждый элемент набора встречаться в массиве только один раз или же он может встречаться много раз. В последнем случае операция insertбудет работать быстрее, однако операции delete и memberбудут выполняться медленнее. Если операция memberиспользуется часто, мы должны остановиться на первом случае.
Заметим, что здесь мы говорим о двух разных типах: новом абстрактном типе intset,который мы реализуем, и массиве целых, который используется как представление. Каждая реализация будет иметь два таких типа:абстрактный типитип представления (rep type).Предполагается, что с типом представления мы имеем дело только при реализации. Все, что мы можем делать с объектами абстрактного типа, —это применять к ним соответствующие данному типу операции. Соблюдение этого ограничения в языке CLUосуществляется с помощью контроля типов.
В следующем разделе мы рассмотрим, как реализовать абстракции данных на языке CLU,о том же, как реализовать типы на других языках, мы поговорим в гл. 7и 15.