и T' должны быть типами;
T и T' должны быть типами; то есть каждый из них должен быть именованным множеством значений.
Каждое значение T' должно быть значением T; то есть множество значений, составляющих T', должно быть подмножеством множества значений, составляющих T (другими словами, если значение принадлежит типу T', то оно также должно принадлежать типу T). Более того, если T и T'
различны (см. IM-предписания 3 и 4), то должно существовать по крайней мере одно значение, которое принадлежит типу T
и не принадлежит типу T'.
T и T' не обязательно должны быть различны; то есть, каждый тип должен быть как подтипом, так и супертипом самого себя.
Если и только если типы T и T'
различны, то T' является собственным подтипом T, и T
является собственным супертипом T'.
Каждый подтип T' должен быть подтипом T. Каждый супертип T должен быть супертипом T'.
Если и только если T' является собственным подтипом T и не существует типа, который одновременно является собственным супертипом T' и собственным подтипом T, то T' является непосредственным подтипом T, а T является непосредственным супертипом T'. Тип, который не является непосредственным
подтипом какого-либо типа, является корневым
типом. Тип, который не является непосредственным
супертипом какого-либо типа, является листовым типом.
( Вариант, предполагающий множественное наследование )
Если типы T1 и T2 являются различными корневыми типами, то они должны быть непересекающимися; то есть никакое значение не должно одновременно принадлежать типу T1 и типу T2.
( Вариант, предполагающий множественное наследование )
Для каждого набора скалярных типов T1, T2, …, Tn (n>0) должен иметься общий подтип T' такой, что заданное значение принадлежит каждому из типов T1, T2, …, Tn, если и только если оно принадлежит типу T'.
Пусть скалярная переменная V относится к объявленному типу T. По причине возможности замены значений (см. IM-предписание 16) значение v, присвоенное V , в любой момент времени может принадлежать любому подтипу T' типа T как своему наиболее конкретному типу. Поэтому можно моделироватьV как именованный упорядоченный триплет вида <DT,MST,v>, где:
DT является именем объявленного типа переменной V;
v является значением наиболее конкретного типа – текущим значением (для)переменной V.
Обозначения DT(V), MST(V), v(V) используются для ссылок на компоненты DT, MST и v этой модели скалярной переменной V
соответственно.
Далее, пусть X - скалярное выражение. Систему обозначений DT(V), MST(V), v(V) можно очевидным образом расширить для ссылок на объявленный тип DT(X), текущий наиболее конкретный тип MST(X) и текущее значение v(X) выражения X соответственно, где “объявленный тип” – это то, что разъяснялось в RM-предписании 3, и этот тип известен во время компиляции, а “текущий наиболее конкретный тип” и “текущее значение” относятся к результату вычисления X и поэтому в общем случае неизвестны до времени выполнения.
Пусть T - регулярный собственный супертип (см. IM-предписание 20), и пусть T' - непосредственный подтип T. Тогда в определении T' должно специфицироваться ограничение специализации SC, сформулированное в терминах T и такое, что значение типа T должно принадлежать типу T', если и только если оно удовлетворяет ограничению SC. Должно существовать по крайней мере одно значение типа T, которое не удовлетворяет ограничению SC.
Пусть X - выражение. Рассмотрим присваивание
V := X
;
(где V является переменной). DT(X) должно быть подтипом DT(V). Присваивание должно сделать MST(V) равным MST(X), а v(V) - равным v(X).
Рассмотрим сравнение на равенство
Y = X
(где Y и X являются выражениями). DT(X) и DT(Y) должны иметь общий супертип. Сравнение должно возвращать true, если MST(Y) равно MST(X) и v(Y) равно v(X), иначе - false.
Пусть rx и ry - отношения с общим атрибутом A, и пусть объявленные типы A в rx и ry
- это DT(Ax) и DT(Ay) соответственно. Рассмотрим соединение rx и ry ( обязательно по A, по крайней мере, частично). DT(X) и DT(Y) должны иметь общий супертип и, следовательно, обязательно общий наиболее конкретный супертип, скажем T. Тогда объявленным типом A в результате соединения должен быть тип T.
Аналогичные замечания относятся к объединению, пересечению и разности операций. То есть в каждом случае:
Для каждого типа T должна поддерживаться операция в форме
TREAT_DOWN_AS_T ( X )
(или ее логический эквивалент), где X является выражением. T должен быть подтипом DT(X) и MST(X) должен быть подтипом T. Такие операции обобщенно называются операциями “TREAT DOWN”; их семантика такова:
свой аргумент X (точнее, он должен назначать версию X, для которой DT(X) равно T, но MST(X) и v(X) неизменны). Аргумент X должен быть указан именно как переменная, а не как произвольное выражение.
( Вариант, предполагающий множественное наследование )
Для каждого типа T, должна поддерживаться логическая операция вида
IS_T ( X )
(или ее логический эквивалент), где X - выражение. DT(X) и T
должны иметь общий подтип. Эта операция должна возвращать true, если v(X) принадлежит типу T, и false в противном случае.
Пусть Op - операция только чтения, пусть P - параметр Op, и пусть T - объявленный тип для P. Тогда должно допускаться, чтобы объявленный тип выражения аргумента (и следовательно, тем более, наиболее конкретный тип значения аргумента), соответствующего параметру P в вызове Op, был любым подтипом T' типа T. Другими словами, операция только чтения Op применяется к значениям типа T и поэтому, обязательно, к значениям типа T' – Принцип Наследования Операций (Только Чтения). Из этого следует, что такие операции являются полиморфными, поскольку они применимы к значениям нескольких различным типам – Принцип Полиморфизма Операций (Только Чтения). И далее из этого следует, что везде, где допускается значение типа T, должно также допускаться значение любого собственного подтипа T – Принцип Возможности Замены (Значений).
Для каждой заданной операции Op должны иметься:
Если действительно существует несколько версий Op, то все эти версии фактически должны реализовывать одну и ту же семантику.
Пусть Op - операция обновления, и пусть P - параметр Op, который не является предметом обновления. Тогда Op
должна вести себя как операция только чтения, насколько это относится к P, и, следовательно, все аспекты IM-предписания 16 должны быть применимы.
Пусть Op - операция обновления, пусть P
- параметр Op, который является предметом обновления, и пусть T
является объявленным типом для P. Тогда неясно, должно ли допускаться, чтобы объявленный тип (и, следовательно, тем более, текущий наиболее конкретный тип) аргумента-переменной, соответствующего параметру P в некотором вызове Op, был собственным подтипом типа T (в некоторых случаях это должно допускаться, а в некоторых - нет). Из этого следует, что для каждой такой операции обновления Op и для каждого параметра P операции Op, который является предметом обновления, необходимо явно установить, для каких подтипов объявленного типа T параметра P операция Op должна наследоваться – Принцип Наследования Операций (Обновления). (И если операция обновления Op не наследуется таким образом типом T', она не должна наследоваться и никаким подтипом типа T'.) Таким образом, операции обновления должны быть только условно полиморфными – Принцип Полиморфизма Операций (Обновления). Если Op является операцией обновления, P - параметр Op, который является предметом обновления, и T'
является таким подтипом объявленного типа T
для P, что для T' наследуется Op, то по определению должно быть можно вызывать Op с аргументом-переменной, соответствующим параметру P, когда этот аргумент принадлежит объявленному типу T' – Принцип Возможности Замены (Переменных).
Объединенный тип (union type) - это такой тип T, что не существует значения, которое принадлежит типу T и не принадлежит какому-либо собственному подтипу T (то есть не существует такого значения v, что MST(v) есть T). Фиктивный тип (dummy type) - это объединенный тип, который не имеет никакого объявленного возможного представления (и, следовательно, никакого селектора); должно разрешаться, чтобы данный объединенный тип был фиктивным типом, если и только если этот объединенный тип не имеет никакого регулярного непосредственного супертипа (где регулярный тип - это тип, который не является фиктивным типом). Более того,
по отношению к каждому скалярному типу; по определению он не имеет никакого объявленного возможного представления и никаких собственных подтипов.
Пусть типы T и T' оба являются типами кортежа или оба являются типами отношения с заголовками
{ <A1,T1>, <A2,T2>, …, <An,Tn> }
{ <A1,T1'>, <A2,T2'>, …, <An,Tn'> }
соответственно. Тогда тип T' является подтипом
типа T (или, эквивалентно, тип T является супертипом типа T'), если и только если для всех i (i = 1, 2, …, n), тип Ti' является подтипом типа Ti (или, эквивалентно, тип Ti является супертипом типа Ti').
Пусть H - заголовок кортежа или заголовок отношения, определенный следующим образом:
{ <A1,T1>, <A2,T2>, …, <An,Tn> }
Тогда:
a. кортеж t соответствует заголовку H, если и только если t имеет вид
{ <A1,T1',v1>, <A2,T2',v2>, …, <An,Tn,vn> }
где для всех i (i = 1, 2, …, n), тип Ti' является подтипом типа Ti и vi - значение типа Ti'.
c. отношение r соответствует заголовку H,
если и только если r состоит из заголовка и тела, где:
· Заголовок r имеет вид
{ <A1,T1'>, <A2,T2'>, …, <An,Tn'> }
где для всех i (i = 1, 2, …, n), тип Ti' является подтипом типа Ti;
· Тело r - это множество кортежей, которые все соответствуют заголовку r.
Пусть все три типа T, T_alpha, и T_omega - это типы кортежей или типы отношений с заголовками
{ <A1,T1>, <A2,T2>, …, <An,Tn> }
{ <A1,T1_alpha>, <A2,T2_alpha>, …, <An,Tn_alpha> }
{ <A1,T1_omega>, <A2,T2_omega>, …, <An,Tn_omega> }
соответственно. Тогда типы T_alpha и T_omega
являются максимальным типом по отношению к типу T и минимальным типом по отношению к типу T соответственно, если и только если для всех i (i
= 1, 2, …, n) тип Ti_alpha является максимальным типом по отношению к типу Ti и Ti_omega является минимальным типом по отношению к типу Ti.
Пусть H - заголовок кортежа или заголовок отношения, определенный следующим образом:
{ <A1,T1>, <A2,T2>, …, <An,Tn> }
Тогда:
- Если t - кортеж, соответствующий H – в том смысле, что t имеет вид
{ <A1,T1',v1>, <A2,T2',v2>, …, <An,Tn’,vn> }
где для всех i (i = 1, 2, …, n) тип Ti' является подтипом типа Ti',
и vi - это значение типа Ti', то наиболее конкретным типом t
является
TUPLE { <A1 ,MST1>, <A2, MST2>, …, <An MSTn> }
где для всех i (i = 1, 2, …, n) тип MSTi является наиболее конкретным типом значения vi.
- Если r - отношение, соответствующее H – в том смысле, что тело r является множеством кортежей, каждый из которых имеет в качестве своего наиболее конкретного типа тип, являющийся подтипом типа TUPLE{H}, и в том смысле, кроме того, что каждый кортеж можно считать без потери общности имеющим вид
{ <A1,T1',v1>, <A2,T2',v2>, …, <An,Tn’,vn> }
где для всех i (i = 1, 2, …, n), тип Ti' является подтипом типа Ti
и наиболее конкретным типом значения vi
(отметим, что разные кортежи в теле r
будут в общем случае принадлежать разным наиболее конкретным типам; таким образом, тип Ti' различается для разных кортежей в теле r) – то наиболее конкретным типом r является
RELATION { <A1, MST1>, <A2, MST2>, …, <An, MSTn> }
где для всех i (i = 1, 2, …, n), тип MSTi является наиболее конкретным общим супертипом этих наиболее конкретных типов Ti', взятых для всех кортежей в теле r.
Пусть переменная (кортежа или отношения) V имеет объявленный тип T, и пусть заголовок T имеет атрибуты A1,A2, …, An. Тогда можно моделировать V как множество именованных упорядоченных триплетов вида <DTi,MSTi,vi>, где:
Имя каждой тройки является именем соответствующего атрибута.
DTi является именем объявленного типа атрибута Ai.
MSTi является именем наиболее конкретного типа – называемого также как текущим наиболее конкретным типом – (для) атрибута Ai. (Если V - переменная отношения, то наиболее конкретный тип Ai
определяется как наиболее конкретный общий супертип наиболее конкретных типов m значений в vi – см. объяснение vi
ниже.)
Если V - переменная кортежа, то vi - это значение наиболее конкретного типа MSTi
– текущее значение (для) атрибута Ai. Если V - переменная отношения, то пусть тело текущего значения V состоит из m кортежей; пометим эти кортежи (в некоторой произвольной последовательности) как “tuple 1”, “tuple 2”, … “tuple m”; тогда vi является последовательностью из m значений (не обязательно различных), являющихся значениями Ai из tuple 1, tuple 2, … tuple m
(в таком порядке); отметим, что все эти значения принадлежат типу MSTi.
Обозначения DT(Ai), MST(Ai), v(Ai) используются для ссылок на компоненты DTi, MSTi, vi соответственно атрибута Ai этой модели переменной кортежа или отношения V. Мы также используем обозначения DT(V), MST(V), для ссылки на объявленный тип целиком, текущий наиболее конкретный тип целиком и текущее значение целиком соответственно переменной кортежа или отношения V. Отметим, что фактически MSTi(Ai) подразумевается v(Ai), и MST(V) подразумевается v(V).
Пусть теперь X - выражение кортежей или отношений. Только что введенные обозначения Dti(V), MSTi(V),vi(V) можно очевидным образом расширить для ссылки на объявленный тип Dti(X), текущий наиболее конкретный тип MSTi(X)и текущее значение vi(X) соответственно компонентов Dti, MSTi, vi атрибута Ai
выражения кортежей или отношений X.