Абриаль 2.1 Назад Начало Выше Дальше16/08/03 А.И.Пацкин [packin.ru]
Разработка веб-интерфейса ] [ Abrial DDL ] Конструирование БД ] Ассоциации ] Правила. Продукционное программирование ] Схема ядра ]

Abrial DDL


Язык представления данных

Общие замечания

Для работы с базой данных обычному пользователю не требуется знать язык представления данных, поскольку этот язык исполняет такую же роль формата хранения, какую в WWW играет HTML. И так же как в случае WWW, некоторые разработчики сайтов, пользующиеся средствами высокого уровня, могут не знать HTML, Абриаль не требует знания языка представления от разработчика баз данных. Через гипертабличный интерфейс разработчик может сделать практически всё, что ему  может понадобиться.

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

К тому же язык достаточно прост, чтобы воспользоваться им для представления примеров в тексте данного руководства. Хотя данные выглядят через основной табличный интерфейс программы совершенно иначе, эти примеры могут послужить мостиком между традиционным взглядом на знания, и объектно-навигационным взглядом Абриаля.

Строение файла базы данных

Файл базы данных является текстовым файлом, состоящим из предложений следующих типов:

Хотя в основном порядок этих строк должен быть именно таким, в некоторых случаях порядок может быть нарушен.

Условные обозначения

  • Жирный шрифт будет использован для примеров и для всего того, что требуется набирать буквально, например CLASS.
  • Курсивом набираются имена элементов текста подлежащие замене, например имя-слота .
  • Скобки [ ] будут окружать необязательные элементы.
  • Многоточие будет следовать элементу, который может быть повторен многократно.

Определение класса

Имя-класса :CLASS(имя-атрибута1 [,имя-атрибута2 ]…)

Класс определяется строкой, в начале которой стоит имя класса, затем после двоеточия слово CLASS и затем  в скобках следует список атрибутов данного класса. Напомним, что атрибутом класса называется аспект, для которого данный класс назначен доменом. Имя атрибута состоит из имени отношения и имени аспекта этого отношения разделенных знаком "\". Пример определения класса:

Личность:CLASS(ФИО\ФИО,Возраст\Возраст,Пол\Пол,Родитель\Родители,Родитель\Дети)

Порядок следования атрибутов класса определяет порядок столбцов в соответствующих классу гипертаблицах.

Определение отношения

Имя-отношения :LINK(аспект1 [,аспект2 ]…)

Отношение определяется строкой, в начале которой стоит имя отношения, затем после двоеточия слово LINK и затем в скобках следует список определений аспектов данного отношения. Количество аспектов в скобках определяет размерность отношения.

Определение аспекта внутри определения отношения

Имя-аспекта :форма-аспекта

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

имя-домена

владеющий одиночный аспект

{имя-домена }

владеющий множественный аспект

(имя-домена )

владеющий списочный аспект

&имя-домена

ссылочный одиночный аспект

{&имя-домена }

ссылочный множественный аспект

(&имя-домена )

ссылочный списочный аспект

*имя-домена

исходный одиночный аспект

{*имя-домена }

исходный множественный аспект

(*имя-домена )

исходный списочный аспект

[имя-домена ]

целевой аспект

Имя домена для одиночного аспекта записывается без скобок, для множественного аспекта используются фигурные скобки {…},  для списочного - обычные круглые скобки (…) , а для целевого - квадратные скобки […].

Знак & перед именем домена означает, что данный аспект - ссылочный, и удаление связи не приведет к удалению объекта. Знак * перед именем домена означает, что аспект исходный.  Если никакого знака нет, то аспект является владеющим, т.е. "содержит" объект, и тогда удаление связи влечет за собой удаление объекта.

Целевые и исходные аспекты используются только для вычисляемых отношений, т.е. ассоциаций. Для ассоциации действует правило вычислимости: отношение готово к вычислению, если определён хотя бы один не целевой аспект и определены все исходные аспекты.

Примеры отношений

Например, так выглядит определение отношения ФИО (т.е. фамилию, имя и отчество личности):

ФИО:LINK(ФИО:&Личность,ФИО_для:STR)

Это бинарное отношение, состоящее из двух аспектов: ФИО и ФИО_для. Это отношение связывает класс Личность с системным встроенным классом STR. Оба аспекта одиночные, т.е. одна личность может иметь лишь одно имя, и конкретный строчный объект может быть именем только одного объекта типа ЛичностьОбъект класса Личность не зависит от этой связи, а объект класса STR - зависит.

Еще один пример - отношение Родитель, связывающее объекты Личность для родителей и детей.

Родитель:LINK(Дети:{&Личность},Родители:{&Личность})

Оба аспекта этого отношения являются множественными и ссылочными, т.е. это отношение, как принято называть типа "много ко многим" и объекты, связываемые этим отношением не зависят от него.

Определение ключей в отношениях.

Если у отношения есть ключи, они определяются внутри списка аспектов в определении отношения. Ключ определяется конструкцией:

KEY(аспект-1 ,аспект-2 ...)

где аспект-i это имена аспектов данного отношения, включённые в данный ключ. Например, следующее отношение отражает владение человеком иностранными языками и ключ в этом примере отражает тот факт, что один человек владеет одним языком с одной определенной степенью владения.

ин_яз_влад:LINK(ин_яз_владение:{&Личность},
                           ин_яз:{&иностранный_язык},
                           ин_яз_степень:{&ин_яз_степ_владения},
                           KEY(ин_яз_владение,ин_яз))

Определение объекта

Иметь определения должны только сущности, т.е. именованные объекты. Если в базе данных есть хотя бы один факт, ссылающийся на данный объект, то отдельное определение для данного объекта не обязательно. Формат определения объекта предельно прост:

Имя-объекта :Класс-объекта

При этом Класс-объекта есть ссылка на определённый ранее класс, а Имя-объекта есть произвольный идентификатор.

Примеры:

Май:Месяц
Pentium-600:CPU-Type
Евгений Онегин:Роман
Иванов:Личность
Новслободская:Улица

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

Составные имена объектов

Локально именуемые объекты, (т.е. объекты, имена которых относятся к списку, подчиненному некоторому старшему объекту), в базе данных должны именоваться полными т.е. составными именами. В составном имени перед именем собственно локального объекта, должно стоять полное имя старшего объекта. Части составного имени разделяются между собой специальным знаком "\".

Например, допустив, что имена улиц уникальны в пределах города, а номера домов - в пределах улицы, получим:

Москва\Тверская:Улица
Москва\Строителей:Улица
Санкт Петербург\Строителей:Улица
Москва\Строителей\22:Дом
Санкт Петербург\Строителей\22:Дом

Факты (определения связей)

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

Имя-отношения (Параметр1 [,Параметр2 ]…)

Аргумент может быть либо ссылкой на объект, либо литералом, задающим числовой или строковый объект.

Ссылки на объекты в фактах могут быть простыми или квалифицированными. Квалифицированная ссылка состоит из простой ссылки, за которой находится знак ":" и имя класса объекта. Простая ссылка  представляет собой имя объекта (полное имя для локальных объектов), или индекс объекта для структур (неименованных объектов).

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

Индекс объекта представляет собой знак "#" и следом за ним - целое число, которое должно однозначно определять объект в пределах одного файла базы данных. Собственно говоря, индексы играют роль своеобразных системных имён. Обычно их формирует система при сохранении базы данных в файл, но теоретически их может готовить и пользователь. Индексы должны использоваться для внешнего представления объектов - структур.

Литералы задают в фактах объекты - значения, которые обычно связаны с ровно одним фактом. Строчные литералы (класса STR) задаются в виде последовательности символов в "двойных кавычках". Целые числа (INT) представляются последовательностью цифр с возможным знаком минус "-" спереди, действительные числа (NUM) - так же, но должны содержать внутри себя точку.

Примеры фактов

Допустим, имеются классы

Личность:CLASS(ФИО,Пол,Родители,Дети)
Пол:CLASS(Пол_для)

и пусть определены отношения

ФИО:LINK(ФИО:&Личность,ФИО_для:STR)
Родитель:LINK(Дети:{&Личность},Родители:{&Личность})
Пол:LINK(Пол:&Личность,Пол_для:{&Пол})

а также объекты

Иванов:Личность
Петров:Личность
Иванова ОИ:Личность
Муж:Пол
Жен:Пол

Тогда возможны следующие факты, относящиеся к указанным объектам

ФИО(Иванов,"Иванов Иван Иванович")
Пол(Иванов,Муж)
Пол(Петров,Муж)
ФИО(Иванова ОИ,"Иванова Ольга Ивановна")
Пол(Иванова ОИ,Жен)
Родитель(Иванов,Иванова ОИ)

Порядок фактов в файле базы данных

Обычно порядок фактов может быть произвольным, не требуется даже предварительное определение объектов, на которые ссылается факт, нужно лишь, чтобы отношение - тип этого факта (предикат) было определено раньше. Но в одном случае порядок важен: если отношение имеет списочный аспект. В этом случае факты связанные с одним объектом по этому аспекту следовали друг за другом именно в нужном порядке; этот порядок и будет определять порядок связей в соответствующем аспекте данного объекта.

Например, пусть аспект Дети отношения Родитель является списочным аспектом, чтобы порядок в списке детей отражал порядок их рождения. Это потребует некоторой модификации определения отношения.

Родитель:LINK(Дети:(&Личность),Родители:{&Личность})

Тогда три сына человека по имени Алексей, могут быть заданы тремя фактами в следующем порядке:

Родитель(Алексей,Федор)
Родитель(Алексей,Иван)
Родитель(Алексей,Петр)

И тогда, глядя со стороны объекта Алексей на аспект Дети, мы увидим следующий список: (Федор,Иван,Петр). В случае же множественного аспекта, каковым аспект Дети был до модификации, этот порядок определялся системой, (в данном случае - как алфавитный порядок имен), и порядок этих фактов в файле был бы безразличен.

Определение ассоциаций.

Ассоциация определяется как отношение, но с некоторыми дополнениями. Во-первых, после имён аспектов дополнительно должны находиться списки параметров в круглых скобках. В каждом списке должно быть столько параметров, каково число вариантов у ассоциации. Все параметры должны иметь различные имена внутри ассоциации. Каждый параметр должен относиться к ровно одному варианту.

Во-вторых, следом за определением отношения должны следовать определения вариантов. Каждый вариант записывается как правило в языке пролог. Левая часть правила записывается как факт, где вместо имени отношения стоит имя определяемой ассоциации, а вместо аргументов - параметры из соответствующих вышеопределённых списков. Правая часть отделяется от левой знаками ":-" и представляет собой список условий, заканчивающийся точкой.

Условия правой части записываются как факты, предикатами которых могут быть имена отношений, ассоциаций и примитивов. Аргументами условий в скобках могут быть а) параметры б) переменные в) квалифицированные ссылки на объекты в форме Имя-объекта :Класс-объекта и г) литералы, изображающие объекты-значения. При этом объекты формально отличаются от переменных и параметров указанием класса.

Пример ассоциации с одним вариантом:

Брат:LINK(Брат(X):{&Личность},Брат_для(Y):{&Личность})
   Брат(X,Y):-
     Родитель(X,Z),Родитель(Y,Z),NE(X,Y),Пол(Y,Муж:Пол).

Пример ассоциации с тремя вариантами:

Предок:LINK(Предки(A1,A2,A3):{&Личность},Потомки(D1,D2,D3):{&Личность})
  Предок(A1,D1):-  Родитель(A1,D1).
  Предок(A2,D2):-  Родитель(A2,Z),  Родитель(Z,D2).
  Предок(A3,D3):-  Родитель(A3,Y), Предок(Y,X), Родитель(X,D3).

Замечание о порядке. Порядок записи условий в ассоциациях чаще всего безразличен для вычислений, т.к. Абриаль сам выстраивает оптимальный порядок вычислений. Однако в некоторых случаях Абриалю всё равно, какое условие проверять следующим из двух кандидатов, и тогда берётся первое попавшееся, при этом порядок записи может сыграть свою роль.

Кванторы условий в ассоциациях

  1. @Cond(a,b) - квантор цикла. Такие условия выполняются сразу многократно для побочного эффекта и всегда, даже при нулевом числе успехов возвращают успех.
  2. ~Cond(a,b) - квантор отрицания, возвращается успех если условие не имеет ни одного решения и неуспех в противном случае.
  3. ^Cond(a,b) - квантор существования, принудительно выполняется только единожды, даже если есть другие решения

Пример использования квантора цикла для подсчета сумм. Для объектов класса работа (Work), имеющих начало (B) и окончание (E), и упорядоченных в решетку (ORD) рассчитывается длина работы (LR) и затем в цикле (SX) складываются длины всех последующих работ. (Пример не имеет практического смысла ).

Work:CLASS(B\B,E\E,LR\LR,ORD\Next,ORD\Prev,SX\SX)
ORD:LINK(Next:{&Work},Prev:{&Work})
B:LINK(B:&Work,B_of:INT)
E:LINK(E:&Work,E_of:INT)
LR:LINK(LR(O):&Work,R(R):INT)
   LR(O,R):-E(O,E),ADD(R,E),INT(R,1),SUB(R,B),B(O,B).
Sm:LINK(O(O):&Work,S(S):[*INT])
   Sm(O,S):-ORD(O,Nx),LR(Nx,L),ADD(S,L).
SX:LINK(SX(O):&Work,S(S):INT)
    SX(O,S):-@Sm(O,S),INT(S,0).

Пример использования квантора отрицания. События (Event) переводят объекты Дело в новое Состояние в определённый момент (Дата). Ассоциация Status связывает каждое Дело с самым последним Состоянием. Вспомогательная ассоциация _fut определяет для каждой пары Дело-Дата наличие событий по этому Делу после этой Даты. Отрицание _fut в ассоциации Status и означает, что данное состояние - последнее.

Дело:CLASS()
Состояние:CLASS()
Дата:CLASS()
Event:LINK(История:{&Дело},События даты:{&Дата},События для состояния:{&Состояние})
_fut:LINK(D:*Дело,T:*Дата)
    _fut(D,T):-Event(D,T1,S),NE(T1,T),GT(T1,T).
Status:LINK(Состояние:&Дело,дела в состоянии:{&Состояние})
    Status(D,S):-Event(D,X,S),~_fut(D,X).

Примитивные ассоциации

Перечисленные ниже примитивы используются в ассоциациях и в правилах. В ассоциациях и в левых частях правил их можно рассматривать как простейшие встроенные ассоциации. В правой части правила их можно рассматривать как простейшие действия.

ADD(X,Y)
Сложение X + Y - результат остаётся в X
SUB(X,Y)
Вычитание X - Y - результат остаётся в X
MUL(X,Y)
умножение X * Y - результат остаётся в X
DIV(X,Y)
деление X / Y - результат остаётся в X
CAT(X,Y)
конкатенация X и Y - результат остаётся в X
INT(X,Y)
Создание в переменной X значения - целого числа. Число для инициализации берётся из (обычно константы) Y.
NUM(X,Y)
Создание в переменной X значения - действительного числа. Число для инициализации берётся из (обычно константы) Y.
STR(X,Y)
Создание в переменной X строчного значения. Строка для инициализации берётся из (обычно константы) Y.
TOINT(X,Y)
эта функция записывает значение из второго параметра в 1-й, конвертируя его при этом в целый тип INT.
TONUM(X,Y)
эта функция записывает значение из второго параметра в 1-й, конвертируя его при этом в действительный тип NUM.
TOSTR(X,Y)
эта функция записывает значение из второго параметра в 1-й, конвертируя его при этом в строчный тип STR.
NE(X,Y)
Сравнение на неравенство для значений и на неидентичность для всех остальных объектов.
EQ(X,Y)
Сравнение на равенство для значений и на идентичность для всех остальных объектов.
GE(X,Y)
Проверка условия X >= Y
GT(X,Y)
Проверка условия X > Y
LE(X,Y)
Проверка условия X <= Y
LT(X,Y)
Проверка условия X < Y
LET(X,Y)
эта функция записывает в старое значение X новое: Y с учетом старого типа X. Для правил этот примитив инициирует процесс проверки сети на соответствие.
SET(X,Y)
эта функция записывает значение Y на место X, старое значение X пропадает и его тип безразличен

Определение правил

Правило определяется конструкцией:

Имя-правила :RULE(Тело-правила )

Вместо закрывающей скобки может стоять точка.

Тело-правила определяется так:

Тело-правила ::= Левая-часть => Альтернатива-1 [ | Альтернатива-2 ] ...
Левая-часть ::= Условие-1 [, Условие-2 ]...
Альтернатива-i ::= Действие-1
[, Действие-2 ]...
Условие-i ::=
[Квантор ] Предикат (Аргумент-1 [, Аргумент-2 ]... )
Действие-i ::= [Квантор ] Предикат (Аргумент-1 [, Аргумент-2 ]... )
Квантор ::= знак~
или знак@ или знак^
Предикат ::= Имя-отношения
Аргумент-i ::= Переменная или Объект или Литерал
Переменная ::= Имя
Объект ::=
Имя-объекта :Класс-объекта
 Литерал::= "
строчный литерал " или целое-число или число-с-точкой

Например,  рассмотрим группу правил, поддерживающих состоятельность календарного графика работ. Время начала (Beg) следующей работы (Work) не должно быть меньше времени окончания (End) предыдущей.

Work:CLASS(Beg\Beg,Len\Len,End\End)
Beg:LINK(Beg:&Work,B_of:[INT])
End:LINK(End:&Work,End-of:[INT])
Len:LINK(Len:&Work,Len-of:[INT])
After:LINK(Before:{&Work},After:{&Work})
Rule0:RULE(Beg(W,B)=>GT(B,0))
Rule1:RULE(Beg(W,B),Len(W,L)=>
           INT(E,-1),ADD(E,L),ADD(E,B),End(W,E).
Rule2:RULE(End(W,E),Len(W,L)=>
           INT(B,1),ADD(B,E),SUB(B,L),Beg(W,B).
Rule3:RULE(Beg(W,B),Len(W,L),End(W,E),INT(bx,1),ADD(bx,E),SUB(bx,L),NE(B,bx)=>
           Beg(W,bx)|
           INT(ex,-1),ADD(ex,L),ADD(ex,B),End(W,ex).
Rule4:RULE(End(W1,E),Beg(W2,B),After(W1,W2),GE(E,B)=>
           INT(x,-1),ADD(x,B), LET(E,x)|
           INT(y,1),ADD(y,E),LET(B,y).

Порядок действий в правой части существенен. Именно в этом порядке они выполняются. Порядок условий в левой части может быть любым (с учетом замечания о порядке в ассоциациях).

Кванторы в правилах. В правилах для текущей версии может использоваться только квантор отрицания: знак ~. В левой части он имеет такой же смысл, как для ассоциаций.


Все права защищены. © 2000-2004 РосНИИ ИИ
http://artint.ru
Copyright. © 2000-2004 by RRIAI
Александр Иосифович Пацкин [mailto:aleksandr@tochka.ru].
16/08/03

К началу документа.