Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Разработка языка запросов в бинарной модели знаний и транслятора этого языка в язык SQL (бакалаврская работа).doc
Скачиваний:
13
Добавлен:
28.06.2014
Размер:
1.31 Mб
Скачать

2.2.3. Спецификация функций

На специфицированных типах можно задавать операции (функции), используя предопределенные операции на примитивных типах значений и операторы, ассоциированные с конструкторами типов. Таким образом, мы получаем так называемые абстрактные типы данных.

Примеры 2.3:

1) Определим на типе значений БинДерево1 функцию, которая по заданному бинарному дереву (с натуральными метками в вершинах) дает зеркальное отражение этого дерева. Эту функцию обозначим отраж(X). Например, дерево (а) рис.1.3 отображается в дерево (б) рис.1.3. Эта функция определяется следующим образом:

FUN отраж: БинДерево1 -> БинДерево1

отраж(X):= X IF X IN Nat.

отраж((Лев:X,Центр:Y,Прав:Z)) :=

(Лев:отраж(Z),Центр:Y,Прав:отраж(X))

END

(а) (б)

2 2

/ \ / \

7 2 2 7

/ \ / \

4 1 1 4

/ \ / \

1 0 0 1

/ \ / \

2 3 3 2

Рис. 2.3.

Рассмотрим вычисление значения функции отраж(e), где

e=(Лев:(Лев:1,Центр:2,Прав:(Лев:0,Центр:4,Прав:1)), Центр:5, Прав:9).

(Кортеж е представляет дерево, изображенное на рис.1.2.)

отраж(e) = отраж((Лев:(Лев:1,Центр:2, Прав:(Лев:0,Центр:4,Прав:1),

Центр:5,Прав:9)) =

% X =(Лев:1,Центр:2,Прав:(Лев:0,Центр:4,Прав:1)), Y =5, Z =9 %

= (Лев:отраж(9),Центр:5,

Прав:отраж((Лев:1,Центр:2,

Прав:(Лев:0,Центр:4,Прав:1))) =

= (Лев:9,Центр:5,

Прав:отраж((Лев:1,Центр:2,

Прав:(Лев:0,Центр:4,Прав:1))) =

% Х =1, Y =2, Z = (Лев:0,Центр:4,Прав:1) %

= (Лев:9,Центр:5,

Прав:(Лев:отраж((Лев:0,Центр:4,Прав:1)),

Центр:2,Прав:отраж(1)) =

= (Лев:9,Центр:5,

Прав:(Лев:отраж((Лев:0,Центр:4,Прав:1)),

Центр:2,Прав:1) =

% X =0, Y =4, Z =1 %

= (Лев:9,Центр:5,

Прав:(Лев:отраж(1),Центр:4,Прав:отраж(0)),

Центр:2,Прав:1) =

= (Лев:9,Центр:5, Прав:(Лев:1,Центр:4,Прав:0),

Центр:2,Прав:1).

В результате мы получили кортеж, представляющий изображенное на рис.1.4 дерево, которое, очевидно, есть отражение дерева рис.3.2.

5

/ \

9 2

/ \

4 1

/ \

1 0

Рис.3.4.

2) Определим функцию, заданную на элементах типа Дерево, которая для каждого элемента e Дерево дает сумму всех меток, приписанных вершинам дерева e.

FUN сумма:Дерево->Nat

сумма((X)):= X IF X IN Nat.

сумма((X,Y)):= X+сумма(Y).

сумма(X::Y)):= сумма(X)+сумма(Y).

END

Например, для дерева, изображенного на рис.2.6, имеем:

сумма(5,[9,(2,[(4,[1,0]),1])]) = 5+сумма([9,(2,[(4,[1,0]),1])]) =

5+сумма(9)+сумма([(2,[(4,[1,0]),1])]) =

5+9+2+сумма([(4,[1,0]),1]) =

16+сумма((4,[1,0])+сумма(1) =

16+4+сумма([1,0])+1 =

21+сумма(1)+сумма(0) = 2+1+0= 22.

Мы рассмотрели только примеры спецификации операций для абстрактных типов данных, в которых использовались конструкторы := , IN, IF и CASE. В общем случае необходим функциональный язык программирования для определения функций. В БМЗ имеется простой функциональный язык типа языка Hope, [Филд и Харрисон 1991] .

Спецификация в этом языке произвольной функция (с несколькими аргументами, принадлежащими разным типам) выглядит так:

FUN f:(T1,T2,…,Tn) -> T

<предложение1>.

<предложение2>.

:

<предложениеN>.

END

Пример 3.4. Окружность на плоскости можно идентифицировать, указав координаты ее центра и ее радиус. Поэтому тип данных «Окружность» можно задать так:

Окружность = (Центр:Точка, Радиус:Real).

Точка = (Абсцисса:Real, Ордината:Real).

Предположим, что мы хотим задать предикат, выясняющий соприкасаются или нет два круга. Тогда можно дать следующее определение.

FUN расст:(Точка,Точка) -> Real

расст(X,Y):= sqrt((X.Абсцисса-Y.Абсцисса)**2+ X.Абсцисса-Y.Абсцисса)**2)

END

FUN соприкас:(Окружность, Окружность)-> Boolean

cоприкас(X,Y) := true IFF расст(X.Центр, Y.Центр)= X.Радиус + Y.Радиус

END

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

Пример 2.5. Следующий модуль специфицирует типы данных «Точка», «Вектор», «Окружность» и функции, дающие:

▪ расстояние между точками, длину вектора и площадь окружности; а также предикаты, выясняющие:

▪ коллинеарность двух векторов;

▪ является ли две окружности соприкасающимися;

▪ является ли последовательность векторов цепью (в том смысле, что конец одного вектора совпадает с началом следующего вектора).

TYPES Точка = (Абсцисса:Real, Ордината:Real).

Вектор = (Начало:Точка, Конец:Точка).

Окружность = (Центр:Точка, Радиус:Real).

FUN: расст(X,Y):= sqrt((X.Абсцисса-Y.Абсцисса)**2+.Абсцисса-Y.Абсцисса)**2)

END

FUN: длина: Вектор -> Real

длина(X):= расст(X.Начало,Y.Конец)

END

FUN цепь: LLIST(Вектор)-> Boolean

цепь(Х):= true IF X IN Вектор,

цепь(X::Y):= X.Конец = CAR(Y).Начало; цепь(Y)

END

FUN: коллин: (Вектор, Вектор) -> Boolean

коллин(X,Y):= (длина(X)=длина(Y));

(расст(X.Начало,Y.Начало) = расст(X.Начало,Y.Начало)).

END

FUN: площадь: Окружность -> Real

площадь(Х):= 3.141592*(Х.Радиус)**2

END

FUN: соприкас: (Окружность, Окружность) -> Boolean

cоприкас(X,Y):= true IFF

расст(X.Центр, Y.Центр)= X.Радиус + Y.Радиус

END

Соседние файлы в предмете Государственный экзамен