Три манифеста баз данных ретроспектива и перспективы
1942e8f8

По поводу приведенных примеров следует сделать несколько замечаний:


  • С уществует существенное логическое различие между (a ) формальными операндами, или параметрами, в терминах которых определяется данная операция и (b ) реальными операндами, или аргументами, которые передаются любому вызову этой операции. (Эта разница становится особенно значительной, если поддерживается наследование типов.)

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

    Важное логическое различие имеется между операциями обновления и операциями только чтения. Операции обновления применяются к переменным, а не к значениям. Следовательно, операции только чтения применяются к значениям (в частности, они  применимы к значениям, которые являются текущими значениями переменных); операции обновления применяются именно к переменным.

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

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

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

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

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

    Как отмечалось ранее, в определении любого скалярного типа должно указываться по крайней мере одно объявленное возможное представление для значений этого скалярного типа (и при таком заданном скалярном типе T и таком возможном представлении PR каждое значение типа T должно быть представимо посредством PR ).118Объявление возможного представления автоматически приводит в действие поддержку соответствующего селектора (и нельзя обеспечить селекторы никаким другим способом). Следовательно, селекторы и возможные представления находятся во взаимно однозначном соответствии друг с другом (параметры селекторов и компоненты возможных представлений находятся также во взаимно однозначном соответствии). Поэтому можно принять соглашение о задании селектору и соответствующему возможному представлению одного и того же имени (хотя они являются логически различными понятиями).

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




    Объявленный тип этого символа ( который является, конечно, частным случаем выражения) также определяется самим.

    Вернемся к примеру определяемого пользователем типа POINT , чтобы обсудить  вопросы определения

    и реализации типов. Повторим в упрощенном виде определение этого типа:

    TYPE POINT
         POSSREP POINT  { X LENGTH, Y LENGTH }
         POSSREP POLAR { R LENGTH, THETA ANGLE } ;

    В данном примере в определении типаспецифицированы два объявленных возможных представления –  POINT и POLAR . Следовательно, будут существовать две соответствующие операции выбора: POINT , которая позволяет пользователю задавать декартовы координаты X и Y как два значения типа LENGTH и возвращает соответствующее значение типа POINT , и POLAR , которая позволяет пользователю задавать полярные координаты R и THETA как значения типов LENGTH и ANGLE соответственно и возвращает соответствующее значение типа POINT .

    Предположим, что представление с декартовыми координатами на самом деле является реальным. Тогда в системе будут поддерживаться высоко защищенные операции, не входящие в D ,  которые раскрывают это реальное представление, и реализатор типа будет использовать эти операции для реализации требуемых селекторов POINT и POLAR . Вот, например, возможная реализация (псевдокод) для селектора POINT :

    OPERATOR POINT ( X LENGTH, Y LENGTH ) RETURNS POINT ;
       BEGIN ;
          VAR P POINT ;
          P.X   :=  X ;          /* assign to actual representation */
          P.Y   :=  Y ;          /* assign to actual representation */
          RETURN P ;
       END ;

    END OPERATOR ;

    “Высоко защищенные операции, не входящие в D ” представлены в приведенном коде посредством точечной нотации. Селектор POLAR также мог бы быть реализован “вне среды D ” (снова псевдокод): 

    OPERATOR POLAR ( R LENGTH, THETA ANGLE ) RETURNS POINT ;
       BEGIN ;
          VAR P POINT ;
          P.X   :=  R * COS ( THETA ) ;           
          P.Y   :=  R * SIN ( THETA ) ;           
          RETURN P ;
       END ;

    END OPERATOR ;

    Но селектор POLAR , возможно, менее эффективно мог бы быть реализован в терминах селектора POINT :



    OPERATOR POLAR ( R LENGTH, THETA ANGLE ) RETURNS POINT ;
       RETURN POINT ( R * COS ( THETA ), SIN ( THETA ) ) ;

    END OPERATOR ;

    Из всего этого следует, что реализаторы типа(но не определители типа и, конечно, не пользователи типа) должны на самом деле знать реальные представления.

    Пусть PR - это возможное представление скалярного типа T , и пусть у PR имеются компоненты C 1 , C 2 , …, Cn . Определим THE _ C 1 , THE _ C 2 , …, THE _ Cn как семейство операций, таких что для каждогоi (i = 1, 2, …, n ), операция THE _ Ci обладает следующими свойствами:

    Ее единственный параметр имеет тип T .

    Если ссылка на операцию, появляется в позиции “источника” (в частности, в левой части присвоения), то операция возвращает компонент Ci своего аргумента. (Точнее, она возвращает значение компонента Ci возможного представления PR ( v ) значения своего аргумента v .)

    Если ссылка на операцию, появляется в позиции “цели” (в частности, слева от присвоения), то:

    Аргумент должен быть явно указан как переменная, а не произвольное выражение.

    Ссылка действует как ссылка на псевдопеременную, и это означает, что она реально обозначает компонент Ci этого аргумента, а не только возвращает значение его значение. (Точнее, она обозначает компонент Ci возможного представления PR ( V ) аргумента-переменной V .)

    Несколько примеров :

    TYPE TEMPERATURE POSSREP CELSIUS { C RATIONAL } ;

    VAR TEMP TEMPERATURE ;

    VAR CEL RATIONAL ;

    CEL  :=  THE_C ( TEMP ) ;

    THE_C ( TEMP )  :=  CEL ;

    В первом присваивании температура, измеренная в градусах Цельсия, которая является текущим значением переменной TEMP типа TEMPERATURE , присваивается переменной CEL типа RATIONAL ; во втором – текущее значение переменной CEL типа RATIONAL , рассматриваемое как температура в градусах Цельсия, используется для обновления переменной TEMP типа TEMPERATURE . Операция THE _ C фактически раскрывает возможное представление температуры посредством “градусов Цельсия” как для целей обновления, так и для целей только чтения.


    Но это возможное представление не обязательно является реальным представлением; например, температуру можно было бы представлять в градусах Фаренгейта, а не в градусах Цельсия.

    Вот немного более сложный пример:

    TYPE POINT POSSREP POINT { X LENGTH, Y LENGTH } ;

    VAR L LEHGTH ;

    VAR P POINT ;

    L  :=  THE_X ( P ) ;

    THE_X ( P )  :=  L ;

    В первом присваивании переменной L типа LEHGTH присваивается координата X точки, являющейся текущим значением переменной P типа POINT ; во втором – текущее значение переменной L типа LEHGTH используется для обновления координаты X переменной P типа POINT . Операции THE _ X и THE _ Y фактически раскрывают возможное представление точек посредством “Декартовых координат” как для целей обновления, так и для целей только чтения; и снова это возможное представление не обязательно совпадает с реальным представлением.

        

    Заметим теперь, что псевдопеременные THE _ логически необязательны. Рассмотрим второе присваивание в первом примере. Это присваивание, в котором используется псевдопеременная, логически эквивалентно другому, в котором псевдопеременная не используется:

    TEMP   :=  CELSIUS ( CEL ) ;    /* вызов селектора CELSIUS */

    Вот логический эквивалент второго присваивания во втором примере без использования псевдопеременной:

    P  :=  POINT ( L, THE_Y ( P ) ) ;    /* вызов селектора POINT */

    Другими словами, псевдопеременные как таковые не являются строго необходимыми для поддержки обсуждаемой разновидности обновления на уровне компонентов. Однако подход с использованием псевдопеременных интуитивно выглядит более привлекательным, чем альтернативный (для которого первый подходможно рассматривать как сокращенную форму); более того, он также обеспечивает высокую степень устойчивости к изменениям синтаксиса соответствующего селектора. 

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


    Содержание раздела