- •Информационная модель предметной области
- •Моделирование задач на эвм
- •Преобразование информации при решении задачи на эвм
- •Понятие о данных
- •Абстрактные структуры данных
- •Классификация структур данных
- •14101954
- •Абстракция
- •Лекция 6. Види та методи абстракції в програмуванні. Абстракция через параметризацию
- •Абстракция через спецификацию
- •Виды абстракций
- •Лекция 7. Процедурна абстракція. Специфікація процедурної абстракції. Процедурная абстракция
- •Спецификации
- •Спецификации процедурных абстракций
- •Реализация процедур
- •Более обобщенные процедуры
- •Создание процедурных абстракций
- •Заключение
- •Лекция 8. Абстракція даних Абстракции данных
- •Спецификации для абстракций данных
- •Реализация на языке clu
- •Замечания по поводу операций up и down
- •Использование абстракций данных
- •Лекция 9. Реалізація абстракції даних. Функція абстракції. Функція інваріант подання.
- •Функция абстракции
- •Инвариант представления
- •Сохранение инварианта представления
- •Изменяемые представления
- •Параметризованные абстракции данных
- •Будем искать решение нашей задачи в виде цикла, имеющего следующий вид:
Реализация на языке clu
Хотя, конечно, возможно реализовать типы на языках, которые специально не приспособлены для этой цели, более удобно, если тип может быть реализован как отдельный программный модуль. Язык CLUпредоставляет такую программную единицу. Эта единица называетсякластер. (CLU,отметим, —это первые три буквы словаcluster.) Кластер включает в себя следующее.
1.Заголовок, в котором придаются имена реализуемому типу и операциям. Этот заголовок похож на заголовок в спецификации.
2.Определение представления, выбранного в данной реализации.
3.Реализации примитивных операций. Дополнительные программы (процедуры и итераторы) также могут быть включены в кластер, но обращаться извне можно только к тем, которым приданы имена в заголовке.
Общий вид кластера представлен на рис. 4.4.
dnarne =clusteris %список имен операций
rep =%здесь дается описание представления
%здесь помещаются реализации операций
%если необходимо, здесь могут быть представлены
%вспомогательные программы
enddnarne
Рис. 4.4.Общий вид кластера.
Для представления наборов целых чисел с помощью массивов, например, мы указываем
гер =array[int]
Эта строка выполняет две функции) информирует компиляторCLUо том, что в этом кластере представлением является массив целых чисел и что в теле кластера обозначение герможет использоваться в качестве аббревиатуры для этого представленного массивом типа.
Внутри кластера должны быть доступны как абстрактный тип, так и тип представления. Более того, должна иметься возможность перехода от одного типа к другому. Например, операция insertполучает в качестве аргумента набор целых чисел, но для реализацииinsertнеобходимо использовать массив, который представляет этот набор.
Возможность перехода от абстрактного типа к типу представления и обратно в языке CLUобеспечивают ^две специальные операции:upиdown. Операцияupиспользует в качестве аргумента объект представления и в качестве результата выдает абстрактный объект, а операция downосуществляет обратное действие. Для того чтобы обеспечить преобразование абстрактного типа в тип представления и обратно, каждый кластер имеет свою собственную версию операций upи down.Эти операции автоматически определяются компилятором CLU.Например, в кластере процедурыintsetкомпилятор порождает операцииupиdownсо следующими заголовками:
up = proc (a: array tint 1) returns (intset)
down == proc (s: intset) returns (array [int])
Операцииupиdownмогут использоваться только в кластерах и всегда осуществляют переход от абстрактного типа к типу представления и обратно только для кластера, в котором они появились. Поэтому операции up и downне могут отрицательно повлиять на контроль типов языка CLU.
Хотя операции upи downмогут появиться, где угодно, среди операций кластера, они в основном используются в одном из двух случаев. В первом случае, когда операция использует в качестве аргумента абстрактный объект, для преобразования этого объекта в тип представления используется операцияdown. Во втором случае, когда операция возвращает заново созданный абстрактный объект, сразу же перед возвратом для преобразования объекта представления в абстрактный тип используется операцияup. Для удобства работы язык CLUпредоставляет специально зарезервированное словоcvt. Словоcvtможет использоваться как тип аргумента или результата в заголовках операций кластеров. Использование его как типа аргумента указывает, что фактический аргумент -абстрактного типа, неформальный -типа представления и что поэтому к фактическому аргументу сразу же после вызова должна быть неявно применена операцияdownи результирующий объект представления должен быть присвоен формальному аргументу. Когдаcvtиспользуется как тип результата, это означает, что результирующий объект -абстрактного типа, но возвращаемый объект- типа представления и что поэтому прямо перед возвратом к возвращаемому объекту неявно должна быть применена операцияup. Слово cvtне добавляет никакой функциональности, которая не была бы обеспечена операциямиupиdown. Оно обеспечивает только удобство, которое возникает из возможности довольно просто описывать общие случаи.
Теперь мы можем обратиться к представленной на рис. 4.5 реализации процедурыintset.
intset = cluster is create, insert, delete, member, size, choose
rep = array [int]
create = proc ( ) returns (cvt)
return (rep$new ( ))
end create
insert = proc (s: intset, x: int)
if ~ member (s, x) then rep$addh (down (s), x) end
end insert
delete = proc (s: cvt, x: int)
j: int :== getind (s, x)
if j <= rep$high (s)
then s [j] := rep$top (s) % top возвращает s [high (s)]
rep$remh (s)
end
end delete
member = proc (s: cvt, x: int) returns (bool)
return (getind (s, x) <= rep$high (s))
end member
size = proc (s: cvt) returns (int)
return (rep$size (s))
end size
choose = proc (s: cvt) returns (int)
return (rep$bottom (s)) % bottom возвращает s [low (s) ]
end choose
getind = proc (s: rep, x: int) returns (int)
i: int : = rep$low (s)
while i <= rep$high (s) do
if x = s[i] then return (i) end
i:=i+ I
end
return (i)
end getind
endintset
Рис. 4.5.Реализация типа данныхintset.
Прежде всего обратим внимание на реализацию операцииcreate. Заголовок здесь следующий:
create = proc ( )returns(cvt)
Следовательно, возвращается абстрактный объект, т. е. набор целых чисел. По операторуreturnдолжен быть возвращен массив, но к этому объекту перед возвращением применяется операцияup. Обратимся теперь к реализации операцииinsert. В этом случае cvtне используется. Заголовок здесь следующий:
insert =proc(s:intset, х:int)
Следовательно, заданный пользователем абстрактный объект intsetне подвергается операции down.
Операцияinsertне возвращает никакого результата; вместо этого она модифицирует свой аргументintset. В данной реализации каждый элемент набора встречается в представляющем этот набор массиве только один раз; следовательно, операцияinsertне может просто добавить целое число х в массив. Она должна прежде проверить, не содержится ли уже х в массиве. Для этой цели используется операцияmember. Аргументом этой операции является набор целых чисел, поэтому в заголовкеinsertне используется cvt.Заметим, что в обращении к операцииmemberпрефикс «intset$» отсутствует; этот префикс не требуется, если операция вызывается внутри своего собственного кластера.
Если оказывается, что х не является членом s,к sявно применяется операция downи при помощи операцииaddhх добавляется в массив. Если х уже принадлежит s,массив не модифицируется. Заголовок операцииdeleteследующий:
delete = proc (s: cvt, х: int)
В этом случае к переданному в качестве аргумента абстрактному объектуintsetнемедленно применяется операция down и внутри операцииdelete sбудет иметь типarray [int].
Операцияdeleteдолжна прежде всего выяснить, принадлежит ли х s.Для этого используется внутренняя процедураgetind. Если х есть в массиве, процедураgetindвозвращает индекс, соответствующий расположению х, в противном случае возвращается число, большее верхней границы массива. Так как процедураgetindне указана в заголовке кластера, она является внутренней для этого кластера, т. е. может быть вызвана только из этого кластера.
Если х принадлежит s,операцияdeleteпросто записывает верхний элемент массива в позицию х и затем уничтожает верхний элемент, используя операциюremh. При этом операцияremhвозвращает удаляемый элемент как результат, однако в нашем случае этот ненужный результат просто уничтожается.
Операция chooseпозволяет возвратить произвольный элемент s.Следовательно, при реализации этой операции мы можем действовать, как нам удобно. Один удобный выбор -это первый элемент массива, другой, тоже удобный, —последний элемент. Конечно, это приводит к тому, что операцияchooseвозвращает обратившемуся к ней различные объекты, но, так как в спецификацииchooseговорится, что выбор произвольный, не следует рассчитывать на возврат каких-то определенных объектов. Отметим, что в согласии со спецификацией операцияchooseне изменяет переданного ей в качестве аргумента набораintset.