ЗМІННІ І оператор привласнення

Припустимо, що є дві змінні Е і з з оголошеними типами, відповідно, ELLIPSE і CIRCLE, як показано нижче

VAR E ELLIPSE VAR З CIRCLE

Припустимо, що відбувається ініціалізація змінної з для визначення деякої окружності, припустимо (просто, щоб цей приклад був більш конкретним), окружності з радіусом три і центром на початку координат

С: = CIRCLE (LENGTH (30), POINT (00, 00))

У цьому прикладі вираз праворуч від оператора присвоювання являє собою виклик селектора для типу CIRCLE Як було зазначено в розділі 5, для кожного оголошеного можливого подання передбачений конкретний оператор селектора з тим же імям і з формальними параметрами, відповідними компонентам розглянутого можливого подання Призначення селектора полягає в тому, щоб дати користувачеві можливість визначати або вибирати значення розглянутого типу, надаючи значення для кожного компонента розглянутого можливого подання

Примітка Для спрощення тут і далі у цій главі передбачається, що декартово можливе подання для точок називається POINT, а не (як в розділі 5) CARTESIAN Тому другим фактичним параметром в селекторі CIRCLE в даному прикладі є виклик цього селектора декартових координат для точок

Тепер розглянемо наступний оператор присвоювання

Е: = С

У звичайних обставинах (тобто за відсутності застосування підтипів і успадкування) для виконання відповідної операції привласнення потрібно, щоб значення, представлене виразом в правій частині, мало той же тип (а саме, оголошений тип), що й змінна в лівій частині Але з принципу заменяемости значень випливає, що в будь-якому місці, де система очікує значення типу ELLIPSE, завжди можна підставити значення типу CIRCLE, тому дана операція привласнення є допустимою (фактично операція присвоювання є поліморфною) Крім того, дія цієї операції зводиться до того, що значення окружності копіюється з змінної З

в змінну Е, тому значення змінної Е після цього присвоювання відноситься до типу CIRCLE, а не до типу ELLIPSE Іншими словами, справедливі наведені нижче твердження

■&nbsp&nbsp&nbsp&nbsp Значення зберігають свій найбільш конкретний тип після їх присвоювання змін вим найменш конкретного оголошеного типу При такому присвоєнні преобразо вання типів НЕ проісходіт6 (у даному прикладі коло не перетвориться так, щоб вона стала просто еліпсом) Слід також відзначити, що нам і не потрібно, щоб виконувалися будь-які подібні перетворення, оскільки вони приве чи б до втрати найбільш конкретних функціональних властивостей розглянутого значення Наприклад, в даному випадку застосування такого перетворення означало б, що після присвоювання ми втрачаємо можливість визначити радіус з значе ня кола у змінній Е (Див підрозділ Оператор TREAT DOWN, приве денний нижче в даному розділі, де описано, які дії необхідно виконати нитка для вирішення зазначеного завдання визначення радіуса)

■ Тому з поняття заменяемости випливає, що змінна оголошеного типу т може мати будь-яке значення, найбільш конкретним типом якого є будь підтип типу Т Тому необхідно враховувати, що користувачі типів і підтипів зобовязані ретельно враховувати логічне відмінність між оголошеним типом деякої змінної і найбільш конкретним типом поточного значення цієї змінної Ми повернемося до цього важливого питання в наступному підрозділі

Продовжуючи наведений вище приклад, припустимо, що тепер передбачена ще одна змінна А з оголошеним типом AREA, як показано нижче

VAR  A  AREA   

Розглянемо наступний оператор присвоювання

А: = AREA (Е):

Нижче описано, що відбувається при виконанні даного оператора

■ По-перше, система виконує перевірку типів на етапі компіляції вирази AREA (E) Ця перевірка завершується успішно, оскільки Е відноситься до оголошений ному типу ELLIPSE, а єдиний формальний параметр оператора AREA також відноситься до оголошеного типу ELLIPSE, як показано в розділі 202

■ По-друге, система на етапі прогону виявляє, що поточним найбільш кон конкретним типом змінної Е (вірніше, що зберігається в ній значення) є CIRCLE, і тому викликає версію оператора AREA, яка відноситься до окруж ностям іншими словами, система виконує процес звязування на етапі прого на, описаний в попередньому розділі

Безумовно, той факт, що викликається версія оператора AREA, що відноситься до кіл, а не версія для типу ELLIPSE, не повинен турбувати користувача ще раз зазначимо, що з точки зору користувача існує тільки один onepaтop AREA

6 І дійсно, навіть побіжний аналіз показує, що сама ідея подібного перетворення безглузда, оскільки навіть якби воно було можливо, це означало б, що одне і те ж значення може ставитися до двох найбільш конкретним типам одночасно

Змінні

Вище було показано, що поточне значення v змінної V оголошеного типу т може мати будь підтип типу т в якості свого найбільш конкретного типу З цього випливає, що існує можливість моделювати змінну v як упорядковану трійку у формі Тут використовуються позначення, описані нижче

■ DT Оголошений тип (Declared Type – DT) змінної V

■ MST Поточний найбільш конкретний тип (Most Specific Type – MST) для змін ної V (під цим мається на увазі найбільш конкретний тип значення, яке яв ляется поточним значенням змінної V)

■ v Значення найбільш конкретного типу MST, а саме поточне значення змін ної V

Для позначення компонентів DT, MST і v розглянутої моделі змінної V використовуватимуться, відповідно, позначення DT (V), MST (v) і v (V) Необхідно враховувати наступне: по-перше, MST (V) завжди являє собою підтип (причому не обовязково строгий підтип) типу DT (V) по-друге, компоненти MST (V) і v (V) у загальному можуть змінюватися у часі по-третє, компонент MST (V) фактично визначається компонентом v (V), оскільки кожне значення відноситься до одного і тільки одному найбільш конкретному типу

Ця модель змінної може застосовуватися для докладного аналізу семантики різних операцій, включаючи, зокрема, операції привласнення Але перш ніж приступити до цього аналізу, необхідно пояснити, що поняття оголошеного типу та поточного найбільш конкретного типу можуть бути очевидним чином доповнені, щоб вони могли застосовуватися не тільки до простих змінним, а й до довільних виразів Припустимо, що х-такий вислів, av (X) – результат обчислення цього виразу У такому випадку справедливі наведені нижче твердження

■ Вираз х має оголошений тип DT (X), а саме оголошений тип операто ра Oр, який викликається на самому зовнішньому рівні вираження X Тип DT (X) стає відомим на етапі компіляції

■ Вираз х має також поточний найбільш конкретний тип MST (X), а саме тип, який є найбільш конкретним типом значення v (X) Тип MST (X) (у загальному) залишається невідомим до етапу прогону

Тепер ми можемо приступити до докладного опису дії оператора присвоювання Розглянемо наступний оператор присвоювання

V   : =   X   

Тут V – змінна, а х – вираз Тип DT (X) повинен бути підтипом типу DT (V), тому що в противному випадку цей оператор присвоювання стає неприпустимим (перевірка відбувається на етапі компіляції) А якщо оператор присвоювання є допустимим, то результат його дії зводиться до того, що тип MST (V) стає рівним типом MST (X), а значення v (V) – рівним значенню v (X)

До речі, слід зазначити, що якщо поточний найбільш конкретний тип змінної V дорівнює т, то кожен строгий супертіп типу т також є поточним типом змінної V

Наприклад, якщо змінна Е (оголошеного типу ELLIPSE) має поточне значення найбільш конкретного типу CIRCLE, то поточними типами Е є відразу всі типи – CIRCLE, ELLIPSE і PLANE_FIGURE Але вираз поточний тип X зазвичай застосовується, щонайменше, неформально для позначення саме найбільш конкретного типу MST (x)

Додаткові відомості про заменяемости Розглянемо наступне визначення оператора

OPERATOR COPY ( E ELLIPSE )

RETURNS ELLIPSE RETURN ( E ) END OPERATOR

Завдяки використанню заменяемости оператор COPY можна викликати із зазначенням в якості фактичного параметра найбільш конкретного типу або типу ELLIPSE, або типу CIRCLE, і, безумовно, до якого б типу не ставився цей фактичний параметр, оператор COPY повинен повернути результат з тим же найбільш конкретним типом Тому з визначення заменяемости випливає ще один наслідок, що якщо оператор Ор визначений як має результат оголошеного типу т, то фактичний результат виклику оператора Ор може (в загальному) ставитися до будь-якого підтипу типу т Іншими словами, так само як, по-перше, посилання на змінну оголошеного типу т може (в загальному) фактично вказувати на значення будь-якого підтипу типу т, так і, подруге, виклик будь-якого оператора з оголошеним типом т може (знову-таки, в загальному) фактично повертати значення будь-якого підтипу типу т

Оператор TREAT DOWN

Ще раз розглянемо приклад, наведений на початку даного розділу

VAR E ELLIPSE VAR З CIRCLE

С: = CIRCLE (LENGTH (30), POINT (00, 00))

Е: = С

Тепер компонент моделі змінної MST (E) являє собою тип CIRCLE Тому припустимо, що потрібно визначити радіус розглянутого кола та привласнити його деякої змінної L Перша спроба виконати таку дію може полягати в наступному

VAR L LENGTH

L: = THE_R (E) / * Помилка невідповідності типів на етапі

компіляції * /

Але, як зазначено в коментарі до цього коду, спроба його застосування закінчується невдачею через помилку при перевірці типу на етапі компіляції А саме, таке невдале завершення відбувається через те, що оператор THE_R (оператор визначення радіуса), присутній в правій частині оператора присвоювання, вимагає використання фактичного параметра типу CIRCLE, а оголошеним типом змінної Е є ELLIPSE, а не CIRCLE Слід зазначити, що якби така перевірка типів на етапі компіляції не було виконане, то ми отримали б замість помилки часу компіляції помилку через невідповідність типів на етапі прогону (а це набагато гірше) у разі

виявлення того, що значення Е на етапі прогону являє собою просто еліпс, а не коло Проте, в ситуації, що розглядається нам відомо, що на етапі прогону дане значення представлятиме собою коло, але вся складність полягає в тому, що ми це знаємо, а компілятор-ні

Для вирішення подібних проблем автор пропонує ввести новий оператор і присвоїти йому неформальну назву TREAT DOWN (розглядати як відноситься до підтипу) У такому випадку правильний спосіб отримання радіуса в даному прикладі стає таким, як показано нижче

L := THE_R ( TREAT_DOWN_AS_CIRCLE ( E ) ) :

Вираз TREAT_DOWN_AS_CIRCLE (E) визначається як відноситься до оголошеного типу CIRCLE, тому тепер перевірка типів на етапі компіляції закінчується успішно Потім на етапі прогону здійснюються описані нижче дії

■ Якщо поточне значення змінної Е дійсно відноситься до типу CIRCLE, то все це вираження успішно повертає радіус даної кола Точніше, виклик оператора TREAT DOWN призводить до отримання деякого результату, скажімо, z, який, по-перше, має оголошений тип DT (Z), рівний CIRCLE, оскільки задана специфікація . _AS_CIRCLE (… Як окружність) по-друге, відно сится до поточного найбільш конкретному типу MST (Z), рівному MST (E), який в даному прикладі також представляє собою CIRCLE по-третє, має поточне значення v (Z), рівне v (E) нарешті, по-четверте, обчислюється вираз THE_R (Z), що дозволяє отримати необхідне значення радіуса (яке потім може бути присвоєно змінної L)

■ Але якщо поточне значення Е відноситься тільки до типу ELLIPSE, а не до типу CIRCLE, то виконання оператора TREAT DOWN на етапі прогону закінчується невдачею через помилку, повязаної з невідповідністю типів

Загальне призначення оператора TREAT DOWN СКЛАДАЄТЬСЯ У забезпеченні того, щоб помилки через невідповідність типів ко час прогону могли виникати тільки в контексті виклику самого оператора TREAT DOWN

Примітка Припустимо, що тип CIRCLE, в свою чергу, має строгий підтип, скажімо, O_CIRCLE (О-окружність тут під О-окружністю мається на увазі коло з центром на початку координат), який визначений, як показано нижче

TYPE O_CIRCLE IS CIRCLE

CONSTRAINT THE_CTR ( CIRCLE ) = POINT ( 00, 00 ) POSSREP { R = THE_R ( CIRCLE ) }

У такому випадку в деякий момент часу поточне значення змінної Е може відноситися до найбільш конкретному типу O_CIRCLE, а не просто CIRCLE Якщо справа йде таким чином, то наведений нижче виклик оператора TREAT DOWN завершиться успішно

TREAT_DOWN_AS_CIRCLE (Е)

Цей виклик призведе до отримання результату, скажімо, Z, такого що, по-перше,

його тип DT (Z) дорівнює CIRCLE, оскільки задана специфікація . _AS_CIRCLE ;

по-друге, тип MST (Z) дорівнює O_CIRCLE, оскільки O_CIRCLE – найбільш конкретний тип змінної Е і по-третє, значення v (Z) дорівнює v (E) Іншими словами (висловлюючись неформально), оператор TREAT DOWN завжди залишає незмінним найбільш конкретний тип і ні за яких обставин »не просуває його вгору по ієрархії типів, щоб він став менш конкретним, ніж перед цим

Нижче наведено призначене для використання в майбутньому більш формальне визначення семантики виклику оператора TREAT_DOWN_AS_T (X), де х-деякий вираз По-перше, тип MST (X) повинен бути підтипом типу Т (перевірка цього виконується на етапі прогону) якщо припустити, що ця умова задовольняється, то даний виклик повертає результат Z з типом DT (Z), рівним т, типом MST (Z), рівним MST (X), і значенням v (Z), рівним v (X)

Примітка У [33] визначена також узагальнена форма оператора TREAT DOWN, яка дозволяє розглядати один операнд як відноситься до типу іншого, а не як відноситься до деякого явно зазначеного типу

Джерело: Дейт К Дж, Введення в системи баз даних, 8-е видання: Пер з англ – М: Видавничий дім «Вільямс», 2005 – 1328 с: Ил – Парал тит англ

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*