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

Реализация на языке 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.Для этого используется внутренняя процедураge­tind. Если х есть в массиве, процедураgetindвозвращает индекс, соответствующий расположению х, в противном случае возвра­щается число, большее верхней границы массива. Так как про­цедураgetindне указана в заголовке кластера, она является вну­тренней для этого кластера, т. е. может быть вызвана только из этого кластера.

Если х принадлежит s,операцияdeleteпросто записывает верхний элемент массива в позицию х и затем уничтожает верх­ний элемент, используя операциюremh. При этом операцияremhвозвращает удаляемый элемент как результат, однако в нашем случае этот ненужный результат просто уничтожается.

Операция chooseпозволяет возвратить произвольный эле­мент s.Следовательно, при реализации этой операции мы можем действовать, как нам удобно. Один удобный выбор -это первый элемент массива, другой, тоже удобный, —последний элемент. Конечно, это приводит к тому, что операцияchooseвозвращает обратившемуся к ней различные объекты, но, так как в специ­фикацииchooseговорится, что выбор произвольный, не следует рассчитывать на возврат каких-то определенных объектов. От­метим, что в согласии со спецификацией операцияchooseне из­меняет переданного ей в качестве аргумента набораintset.

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