Subtypes and Supertypes Setting the Scene

       

THE_операции


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

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

  • Ее единственный параметр принадлежит к объявленному типу T.
  • Если вызов операции появляется в позиции "источника" (в частности, в правой части операции присваивания), то он возвращает компонент Ci аргумента. (Более точно, возвращается значение компонента Ci возможного представления PR(v) значения аргумента v.)
  • Если вызов операции появляется в позиции "цели" (в частности, в левой части операции присваивания), то, во-первых, этот аргумент должен быть явно специфицирован как скалярная переменная, а не как произвольное скалярное выражение; во-вторых, вызов действует как псевдопеременная в том смысле, что в действительности указывает на компонент Ci аргумента -- а не только возвращает его значение. (Более точно, он указывает на компонент Ci возможного представления PR(V) своего аргумента-переменной V.)

    Замечание: Термин псевдопеременная взят из PL/1. Однако помните, что псевдопеременные в PL/1 не могут быть вложенными, а THE_псевдопеременные - могут. Другими словами, мы действительно относимся к вызовам псевдопеременных как к ссылкам на переменные, из чего следует, помимо прочего, что они могут появляться в качестве аргументов других таких вызовов.

    Вот пример:

    TYPE TEMPERATURE POSSREP CELSIUS ( C RATIONAL ) ;

    VAR TEMP TEMPERATURE ; VAR CEL RATIONAL ;

    CEL : = THE_C ( TEMP ) ; THE_C ( TEMP ) : = CEL ;

    В первом из этих присваиваний переменной CEL типа RATONAL присваивавется температура, соответствующая текущему значению переменной TEMP типа TEMPERATURE, преобразованная при необходимости к градусам Цельсия; во втором присваивании текущее значение переменной CEL типа RATIONAL, рассматриваемое как температура в градусах Цельсия, используется для обновления переменной TEMP типа TEMPERATURE.
    Таким образом, операция THE_C раскрывает возможное представление "градусы Цельсия" температур (для целей и чтения, и обновления). Однако это возможное представление не обязательно является действительным представлением. Например, температуры могли бы реально представляться в градусах Ференгейта, а не Цельсия.

    Вот слегка более сложный пример с использованием ранее определенного типа POINT:

    VAR Z RATIONAL ; VAR P POINT ;

    Z : = THE_X ( P ) ; THE_X ( P ) : = Z ;

    В первом из этих присваиваний переменной Z типа RATIONAL присваивается координата X точки, соответствующей текущему значению переменной P типа POINT; во втором присваивании текущее значение переменной Z типа RATIONAL используется для обновления координаты X переменной P типа POINT (говоря немного вольно). Следовательно, как отмечалось ранее, операции THE_X и THE_Y раскрывают возможное представление точек на основе Декартовых координат для целей и чтения, и обновления; однако снова это возможное представление не обязательно то же, что и какое-либо действительное представление.

    И еще один пример, основанный на предыдущем (здесь LINESEG обозначает отрезок прямой):

    TYPE LINESEG POSSREP ( BEGIN POINT, END POINT ) ; /* начальная и конечная точки -- соответствующий */ /* селектор по умолчанию называется LINESEG */

    VAR Z RATIONAL ; VAR LS LINESEG ;

    Z : = THE_X ( THE_BEGIN ( LS ) ) ; THE_X ( THE_BEGIN ( LS ) ) : = Z ;

    В первом из этих присваиваний переменной Z присваивается координата X точки начала текущего значения LS. Во втором присваивании текущее значение Z используется для обновления координаты X точки начала переменной LS. (Обратите внимание на вложенность псевдопеременных в этом втором присваивании.) Таким образом, операции THE_BEGIN и THE_END раскрывают возможное представление отрезков на основе "точек начала и конца" -- снова для целей и чтения, и обновления. Однако снова это возможное представление не обязательно совпадает с каким-либо реальным представлением.

    Кстати, в Манифесте требуется также поддержка множественной формы присваивания.Так, например, можно использовать оператор

    THE_BEGIN ( LS ) : = P , THE_END ( LS ) : = Q ;

    для обновления точек начала и конца переменной отрезка LS в одной операции.


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