|
Программирование >> Хронологические базы данных
Здесь тип MST{E) - CIRCLE. Предположим, что требуется получить радиус данной окружности и присвоить его некоторой переменной L. Можно попытаться сделать это так. VAR L LENGTH ; L := THE R ( Е ) ; /* Ошибка времени компиляции - недопустимый тип!!! */ Однако, как явствует из комментария, этот код во время компиляции выдает сообщение об ошибке о несоответствии типов. Точнее говоря, ошибка возникает из-за того, что оператор THE R ( радиус ) в правой части оператора присвоения требует, чтобы его аргумент относился к типу CIRCLE, а объявленный тип его аргумента Е - ELLIPSE, а не CIRCLE. Замечание. Если бы проверка во время компиляции не выполнялась и текущее значение Е во время выполнения оказалось бы эллипсом, а не окружностью, возникла бы ошибка времени выполнения, что еще хуже. В нашем случае, безусловно, заранее известно, что значение во время выполнения будет окружностью, и проблема состоит лишь в том, что мы знаем об этом, а компилятор - нет. Чтобы решить эту проблему, введем новый оператор, который неформально будем называть TREAT DOWN (трактовать). Теперь можно корректно обратиться к оператору THE R и получить радиус окружности. L := THE R ( TREAT DOWN AS CIRCLE ( Е ) ) ; Выражение 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, в свою очередь, имеет собственный подтип (скажем, О CIRCLE, где 0 CIRCLE - окружность, центр которой расположен в начале координат). TYPE 0 CIRCLE POSSREP ( R LENGTH ) SUBTYPE OF ( CIRCLE ) CONSTRAINT ( THE CTR ( 0 CIRCLE ) = POINT ( 0.0, 0.0 ) ) ; Тогда текущее значение переменной Е в данное время может иметь конкретный тип 0 CIRCLE, а не просто CIRCLE. Рассмотрим вызов оператора TREAT DOWN в этом случае. TREAT DOWN AS CIRCLE ( Е ) Его выполнение завершится нормально, и будет выдан результат (скажем, Z) с объявленным типом DT(Z), равным CIRCLE, поскольку задано уточнение ... AS CIRCLE, текущим конкретным типом MST(Z), равным типу 0 CIRCLE, поскольку 0 CIRCLE - это конкретный тип переменной Е, и текущим значением v(Z), равным v(E). Короче говоря, оператор TREAT DOWN всегда возвращает конкретный тип; он никогда не повыщает тип, чтобы сделать его менее конкретным, чем он был прежде. Приведем более формальное изложение семантики вызова оператора TREAT DOWN AS T (X), где X - некоторое скалярное выражение. Во-первых, тип Т должен быть подтипом типа DT(X) (это проверяется во время компиляции). Во-вторых, конкретный тип MST(X) должен быть подтипом типа Т (это проверяется во время выполнения). Если данные условия удовлетворяются, то после обращения к оператору возвращается результат Z с типом DT(Z), равным Т, типом MST(Z), равным типу MST(X), и текущим значением v (Z), равным v (X). Замечание. В [3.3] также определяется общая форма оператора TREAT DOWN, которая допускает, чтобы один операнд трактовался как имеющий тип другого операнда вместо некоторого явно указанного конкретного типа. 19.5. Специализация по ограничениям Рассмотрим следующий пример вызова оператора выбора для типа ELLIPSE. ELLIPSE { LENGTH ( 5.0 ), LENGTH ( 5.0 ), POINT (...)) Это выражение возвращает эллипс с одинаковыми полуосями. Однако эллипс с одинаковыми полуосями фактически является окружностью. Следует ли из этого, что данное выражение возвращает результат конкретного типа CIRCLE, а не ELLIPSE? Вопросы, подобные приведенному выше, вызывали (и продолжают вызывать) в литературе довольно бурные дискуссии. В нашей модели мы решили (после долгих раздумий), что лучше настаивать на том, чтобы выражение действительно возвращало результат конкретного типа CIRCLE. В общем виде это можно сформулировать так: если тип Т является подтипом типа Т, а в результате вызова оператора выбора для типа Т возвращается значение, которое удовлетворяет ограничениям типа для типа Т, то (в нашей модели) результат вызова оператора выбора будет иметь тип Т. Замечание. Предупредим, что лишь немногие существующие в настоящее время коммерческие реализации, если таковые вообще имеются, реально работают указанным образом, но мы считаем это просто одним из недостатков существующих систем. В [3.3] показано, к каким результатам приводит отсутствие подобной функциональности - такие системы вынуждены поддерживать некруглые окружности , неквадратные квадраты и другие нелепости, чего не скажешь в случае нашего подхода. В [3.3] для достижения подобного эффекта в определении типа Т предлагается использовать фразу SPECIALIZE. Однако впоследствии мы пришли к заключению, что для достижения желаемого результата никакого специального синтаксиса не требуется. Из вышесказанного следует (по крайней мере, в нашей модели), что нет значений конкретного типа ELLIPSE, для которых бы выполнялось равенство а = Ь. Иначе говоря, значения конкретного типа ELLIPSE относятся только к настоящим эллипсам, которые не являются окружностями. В других же моделях наследования, напротив, значения конкретного типа ELLIPSE соответствуют эллипсам, которые могут быть или не быть окружностями. Мы считаем нашу модель более приемлемой в качестве реальной модели . Идея, согласно которой, например, эллипс с полуосями а = b должен относиться к типу CIRCLE, называют специализацией по ограничениям [3.3], хотя следует предупредить, что некоторые авторы подразумевают под этим понятием совсем иное (см., например, [19.7] и [19.11]). Пересмотр оператора ТНЕ псевдопеременная Напомним, что в главе 5 оператор 1!ИВ псевдопеременная использовался для обновления одного компонента переменной, оставляя при этом остальные компоненты неизменными (здесь компоненты - это, конечно, компоненты некоторого возможного представления, а не обязательно реального представления). Пусть, например, переменная Е имеет объявленный тип ELLIPSE, и пусть текущим значением переменной Е будет эллипс с полуосями а = 5 и b = 3. Тогда в результате выполнения приведенного ниже оператора присвоения значение длины оси b переменной Е изменится, а длина оси а и положение центра останутся прежними. ТНЕ В ( Е ) := LENGTH ( 4.0 ) ; Как отмечалось в разделе 8.2 главы 8, операторы 1!ЕЕ псевдопеременная не являются логически необходимыми- фактически это просто удобные сокращения. Например, предыдущая команда присвоения с оператором ТНЕ В - это сокращенная запись для следующего оператора присвоения. Е := ELLIPSE ( ТНЕ А ( Е ), LENGTH ( 4.0 ), THE CTR ( Е ) ) ; Итак, рассмотрим приведенную ниже операцию присвоения. ТНЕ В { Е ) := LENGTH { 5.0 ) ; По определению это присвоение эквивалентно следующему оператору. Е := ELLIPSE ( ТНЕ А ( Е ), LENGTH ( 5.0 ), THE CTR ( Е ) ) ; Следовательно, здесь должна вступить в силу специализация по офаничениям (поскольку выражение в правой части операции присвоения возвращает эллипс с полуосями а = Ь). В результате после выполнения присвоения тип MST(E) должен быть CIRCLE,а не ELLIPSE. Рассмотрим еще одну операцию присвоения. ТНЕ В ( Е ) := LENGTH ( 4.0 ) ; Отметим, кстати, что оператор TREAT DOWN можно было бы использовать и как псевдопеременную [3.3], но, опять-таки, это будет просто сокращенная запись.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |