Предисловие В сборнике представлены статьи сотрудников Института системного программирования, описывающие результаты исследований, которые получены в 2002-2003 гг. В статьях обсуждаются как теоретические вопросы, так и аспекты организации прикладных систем. В статье И.Б. Бурдонова, А.С. Косачева и В.В. Кулямина “Асинхронные автоматы: классификация и тестирование” предлагается теория конечных автоматов, которые отличаются от классических автоматов Мили тем, что смена состояния автомата происходит либо при приеме входного символа, либо при выдаче выходного символа, причем выбор перехода всегда недетерминирован. Вводится понятие асинхронного автомата, в котором допускается смена состояния при отсутствии входного символа. Предлагается классификация асинхронных автоматов, основанная на реализуемой автоматом словарной функции и эквивалентности автоматов с совпадающей словарной функцией. Статья А.В. Чернова “Об одном методе маскировки программ” посвящена обсуждению подхода к защите от возможности восстановления исходного кода программы по ее объектному коду – маскировке (obfuscation) программ. Предлагаемый метод маскировки основан, главным образом, на преобразовании графа потока управления исходной программы. При использовании данного метода не затрагиваются структуры данных исходной программы, но в замаскированную программу вносится большое число несущественных зависимостей по данным. В статье Г.В. Ключникова, А.С. Косачева, Н.В. Пакулина, А.К. Петренко и В.З. Шнитмана “Применение формальных методов для тестирования реализации IPv6” представлен опыт разработки тестового набора для реализации протокола IPv6. Использовался метод разработки тестовых наборов на основе формальных спецификаций UniTesK, разработанный и развиваемый в ИСП РАН. Объектом тестирования была реализация протокола IPv6, выполненная в Microsoft Research. Описываются организация тестового набора и результаты проекта. Исследованию современных подходов, методов и технологии реинжиниринга информационных систем посвящена статья К.В. Ахтырченко и Т.П. Сорокваша “Методы и технологии реинжиринга ИС”. На основе проведенного анализа и вводимой авторами классификации дается оценка текущего состояния данной области. Предметом статьи В.В. Кулямина и О.Л. Петренко “Место тестирования среди методов оценки качества ПО” является оценка места тестирования в современном процессе производства программного обеспечения. Исследуются понятия качества ПО и значимости тестирования при обеспечении и контроле качества. 5
Статья Д.Н. Волкова “Вопросы организации распределенного хранения данных в системах обработки изображений” содержит анализ методов организации хранения данных в современных фотограмметрических системах. Описывается разработанный автором подход к организации распределенного хранилища данных для систем обработки изображений. В статье Л.Г. Новака и С.Д. Кузнецова “Свойства схем данных XML” изучаются свойства XML-схем и методов преобразования схем над моделью данных XML. Предлагается методика, позволяющая упростить алгоритмы управления данными и метаданными XML за счет выделения простых подклассов из множества XML-схем. Статья Д.Р. Ширяева “Автоматическая генерация графических пользовательских интерфейсов доступа к интегрированным данным на основе диаграмм классов UML” посвящена описанию выработанной автором технологии автоматического построения графических пользовательских интерфейсов к системе интеграции данных на основе представления глобальной схемы в виде диаграммы классов UML. Используя одно и то же представление глобальной схемы, оказывается возможным генерировать разные виды GUI – формы и каталоги, а также своеобразный интерфейс с навигацией по классам. Следует отметить, что многие из работ, представленных в сборнике, поддерживались грантами РФФИ и других научных фондов. Член-корреспондент РАН
6
В.П. Иванников
Асинхронные автоматы: классификация и тестирование И.Б. Бурдонов, А.С. Косачев, В.В. Кулямин Аннотация. В статье рассматриваются конечные автоматы, отличающиеся от классического автомата Мили тем, что переход осуществляется либо по приему стимула (входного символа), либо по выдаче реакции (выходного символа), причем в каждом состоянии выбор одного из допустимых переходов недетерминирован. Такими автоматами являются автоматы с отложенной реакцией (АОР), в которых переход по стимулу выполняется всегда, когда этот стимул имеется на входе автомата, и автоматы вводавывода (IOSM - Input/Output State Machines), в которых переход по выдаче реакции допустим независимо от наличия стимула, в то время как, принятый в этом состоянии стимул может быть принят позже, в другом состоянии. Обобщением этих классов автоматов является асинхронный автомат, в котором допускаются также переходы по отсутствию стимула. Предлагается классификация асинхронных автоматов, основанная на реализуемой автоматом словарной функции и эквивалентности автоматов с совпадающей словарной функцией. Показывается, что класс всех асинхронных автоматов эквивалентен своему подклассу автоматов с отложенными реакциями, а словарные функции автоматов ввода-вывода образуют собственное подмножество всех автоматных словарных функций. С автоматом связывается также множество сериализаций (смешанных последовательностей воспринимаемых стимулов и выдаваемых реакций), и исследуется его связь со словарной функцией. Статья завершается обзором основных проблем тестирования соответствия, когда асинхронные автоматы используются как спецификационная модель программных и аппаратных систем.
1. Введение Понятие автомата с отложенными реакциями (АОР) было введено авторами настоящей статьи совместно с А.Хорошиловым для моделирования многопроцессной программной системы, интерфейс которой основан на обмене сообщениями. В ответ на входное сообщение система может выдать несколько выходных сообщений, причем, если в процессе их выдачи поступает следующее входное сообщение, оно может изменить выходной поток. Целью моделирования являлось написание формальных спецификаций, на основе которых создавался тест для проверки соответствия реализации спецификации. Поскольку внутреннее состояние тестируемой системы было недоступно, она рассматривалась как «черный ящик» и о ее поведении можно было судить только по ее реакциям (выходным сообщениям) на подаваемые стимулы (тестовые входные сообщения). 7
Автоматы с отложенными реакциями похожи на хорошо известные в литературе [1-6] автоматы ввода-вывода (IOSM – Input/Output State Machines), называемые также взаимодействующими конечными автоматами (CFSM - Communicating Finite State Machines). В обоих автоматах переход из одного состояния в другой происходит либо как прием входного символа (стимула) – принимающий переход, либо как выдача выходного символа (реакции) – посылающий переход, либо как пустой переход, не сопровождающийся ни приемом стимула, ни выдачей реакции. Стимул допустим в некотором состоянии, если в этом состоянии определен принимающий переход по этому стимулу, в противном случае стимул недопустим в данном состоянии. Поскольку мы не требуем допустимости каждого стимула в каждом состоянии, рассматриваемые автоматы являются частично-определенными. Состояние автомата – принимающее, если в нем определены только принимающие переходы, посылающее, если в нем определены только посылающие или пустые переходы, смешанное, если в нем определены как принимающие, так и посылающие или пустые переходы, и терминальное, если в нем никаких переходов не определено. Принимающие и смешанные состояния будем называть рецептивными (в этих состояниях возможен прием стимула). Стимулы могут поступать на автомат только в рецептивном состоянии, но они не обязаны поступать в каждом его рецептивном состоянии. Переходы, допустимые в данном состоянии, определяются в зависимости от наличия или отсутствия стимула на входе автомата и, в случае наличия стимула, от самого этого стимула. Если оказывается, что таких допустимых переходов несколько, то выбирается один из них недетерминированным образом. В обоих автоматах, если состояние посылающее или рецептивное, но стимул отсутствует, то допустимыми являются посылающие и пустые переходы, определенные в этом состоянии. Различие между АОР и IOSM имеет место при определении допустимых переходов в случае наличия стимула в смешанном состоянии. Для АОР допустимы только принимающие переходы по этому стимулу и недопустимы как принимающие переходы по другим стимулам, так и посылающие и пустые переходы. Для IOSM также допустимы принимающие переходы по этому стимулу и недопустимы переходы по другим стимулам, однако посылающие и пустые переходы остаются допустимыми. При этом, если выполняется посылающий или пустой переход, то стимул остается на входе автомата в ожидании либо 1) выборки допустимого принимающего перехода по этому стимулу в другом рецептивном состоянии, либо 2) перехода в принимающее состояние, в котором не определен переход по данному стимулу. В случае 1) стимул выбирается автоматом и далее на его вход может поступить следующий стимул, а в случае 2) поведение автомата считается не определенным и это рассматривается как, так называемая, ошибка неспецифицированного ввода. Заметим, что для АОР такая ошибка фиксируется сразу же, как только на вход автомата поступает недопустимый в текущем состоянии стимул. Разумеется, возможно также выполнение автомата, при котором стимул никогда не будет выбран: если автомат перешел в терминальное состояние или бесконечно выполняются посылающие и пустые переходы (для 8
АОР – в посылающих состояниях). В терминальном состоянии автомат останавливается: состояние не меняется и прекращается как прием стимулов, так и выдача реакций. Хотя в терминальном состоянии все стимулы формально недопустимы, тем не менее ошибка неспецифицированного ввода не фиксируется, поскольку считается, что работа автомата закончена. Классический автомат Мили, который на каждый допустимый стимул выдает ровно одну реакцию и ничего не делает при отсутствии стимулов, может рассматриваться как частный случай АОР и IOSM. Для этого достаточно каждый его переход, сопровождающийся приемом стимула и выдачей реакции, представить как последовательность из двух переходов: принимающего перехода по этому стимулу и посылающего перехода по этой реакции, между которыми добавляется промежуточное посылающее состояние (исходные нетерминальные состояния становятся принимающими, а смешанных состояний нет). Тестирование соответствия основано на сравнении поведения двух автоматов: спецификационного, заданного явно, например, своим графом состояний, и реализационного, рассматриваемого как «черный ящик», о графе состояний которого и текущем состоянии мы не имеем информации, но можем судить о его поведении по тем реакциям, которые он выдает в ответ на поступающие к нему тестовые стимулы. Реализация считается соответствующей спецификации, если для любой последовательности стимулов (входного слова) автоматы выдают одинаковые последовательности реакций (выходные слова). Для недетерминированного спецификационного автомата более осмысленно говорить не о совпадении выходных слов, а о принадлежности любого выходного слова, выдаваемого реализацией, множеству выходных слов, разрешаемых спецификацией. Заметим, что при этом реализационный автомат может быть даже детерминированным (выходное слово однозначно определяется его начальным состоянием и входным словом). Иными словами, спецификация описывает не одну реализацию, а класс реализаций ей соответствующих (сводимых к ней). С автоматом связана словарная функция, им реализуемая и определяемая как отображение входного слова, подаваемого на автомат, начиная с его начального состояния, во множество возможных выходных слов. Область ее определения включает только допустимые входные слова, то есть, такие, которые не могут при некотором возможном выполнении автомата вызвать ошибку неспецифицированного ввода. По существу, тестирование соответствия ставит своей задачей определение словарной функции реализационного автомата и сравнение ее со словарной функцией спецификационного автомата: область определения этих словарных функций предполагается одинаковой (по крайней мере, модельный домен вложен в реализационный), а тестирование проверяет, что для каждого допустимого входного слова значение на нем реализационной словарной функции вложено в значение спецификационной словарной функции. Для классического автомата Мили такое определение словарной функции достаточно: все нетерминальные состояния рецептивны и подача на его вход 9
допустимого входного слова длины n вызывает последовательность переходов через m≤n рецептивных состояний, заканчивающуюся в m+1-ом терминальном или, если m=n, терминальном или рецептивном состоянии, и выдачу соответствующего выходного слова длины m. Однако, для АОР и IOSM, в которых посылающие и пустые переходы могут выполняться и при отсутствии стимулов, понятие словарной функции нуждается в уточнении. Для определения входного слова, кроме самой последовательности стимулов, нам следует рассматривать также «паузы» между соседними стимулами, которые естественно измерять в количестве рецептивных состояний, проходимых между приемом этих стимулов. Для моделирования прохода одного рецептивного состояния с отсутствием стимула на входе автомата удобно ввести понятие пустого стимула, расширив им алфавит стимулов. Если между двумя непустыми стимулами во входном слове располагается k пустых стимулов, то это означает, что автомат между приемами этих непустых стимулов пройдет k рецептивных состояний при отсутствии стимула на его входе. Пустой стимул считается допустимым в любом рецептивном состоянии. После этого удобно ввести понятия входной и выходной очередей автомата. Во входной очереди располагается входное слово в расширенном алфавите стимулов, а в выходную очередь поступают выдаваемые автоматом реакции, формируя в ней выходное слово. Принимающий переход по (непустому) стимулу допустим только в том случае, когда в голове входной очереди располагается этот стимул. При выполнении такого перехода стимул удаляется из очереди. Напомним, что в этой ситуации в рецептивном состоянии АОР всегда выполняет принимающий переход, а IOSM может выполнить также посылающий или пустой переход, и тогда непустой стимул остается в голове входной очереди. Если же головной стимул очереди пустой, то он в автоматах обоих видов удаляется при посылающем или пустом переходе из рецептивного состояния. Посылающий переход помещает в выходную очередь соответствующую реакцию и, если это переход из посылающего состояния, не изменяет входной очереди и не зависит от её содержимого. После этого словарная функция определяется на множестве допустимых входных слов в расширенном алфавите стимулов таким образом, что если во входную очередь автомата поместить данное допустимое входное слово, то множество выходных слов, которые могут оказаться в выходной очереди, как раз и есть значение словарной функции. Теперь обратим внимание на то, что для того, чтобы поведение автомата было полностью определено, входное слово должно содержать в конце «достаточное» число пустых стимулов. Иначе, может сложиться ситуация, когда автомат переходит в рецептивное состояние, а входная очередь пуста, то есть, не содержит не только непустые, но и пустые стимулы, хотя последние как раз и предназначены для моделирования пустоты очереди. Более того, если автомат содержит цикл из пустых и посылающих переходов, проходящий хотя бы через одно рецептивное состояние, то таких концевых пустых стимулов должно быть бесконечное число. Это наталкивает на мысль рассматривать словарную функцию определенной не на конечных, а на бесконечных входных словах. 10
Бесконечное слово, содержащее только конечное число непустых стимулов, является аналогом конечного слова и мы будем называть его квази-конечным словом. Мы будем определять словарную функцию на всех допустимых бесконечных словах, а не только квази-конечных. Причина этого в том, что в отличии от классического автомата Мили, в АОР и IOSM такая словарная функция, вообще говоря, не восстанавливается однозначно по ее сужению на поддомене всех допустимых квази-конечных входных слов (см. ниже 3.5.2). Теперь можно рассматривать естественное обобщение АОР и IOSM, заключающееся в том, что автомату разрешается выполнять принимающие переходы не только по непустому стимулу, но также и по пустому стимулу, то есть, поскольку пустой стимул моделирует отсутствие стимула, по отсутствию стимула на входе автомата. Такой переход будем называть e-переходом, а общий вид автомата с e-переходами - асинхронным автоматом, имея в виду, что выдача реакции происходит, вообще говоря, асинхронно с приемом стимула. (Наше понятие асинхронного автомата следует отличать от понятия асинхронно выполняющейся сети взаимодействующих автоматов.) Интерпретация поведения такого асинхронного автомата зависит от двух независимых факторов. Во-первых, от вида того автомата, из которого этот асинхронный автомат произошел – АОР или IOSM, а именно, является ли прием непустого стимула в рецептивном состоянии обязательным или не обязательным. В первом случае асинхронный автомат будем называть императивным, а во втором – факультативным. Во-вторых, поскольку удаление пустого стимула из головы входной очереди теперь может происходить при выборе либо, как раньше, посылающего или пустого перехода из рецептивного состояния, либо принимающего e-перехода, необходимо определиться с взаимным приоритетом этих двух видов переходов, если они определены в одном и том же смешанном состоянии. Приоритет может быть: 1) у посылающих и пустых переходов; 2) у e-переходов; 3) они могут быть равноприоритетны. Таким образом, всего может быть 8 базовых классов автоматов: императивный или факультативный, без e-переходов или с e-переходами и одним из трех указанных приоритетов e-переходов по отношению к посылающим и пустым переходам. Статья состоит из четырех частей. 2-ая (после Введения) часть посвящена определению и сравнительному изучению асинхронных автоматов базовых классов. При этом, в первую очередь, обращается внимание на реализуемые ими словарные функции. С помощью преобразований автоматов, сохраняющих их словарную функцию, все автоматы приводятся к одному классу автоматов без смешанных состояний. На этой основе проводится классификация автоматов, в частности показывается эквивалентность класса всех асинхронных автоматов подклассу АОР – императивных автоматов без e-переходов, и, напротив, 11
показывается, что класс IOSM – факультативных автоматов без e-переходов – не способен моделировать класс всех асинхронных автоматов. В 3-ей части изучаются реализуемые автоматами сериализации (смешанные последовательности стимулов и реакций) и маршруты (последовательности переходов). Вводятся понятия строгой моделируемости и строгой эквивалентности, основанные не на словарной функции, а на множестве реализуемых сериализаций, и показывается, что преобразования автоматов, использованные во 2-ой части, сохраняют не только словарную функцию, но и множество сериализаций. Устанавливается связь словарной функции и множества сериализаций автомата. Рассматриваются вопросы регулярности и существования отвергающих автоматов. Далее рассматриваются конечные сериализации, предикаты на множестве конечных сериализаций и индуцируемые такими предикатами семейства автоматов с соответствующими им словарными функциями. 4-ая часть посвящена проблемам тестирования соответствия для асинхронных автоматов. Проводится разделение на гипотезы – предусловия тестирования, и тестируемые условия, проверяемые в процессе тестирования. Для каждой проблемы намечаются возможные пути ее решения.
2. Словарная функция 2.1. Асинхронный автомат Асинхронным автоматом будем называть шестерку m=(V,v0,X,e,Y,T), где: • V – множество состояний; • v0∈V – начальное состояние; • X – входной алфавит стимулов; • e∉X – пустой стимул, X`=X∪{e} – расширенный алфавит стимулов; • Y – выходной алфавит реакций; будем считать, что алфавиты стимулов и реакций не пересекаются X`∩Y= ∅; • T = R`∪S∪I – множество переходов, где: o R` ⊆ V×X`×V – принимающие переходы, o S ⊆ V×Y×V – посылающие переходы, o I ⊆ V×V – пустые переходы. Принимающие переходы можно разделить на два вида: R=R`∩V×X×V – принимающие переходы по непустым стимулам или x-переходы, и E=R`∩V×{e}×V – принимающие переходы по пустым стимулам или e-переходы. Состояния можно разделить на терминальные, в которых не определены никакие переходы, посылающие, в которых определены только посылающие и пустые переходы, принимающие, в которых определены только принимающие переходы, и смешанные, в которых определены как принимающие, так и посылающие или пустые переходы. Принимающие и смешанные переходы будем называть рецептивными. 12
Стимул x допустим в состоянии v, если имеется хотя бы один принимающий переход (v, x, v`). Автомат конечен, если конечны множества состояний V и переходов T. По умолчанию, мы будем рассматривать только конечные автоматы. Такое определение автомата не полностью описывает его выполнение, поскольку дополнительно нужно указать, является ли автомат императивным или факультативным, разрешены ли в нем e-переходы и какой их приоритет по отношению к посылающим и пустым переходам. Введем обозначения: • M=Mi∪Mf – класс всех асинхронных автоматов, • Mi=Mi0∪Mi1∪Mi2∪Mi3 – императивные автоматы, • Mf=Mf0∪Mf1∪Mf2∪Mf3 – факультативные автоматы, • Mi0 (Mf0) – императивные (факультативные) автоматы без e-переходов (E=∅), • Mi1 (Mf1) – императивные (факультативные) автоматы с e-переходами и приоритетом посылающих и пустых переходов над e-переходами, • Mi2 (Mf2) – императивные (факультативные) автоматы с e-переходами и приоритетом e-переходов над посылающими и пустыми переходами, • Mi3 (Mf3) – императивные (факультативные) автоматы с e-переходами и равноприоритетностью посылающих и пустых переходов и e-переходов. Будем считать, что с автоматом связаны две очереди: входная очередь, в которой располагается бесконечное входное слово в алфавите X`, и выходная очередь, в которую помещаются выдаваемые автоматом реакции, формируя выходное слово в алфавите Y. Срабатывание (однократное выполнение) автомата в состоянии v заключается в определении допустимых переходов, определенных в этом состоянии и, если такие есть, недетерминированном выборе одного из них и выполнении его. Если выбирается пустой переход (v,v`), автомат переходит в состояние v`, входная и выходная очереди не изменяются. Если выбирается принимающий переход (v,x,v`), то x – головной стимул входной очереди и он удаляется из нее, автомат переходит в состояние v`, выходная очередь не изменяется. Если выбирается посылающий переход (v,y,v`), автомат переходит в состояние v`, а в конец выходной очереди помещается реакция y; если v – смешанное состояние и головной стимул входной очереди пустой, то он удаляется из входной очереди, в противном случае входная очередь не изменяется. В срабатывание автомата входит также его действия в случае отсутствия допустимых переходов. Множество допустимых переходов, а также действия автомата при отсутствии допустимых переходов, зависят в общем случае от состояния v, головного стимула x входной очереди и класса автомата: • В терминальном состоянии v допустимых переходов нет. Автомат останавливается: состояние, входная и выходная очереди не изменяются. • В посылающем состоянии v допустимые переходы – это все посылающие (v,y,v`) и пустые (v,v`) переходы. 13
•
В принимающем состоянии v допустимые переходы – это все принимающие переходы (v,x,v`). Если таких переходов нет, то выполнение автомата зависит от того, пустой или непустой головной стимул: если x≠e непустой (недопустимый) стимул, то поведение автомата не определено, это квалифицируется как ошибка неспецифицированного ввода; если же x=e пустой стимул, то автомат остается в состоянии v, а пустой стимул удаляется из входной очереди, выходная очередь не изменяется. • В смешанном состоянии v: o Если x=e пустой стимул, то допустимые переходы: для автоматов Mi0,Mi1,Mf0,Mf1 – посылающие (v,y,v`) и пустые (v,v`) переходы; для автоматов Mf2,Mi2 - e-переходы (v,e,v`), а если их нет, то посылающие (v,y,v`) и пустые (v,v`) переходы; для автоматов Mf3,Mi3 – e-переходы (v,e,v`), если они есть, плюс посылающие (v,y,v`) и пустые (v,v`) переходы. o Если x≠e непустой допустимый стимул, то допустимые переходы: для императивных автоматов Mi - x-переходы (v,x,v`); для факультативных автоматов Mf – x-переходы (v,x,v`) плюс посылающие (v,y,v`) и пустые (v,v`) переходы. o Если x≠e непустой недопустимый стимул, то допустимые переходы: отсутствуют для императивных автоматов Mi – поведение автомата не определено, это квалифицируется как ошибка неспецифицированного ввода; для факультативных автоматов Mf – посылающие (v,y,v`) и пустые (v,v`) переходы. Заметим, что класс автомата влияет на его срабатывание только в смешанных состояниях. Выполнением автомата по бесконечному входному слову w будем называть последовательность однократных срабатываний, начинающуюся в начальном состоянии v0, когда во входной очереди находится слово w. Подпоследовательность посылающих переходов определяет выходное слово u, появляющееся в выходной очереди при данном выполнении. Выполнение допустимо, если оно бесконечное или заканчивается в терминальном состоянии, и недопустимо, если оно заканчивается по ошибке неспецифицированного ввода. Поскольку автомат, вообще говоря, недетерминированный, одному входному слову может соответствовать множество возможных выполнений автомата. Входное слово допустимо, если все его возможные выполнения допустимы. Соответственно, выполнение по допустимому входному слову будем называть вполне-допустимым. Заметим, что вполне-допустимое выполнение допустимо, но 14
обратное, вообще говоря, не верно. Словарная функция автомата W ставит в соответствие каждому допустимому входному слову w множество выходных слов u для всех возможных выполнений. Заметим, что входное слово не обязательно будет полностью выбрано из входной очереди при том или ином выполнении. Допустимость входных слов и словарную функцию можно определить для любого состояния автомата, если его рассматривать как начальное состояние. В дальнейшем мы по умолчанию будем иметь в виде допустимость входных слов и словарную функцию для заданного начального состояния автомата v0.
2.2. Финальная допустимость стимулов Для факультативного автомата, в отличии от императивного, допустимость или недопустимость стимула x в смешанном состоянии v еще ничего не говорит о допустимости или недопустимости в этом состоянии входного слова w, начинающегося со стимула x, в частности, учитывая, что пустые стимулы допустимы во всех нерецептивных состояниях слова xeω. Введем понятие финальной допустимости стимула в факультативном автомате: непустой стимул финально допустим в рецептивном состоянии v, если он допустим в любом принимающем состоянии v`, в которое можно попасть из состояния v по цепочке посылающих и пустых переходов (цепочка будет нулевой длины, если v принимающее состояние). Возможные сочетания допустимости и финальной допустимости стимулов приведены на Рис. 1. Очевидно, для факультативного автомата входное слово допустимо тогда и только тогда, когда при любом выполнении автомата в проходимых рецептивных состояниях головные стимулы финально допустимы. Для принимающих состояний понятия допустимости и финальной допустимости стимулов совпадают. Однако, для смешанных состояний и допустимые и недопустимые стимулы могут быть как финально допустимы, так и финально недопустимы. Допустимость и финальная допустимость стимулов в факультативном автомате X = {x1,x2,x3,x4} Начальное состояние v0, принимающее состояние vR, терминальные состояния v1, v2 и v3. В состоянии v0: x1 - допустим и финально допустим x2 - допустим, но финально недопустим x3 - недопустим, но финально допустим x4 - недопустим и финально недопустим Рис. 1 Обозначим через M`f⊂Mf, M`f1⊂Mf1, M`f2⊂Mf2, M`f3⊂Mf3 подклассы факультативных автоматов, в которых допустимость и финальная допустимость стимулов совпадают. 15
Теорема о финальной допустимости стимулов: Каждый базовый класс факультативных автоматов моделируется своим подклассом автоматов, в которых совпадают допустимость и финальная допустимость стимулов, и, следовательно, эквивалентен ему: W[M`f]=W[Mf], W[M`f1]=W[Mf1], W[M`f2]=W[Mf2], W[M`f3]=W[Mf3]. Доказательство: Определим следующую процедуру преобразования факультативного автомата (Рис. 2): Сведение финальной допустимости к обычной допустимости (случай, когда состояние v остается рецептивным)
X = {x1,x2,x3,x4} стимул x1 допустим и финально допустим в состоянии v стимул x2 допустим, но финально недопустим в состоянии v стимул x3 недопустим, но финально допустим в состоянии v стимул x4 недопустим и финально недопустим в состоянии v Рис. 2 •
Добавим дополнительные состояния вида (v,x), где v∈V – основное состояние, а x∈X – непустой стимул. • Для каждого основного смешанного состояния v удалим все определенные в нем принимающие переходы (v,x,v`) по допустимым, но финально недопустимым стимулам x. • Для каждого основного смешанного состояния v и недопустимого, но финально допустимого в нем стимула x, добавим принимающий переход, ведущий в дополнительное состояние (v,x,(v,x)). • Если в основном рецептивном состоянии v стимул x финально допустим, то для каждого принимающего перехода (v,x,v`) добавим пустой переход из соответствующего дополнительного состояния ((v,x),v`). • Для каждого посылающего (v,y,v`) и пустого (v,v`) перехода добавим, соответственно, посылающий ((v,x),y,(v`,x)) или пустой ((v,x),(v`,x)) переход из дополнительных состояний. Теперь в каждом смешанном основном состоянии допустимы те и только те стимулы, которые финально допустимы. Дополнительные состояния – посылающие. Из этого правила есть одно важное исключение: основное смешанное состояние v может стать нерецептивным (посылающим), если окажется, что все непустые стимулы недопустимы в нем, и в нем не определены 16
e-переходы. Нерецептивность состояния приводит к тому, что при выходе из него по посылающему или пустому переходу пустой головной стимул не удаляется из очереди. Иными словами, если в момент прихода в состояние v во входной очереди было слово ew, то после посылающего или пустого перехода, определенного в v, во входной очереди раньше оставалось слово w, а теперь, когда состояние стало нерецептивным, – то же самое слово ew. Здесь нужно рассмотреть два случая. Случай 1. Если автомат не имеет e-переходов (класс Mf0), то финальная недопустимость стимула x в состоянии v означает существование выполнения, начинающегося в v, содержащего только посылающие и пустые переходы и заканчивающегося в принимающем состоянии v`, в которой стимул x недопустим. Поскольку в v` не определены e-переходы, сначала будут удалены из очереди все пустые стимулы, а потом выбран непустой стимул и, если это x, то фиксируется ошибка неспецифицированного ввода. Следовательно из финальной недопустимости стимула x в смешанном состоянии v следует финальная недопустимость в нем любого слова enx. Тем самым, если в состоянии v недопустимы все непустые стимулы, то в этом состоянии допустимо единственное бесконечное слово eω (которое всегда допустимо). Поскольку для ew=eω, очевидно, w=eω, имеем ew=w и, следовательно, словарная функция не меняется. Случай 2. Если автомат может иметь e-переходы (классы Mf1, Mf2, Mf3), то, вообще говоря, из финальной недопустимости стимула x в состоянии v не следует финальная недопустимость в нем слова ex, то есть, финальная недопустимость стимула x в конце v` какого-нибудь e-перехода (v,e,v`). Простое удаление принимающих переходов, определенных в v, может изменить словарную функцию. Пример на Рис. 3.
переходов эквивалентно (по изменению состояния и содержимого очередей) движению по одному старому переходу. Поэтому и в этом случае словарная функция не меняется. См. Рис. 4. Сведение финальной допустимости к обычной допустимости (особый случай)
x≠x` Рис. 4 Теорема о финальной допустимости стимулов доказана. В дальнейшем мы вместо базовых классов Mf, Mf1, Mf2, Mf3 будем рассматривать эквивалентные им подклассы M`f, M`f1, M`f2, M`f3, которые также будем называть базовыми классами факультативных автоматов там, где это не приведет к недоразумениям.
x≠x`
Рис. 3 Поэтому для таких автоматов, кроме удаления принимающих переходов (v,x,v1) из состояния v, мы дополнительно преобразуем хотя бы один пустой (v,v2) или посылающий (v,y,v3) переход из v, в два смежных перехода, первый из которых e-переход (v,e,v2`), ведущий в дополнительное состояние v2`, а второй пустой (v2`,v`) переход, или, соответственно, e-переход (v,e,v3`) и посылающий (v3`,y,v`) переход. Состояние v остается рецептивным, а движение по паре новых смежных 17
18
2.3. Автоматы без смешанных состояний Обозначим через A класс автоматов без смешанных состояний с e-переходами. Отсутствие смешанных состояний и возможное наличие e-переходов делает автомат этого класса одновременно элементом любого из базовых классов с разрешенными e-переходами, которые отличаются друг от друга поведением только в смешанных состояниях, то есть, A = Mi3∩Mi2∩Mi1∩M`f3∩M`f2∩M`f1. Тем самым, класс A моделируется каждым из базовых классов: W[A]⊆W[Mi3], W[A]⊆W[Mi2], W[A]⊆W[Mi1], W[A]⊆W[M`f3], W[A]⊆W[M`f2], W[A]⊆W[M`f1].
1. Смешанное состояние без e-переходов. 1.1. Императивный автомат (Рис. 5). Mi0=Mi3=Mi2=Mi1
(1)
Теорема об автомате без смешанных состояний: Класс M всех асинхронных автоматов моделируется своим подклассом A автоматов без смешанных состояний и, следовательно, эквивалентен ему. теоремы следует эквивалентность Из этой W[A]=W[Mi3]=W[Mi2]=W[Mi1]=W[M`f3]=W[M`f2]=W[M`f1] и вложенности W[Mi0]⊆W[A] и W[Mf0]⊆W[A]. Доказательство: Для доказательства достаточно рассмотреть возможные срабатывания автоматов разных классов в смешанных состояниях. Можно выделить 11 случаев, изображенных на Таб. 1. Тип смешанного состояния
(1)
(2)
Срабатывание автомата в смешанном состоянии (1.1)Mi0=Mi3=Mi2=Mi1
(1.2)M`f0=M`f3=M`f2=M`f1
x:(v,x,vx)
x:(v,x,vx) x:(v,y,vy) e:(v,y,vy) (2.2)Mi2=M`f2 (2.3)Mi1=M`f1
e:(v,e,ve) e:(v,y,vy)
e:(v,e,ve)
x:(v,x,vx)
x:(v,x,vx)
e:(v,y,vy)
e:(v,e,(v,e))+((v,e),y,vy)
Рис. 5 Для каждого состояния v типа 1 добавляется дополнительное состояние (v,e). Посылающий (v,y,v`y) или пустой (v,v`y) переход из v заменяется на e-переход, ведущую в дополнительное состояние (e,v,(v,e)) и, соответственно, посылающий ((v,e),y,vy) или пустой ((v,e),vy) переход из этого дополнительного состояния. 1.2. Факультативный автомат (Рис. 6). M`f0=M`f3=M`f2=M`f1
(1)
e:(v,y,vy) (2.1)Mi3=M`f3
A
A
x:(v,x,vx) x:(v,y,vy)
x:(v,x,(v,x))+((v,x),vx) x:(v,x,(v,x))+((v,x),y,(vy,x))
e:(v,y,vy)
e:(v,e,(v,e))+((v,e),y,vy)
e:(v,y,vy) Рис. 6
(3.1.1)Mi3 (3.1.2)Mi2 (3.1.3)Mi1 (3.2.1)M`f3 (3.2.2)M`f2 (3.2.3)M`f1 (3)
x:(v,x,vx)
x:(v,x,vx)
e:(v,e,ve) e:(v,y,vy)
e:(v,e,ve)
x:(v,x,vx)
e:(v,y,vy)
x:(v,x,vx) x:(v,y,vy)
x:(v,x,vx) x:(v,y,vy)
e:(v,e,ve) e:(v,y,vy)
e:(v,e,ve)
Аналогично случаю 1.1, для каждого состояния v типа 1 добавляется дополнительное состояние (v,e); посылающий (v,y,v`y) или пустой (v,v`y) переход из v заменяется на e-переход в дополнительное состояние (e,v,(v,e)) и, соответственно, посылающий ((v,e),y,vy) или пустой ((v,e),vy) переход из этого дополнительного состояния. Затем в моделирующий автомат добавляются дополнительные состояния вида (v,x) для состояний v∈V и непустых стимулов x∈X. Для каждого основного смешанного состояния v∈V рассматриваемого типа и допустимого в нем непустого стимула x добавляется принимающий переход
x:(v,x,vx) x:(v,y,vy) e:(v,y,vy)
Таб. 1 19
20
(v,x,(v,x)). В каждом дополнительном состоянии (v,x) определяются посылающие ((v,x),y,(v`,x)) и пустые ((v,x),(v`,x)) переходы тогда и только тогда, когда в моделируемом автомате есть переходы, соответственно, (v,y,v`) и (v,v`). В каждом дополнительном состоянии (v,x) определяется пустой переход ((v,x),v`) тогда и только тогда, когда в моделируемом автомате есть переход (v,x,v`). 2. Смешанное состояние, в котором все принимающие переходы – eпереходы. 2.1. Равный приоритет e-переходов и посылающих и пустых переходов (Рис. 7). Mi3=M`f3 A
Приоритет e-переходов приводит к тому, что в состоянии типа 2 вообще никогда не будут выполняться посылающие и пустые переходы, поэтому их можно удалить. 2.3. Приоритет посылающих и пустых переходов (Рис. 9). Mi1=M`f1 A
(2) e:(v,y,vy)
e:(v,e,(v,e))+((v,e),y,vy)
(2) e:(v,e,ve) e:(v,y,vy)
e:(v,e,ve) e:(v,e,(v,e))+((v,e),y,vy) Рис. 9
Рис. 7 Аналогично случаю 1.1, для каждого состояния v типа 2 добавляется дополнительное состояние (v,e); посылающий (v,y,v`y) или пустой (v,v`y) переход из v заменяется на e-переход в дополнительное состояние (e,v,(v,e)) и, соответственно, посылающий ((v,e),y,vy) или пустой ((v,e),vy) переход из этого дополнительного состояния. 2.2. Приоритет e-переходов (Рис. 8). Mi2=M`f2 A (2)
e:(v,e,ve)
Приоритет посылающих и пустых переходов приводит к тому, что в состоянии типа 2 вообще никогда не будут выполняться e-переходы. Однако, если такие переходы просто удалить, то состояние перестанет быть рецептивным. Поэтому, как и в случае 1.1, для каждого состояния v типа 2 добавляется дополнительное состояние (v,e); посылающий (v,y,v`y) или пустой (v,v`y) переход из v заменяется на e-переход в дополнительное состояние (e,v,(v,e)) и, соответственно, посылающий ((v,e),y,vy) или пустой ((v,e),vy) переход из этого дополнительного состояния. 3. Смешанное состояние общего вида. 3.1. Императивный автомат. 3.1.1. Равный приоритет e-переходов и посылающих, и пустых переходов (Рис. 10). Mi3 A
e:(v,e,ve)
(3)
x:(v,x,vx)
x:(v,x,vx)
e:(v,e,ve) e:(v,e,(v,e))+ ((v,e)y,vy)
e:(v,e,ve) e:(v,y,vy)
Рис. 8
Рис. 10 21
22
Аналогично случаю 2.1, для каждого состояния v типа 3 добавляется дополнительное состояние (v,e); посылающий (v,y,v`y) или пустой (v,v`y) переход из v заменяется на e-переход в дополнительное состояние (e,v,(v,e)) и, соответственно, посылающий ((v,e),y,vy) или пустой ((v,e),vy) переход из этого дополнительного состояния. 3.1.2. Приоритет e-переходов (Рис. 11). Mi2 A (3) x:(v,x,vx)
x:(v,x,vx)
e:(v,e,ve)
e:(v,e,ve)
e:(v,e,ve) e:(v,y,vy)
Аналогично случаю 2.2, приоритет e-переходов приводит к тому, что в состоянии типа 3 вообще никогда не будут выполняться посылающие и пустые переходы, поэтому их можно удалить. 3.1.3. Приоритет посылающих и пустых переходов (Рис. 12). Mi1 A
x:(v,x,vx)
x:(v,x,vx) e:(v,e,(v,e))+((v,e),y,vy)
e:(v,y,vy)
e:(v,e,ve) e:(v,e,(v,e))+ ((v,e),y,vy) Рис. 13
Рис. 11
(3)
3.2. Факультативный автомат. 3.2.1. Равный приоритет e-переходов и посылающих, и пустых переходов (Рис. 13). M`f3 A x:(v,x,(v,x))+ ((v,x),vx) x:(v,x,vx) (3) x:(v,x,(v,x))+ x:(v,y,vy) ((v,x),y,(vy,x))
Аналогично случаю 1.2, для каждого состояния v типа 3 добавляется дополнительное состояние (v,e); посылающий (v,y,v`y) или пустой (v,v`y) переход из v заменяется на e-переход в дополнительное состояние (e,v,(v,e)) и, соответственно, посылающий ((v,e),y,vy) или пустой ((v,e),vy) переход из этого дополнительного состояния. Затем в моделирующий автомат добавляются дополнительные состояния вида (v,x) для состояний v∈V и непустых стимулов x∈X. Для каждого основного состояния v типа 3 и допустимого в нем непустого стимула x добавляется принимающий переход (v,x,(v,x)). В каждом дополнительном состоянии (v,x) определяются посылающие ((v,x),y,(v`,x)) и пустые ((v,x),(v`,x)) переходы тогда и только тогда, когда в моделируемом автомате есть переходы, соответственно, (v,y,v`) и (v,v`), кроме того, определяется пустой переход ((v,x),v`) тогда и только тогда, когда в моделируемом автомате есть переход (v,x,v`). 3.2.2. Приоритет e-переходов (Рис. 14). M`f2 A (3) x:(v,x,(v,x))+ ((v,x),vx) x:(v,x,(v,x))+ ((v,x),y,(vy,x))
x:(v,x,vx) x:(v,y,vy)
Рис. 12 Приоритет посылающих и пустых переходов приводит к тому, что в состоянии типа 3 вообще никогда не будут выполняться e-переходы. Удаляя e-переходы, получаем случай 1.1 и применяем соответствующее преобразование.
23
e:(v,e,ve)
e:(v,e,ve) Рис. 14
Приоритет e-переходов приводит к тому, что в состоянии типа 3 при пустом головном стимуле не будут выполняться посылающие и пустые переходы; эти переходы могут выполняться только при непустом и допустимом головном стимуле. Поэтому делаем аналогично случаю 3.2.1, но только посылающий или 24
пустой переход из основного состояния типа 3 не заменяется на e-переход в дополнительное состояние, и, соответственно, посылающий или пустой переход из этого дополнительного состояния, а просто удаляется. В моделирующий автомат добавляются дополнительные состояния вида (v,x) для состояний v∈V и непустых стимулов x∈X. Для каждого основного состояния v типа 3 и допустимого в нем непустого стимула x добавляется принимающий переход (v,x,(v,x)). В каждом дополнительном состоянии (v,x) определяются посылающие ((v,x),y,(v`,x)) и пустые ((v,x),(v`,x)) переходы тогда и только тогда, когда в моделируемом автомате есть переходы, соответственно, (v,y,v`) и (v,v`), кроме того, определяется пустой переход ((v,x),v`) тогда и только тогда, когда в моделируемом автомате есть переход (v,x,v`). Посылающие и пустые переходы из основных состояний типа 3 удаляются. 3.2.3. Приоритет посылающих и пустых переходов (рис. 15). M`f1 A x:(v,x,(v,x))+ ((v,x),vx) x:(v,x,(v,x))+ ((v,x),y,(vy,x))
x:(v,x,vx) x:(v,y,vy) e:(v,y,vy)
e:(v,e,(v,e))+ ((v,e),y,vy)
2.4. Три класса автоматов и словарных функций В этом разделе мы рассмотрим три класса автоматов: 1) класс Mi0=АОР императивных автоматов без e-переходов (автоматы с отложенными реакциями), 2) класс Mf0=IOSM факультативных автоматов без e-переходов (автоматы вводавывода), 3) пересечение этих классов - класс A0 автоматов без смешанных состояний и e-переходов. Мы покажем, что класс АОР моделирует класс A и, тем самым, эквивалентен классу всех асинхронных автоматов W[АОР]=W[M], класс IOSM этим свойством не обладает, то есть, W[IOSM]⊂W[M], а класс A0 не моделирует класс IOSM, W[A0]⊂W[IOSM], и, тем более, класс АОР, то есть, является самым узким классом в смысле словарной функции.
2.4.1. Автоматы с отложенными реакциями (АОР) – императивные автоматы без e-переходов Сначала мы рассмотрим специальный подкласс A1⊂A автоматов без смешанных состояний и без таких принимающих состояний, в которых определены только eпереходы (такие состояния будем называть e-состояниями), то есть, в каждом принимающем состоянии определен хотя бы один принимающий переход по непустому допустимому стимулу. Теорема о e-состояниях: Класс A моделируется своим подклассом A1 и, тем самым, они эквивалентны W[A]=W[A1]. Доказательство: Для доказательства достаточно рассмотреть моделирование поведения автомата класса A в e-состоянии (Рис.16), поскольку в остальных состояниях автоматы классов A и A1 ведут себя одинаково. A A1
Рис. 15 Приоритет посылающих и пустых переходов приводит к тому, что в состоянии типа 3 при пустом головном стимуле не будут выполняться e-переходы; тем более они не будут выполняться при непустом головном стимуле. Поэтому делаем аналогично случаю 3.2.1, но только e-переходы из основных состояний типа 3 удаляем. В моделирующий автомат добавляются дополнительные состояний вида (v,x) для состояний v∈V и непустых стимулов x∈X. Для каждого основного состояния v типа 3 и допустимого в нем непустого стимула x добавляется принимающий переход (v,x,(v,x)). В каждом дополнительном состоянии (v,x) определяются посылающие ((v,x),y,(v`,x)) и пустые ((v,x),(v`,x)) переходы тогда и только тогда, когда в моделируемом автомате есть переходы, соответственно, (v,y,v`) и (v,v`), кроме того, определяется пустой переход ((v,x),v`) тогда и только тогда, когда в моделируемом автомате есть переход (v,x,v`). Удаляются e-переходы из основных состояний типа 3. Теорема об автомате без смешанных состояний доказана.
25
e:(v,v1)+(v1,e,ve) e:(v,v2)+(v2,e,ve)
e:(v,e,ve)
Рис. 16 Для каждого e-состояния v добавляем два дополнительных состояния v1 и v2, и в состоянии v определяем два пустых перехода в v1 и v2. В состоянии v1 определяем принимающий переход по любому непустому стимулу x, а в состоянии v2 множество принимающих переходов по всем остальным непустым стимулам. 26
Очевидно, что в состоянии v все непустые стимулы финально недопустимы. После этого каждый e-переход (v,e,ve) заменяем на два e-перехода из состояний v1 и v2, соответственно, (v1,e,ve) и (v2,e,ve). В этом доказательстве мы неявно использовали тот факт, что алфавит стимулов состоит хотя бы из двух непустых стимулов, то есть, x1∈X и X\{x1}≠∅. Если это не так, то мы всегда можем добавить в алфавит стимулов еще два непустых стимула, один из которых будем использовать только для принимающих переходов из v1, а другой вместе с остальными стимулами из X - для принимающих переходов из v2. Понятно, что эти дополнительные стимулы не будут входить в допустимые входные слова, поэтому словарная функция не изменится. Теорема о e-состояниях доказана. Теорема об автомате с отложенными реакциями: Класс M всех асинхронных автоматов моделируется своим подклассом автоматов с отложенными реакциями АОР=Mi0 (императивные автоматы без e-переходов) и, следовательно, эквивалентен ему. Доказательство: Класс Mi0, как подкласс класса M всех асинхронных автоматов, им моделируется. Поскольку класс M всех асинхронных автоматов эквивалентен классу A, а класс A эквивалентен своему подклассу A1, нам достаточно показать, что класс A1 моделируется классом Mi0. Для моделирования автомата класса A1 автоматом класса Mi0 достаточно рассмотреть поведение автомата в принимающих состояниях, в которых определены прием как пустого стимула, так и непустых допустимых стимулов, поскольку в автоматах класса A1 нет смешанных состояний и нет e-состояний, а в принимающих состояниях без e-переходов также как в терминальных и посылающих состояниях все автоматы ведут себя одинаково. Моделирование поведения в таком состоянии тривиально: e-переходы заменяем пустыми переходами (Рис. 17). A1 Mi0 x:(v,x,vx) x:(v,x,vx) e:(v,e,ve) e:(v,ve) A1
Mi0 x:(v,x,vx) e:(v,e,ve)
x:(v,x,vx) e:(v,ve) Рис. 17
2.4.2. Автоматы ввода-вывода (IOSM) – факультативные автоматы без e-переходов Теорема об автомате ввода-вывода (IOSM): Класс M всех асинхронных автоматов не моделируется своим подклассом автоматов ввода-вывода IOSM=Mf0 (факультативные автоматы без e-переходов). Доказательство: Поскольку класс Mf0 моделируется своим подклассом M`f0, а класс M всех асинхронных автоматов моделируется подклассом A, нам достаточно показать, что существует автомат a∉A, который не моделируется классом M`f0, то есть, W[a]∉W[M`f0]. Напомним, что автомат класса M`f0 - это факультативный автомат без eпереходов, в котором совпадают допустимость и финальная допустимость стимулов. Такие автоматы обладают следующими двумя свойствами, которыми некоторые асинхронные автоматы класса A не обладают. Свойство 1: Если словарная функция автомата класса M`f0 определена на входном слове uexw, где u – конечное слово, e – пустой стимул, x – некоторый стимул (быть может, пустой), w – бесконечное слово, то она должна быть определена также на входном слове uxeω. Действительно, поскольку входные слова uexw и uxeω имеют общий начальный отрезок u, и слово uexw допустимо, ошибка неспецифицированного ввода может проявиться для слова uxeω только после выборки слова u из входной очереди при приеме стимула x в принимающем состоянии v (последующие стимулы пустые и, тем самым, всегда допустимые). Значит стимул x недопустим в состоянии v. Но тогда для слова uexw автомат после выборки слова u также может оказаться в принимающем состоянии v и примет пустой стимул e. Поскольку v – принимающее состояние и e-переходов нет, выборка пустого стимула не меняет состояние и автомат в том же состоянии v выберет недопустимый стимул x, то есть, будет зафиксирована ошибка неспецифицированного ввода и окажется, что слово uexw недопустимо. Мы пришли к противоречию и, значит, входное слово uxeω должно быть допустимо. Заметим, что требование наличия после непустого стимула x в слове uxeω только пустых стимулов существенно, поскольку может оказаться, что для любого допустимого входного слова вида uexw любое входное слово вида uxw`, допустимо только тогда, когда w`=eω. Пример приведен на Рис. 18. При X = {x,x`} единственное допустимое слово вида xw` – это слово xeω, а для всех допустимых входных слов вида uexw, u - должно быть пусто.
Теорема об автомате с отложенными реакциями доказана. Итак, мы показали, что W[Mi0]=W[A]=W[A1] и, тем самым, доказана эквивалентность всех базовых классов, кроме Mf0: W[M]=W[A]=W[A1]=W[Mi0]=W[Mi3]=W[Mi2]=W[Mi1]=W[M`f3]=W[M`f2]=W[M`f1]. 27
28
также для продолжения выполнения в случае слова uw, хотя обратное, вообще говоря, неверно. Тем самым оказывается, что любое выполнение для слова uew дает последовательность переходов (а значит, и реакций), которая возможна также для слова uw, то есть, W(uew)⊆W(uw). Отсюда непосредственно следует свойство 2. Теперь нам достаточно привести пример автомата класса A, словарная функция которого не обладала бы этим вторым свойством (Рис. 20). Здесь для X={x,x`} слово xx`eω допустимо, а слово xex`eω недопустимо.
Рис. 18 Теперь нам достаточно привести пример автомата класса A, словарная функция которого не обладала бы этим первым свойством (Рис. 19). Словарная функция автомата определена на и только на словах вида ew, начинающихся с пустого стимула, и отображает каждое такое входное слово в пустое выходное слово. Для любого непустого стимула x эта функция определена на любом слове вида exw, но не определена на слове xeω.
Рис. 20 Теорема об автомате ввода-вывода (IOSM) доказана. Рассмотренные нами два свойства словарной функции автоматов ввода-вывода (IOSM) являются необходимыми. Можно сформулировать следующую нерешенную задачу: найти свойства словарной функции, необходимые и достаточные для того, чтобы она была словарной функцией автомата вводавывода (IOSM).
2.4.3. Автоматы без смешанных состояний и e-переходов (A0)
Рис. 19 Свойство 2: Если словарная функция W автомата класса M`f0 определена на слове w, то она определена также на любом слове w`, полученном из w добавлением в произвольные места произвольного числа пустых стимулов, и W(w`)⊆W(w). Действительно, если по конечному слову u автомат может попасть в принимающее состояние v, то, поскольку в принимающем состоянии не определены e-переходы, автомат в состоянии v не сможет различить остатки входных слов, находящиеся во входной очереди в этот момент времени, отличающиеся только количеством пустых стимулов в начале. Все эти пустые стимулы будут "глотаться" принимающим состоянием. Поэтому любое возможное продолжение выполнения автомата для допустимого слова uw дает ту же последовательность переходов (а значит, и реакций), что и для слова uew, и наоборот. Если по конечному слову u автомат может попасть в смешанное состояние v, то, поскольку в смешанном состоянии автомат может сработать по посылающему или пустому переходу независимо от головного стимула, пустой головной стимул в этом случае выбирается из очереди, а непустой остается, любое продолжение выполнения автомата для бесконечного слова uew дает такую последовательность переходов (а значит, и реакций), которая возможна 29
Специальный интерес представляет класс A0 автоматов без смешанных состояний и e-переходов, вложенный, очевидно, во все остальные рассматривавшиеся выше классы автоматов. Теорема об автомате без смешанных состояний и e-переходов: Класс M`f0 не моделируется классом A0. Доказательство: Автоматы класса A0 обладают тремя особыми свойствами, которыми не обладают некоторые автоматы надкласса M`f0. Свойство 1: Если словарная функция W автомата класса A0 определена на слове w, то она определена также на любом слове w`, полученном из w вставкой или удалением конечного числа пустых стимулов, и принимает на нем то же значение W(w`)=W(w). Это непосредственно следует из того, что каждое рецептивное состояние является принимающим состоянием без e-переходов, поэтому такое состояние "глотает" все пустые стимулы. Примером автомата класса M`f0, не моделируемого классом A0 из-за нарушения свойства 1, может служить автомат на Рис. 18. Для X = {x,x`} входное слово exx`eω допустимо, а входное слово xx`eω недопустимо. Заметим, что здесь мы использовали только часть свойства 1 класса A0 - выделенную курсивом. Если использовать это свойство полностью, то можно 30
привести более простой пример автомата класса M`f0, не моделируемого классом A0 (Рис. 21). Для этого автомата допустимы как входное слово xw, так и входное слово exw, где w - произвольное бесконечное слово. Однако, для слова exw определено одно выходное слово - (y), а для слова xw - два выходных слова: пустое () и (y).
Рис. 21 Для того, чтобы определить второе свойство автоматов класса A0, введем следующие обозначения: • c≤c`, где c и c` - два слова (конечных или бесконечных) в одном алфавите, означает, что – или c конечно и является начальным отрезком c`, или они совпадают. • C≤C`, где C и C` - два множества слов (конечных или бесконечных) в одном алфавите, означает, что ∀c∈C ∃c`∈C` c≤c` и ∀c`∈C` ∃c∈C c≤c`. Будем писать C
так и входное слово eω. При этом W(eω)={(y)}, а W(xw)={(),(y)}, и, очевидно, W(xw)<W(eω). Свойство 3: Если словарная функция W автомата класса A0 определена на слове ueω, где u - конечное слово, и существует недопустимое слово uw, где w бесконечное слово, содержащее непустые стимулы, то в множестве выходных слов W(ueω) имеется хотя бы одно конечное слово. Действительно, если существует недопустимое слово uw, то, значит, после выборки из входной очереди слова u, автомат может за конечное число посылающих и пустых переходов перейти в принимающее состояние v, в котором первый непустой стимул слова w недопустим. В этот момент в выходной очереди окажется конечное выходное слово c. Очевидно, что для входного слова ueω дальше будут выбираться только пустые стимулы и автомат класса A0 будет оставаться в состоянии v, не изменяя выходную очередь. Это значит, что при таком выполнении для входного слова ueω будет получено конечное выходное слово c, то есть, c∈W(ueω). Заметим, что если для некоторого допустимого слова uw имеет место W(ueω)<W(uw), то из определения отношения "<" следует, что W(ueω) содержит хотя бы одно конечное слово. Поэтому необходимым и достаточным условием отсутствия в W(ueω) конечных слов является отсутствие недопустимых слов вида uw и для всех допустимых слов вида uw равенство (с учетом свойства 2) W(ueω)=W(uw). Пример автомата класса M`f0, не моделируемого классом A0 из-за нарушения свойства 3, приведен на Рис. 22. В этом автомате для X={x,x`} W(eω)={yω} и, в тоже время, существует недопустимое слово xx`w, где w - любое бесконечное слово.
Рис. 22 Теорема об автомате без смешанных состояний и e-переходов доказана. Рассмотренные нами три свойства словарной функции автоматов без смешанных состояний и e-переходов являются необходимыми. Можно сформулировать следующую нерешенную задачу: найти свойства словарной функции, необходимые и достаточные для того, чтобы она была словарной функцией автомата класса A0.
32
2.5. Общая картина взаимосвязей классов асинхронных автоматов с точки зрения словарной функции Если рассматривать автоматы, в которых e-переходы определены только в принимающих состояниях (не определены в смешанных состояниях), то, очевидно, мы получим следующие классы автоматов Bi=Mi1∩Mi2=Mi1∩Mi3=Mi2∩Mi3, Bf=Mf1∩Mf2=Mf1∩Mf3=Mf2∩Mf3, B`f=M`f1∩M`f2=M`f1∩M`f3=M`f2∩M`f3. Теперь определим разбиение класса всех асинхронных автоматов на непересекающиеся области (Таб. 2). состояния e-переСмешан- eприоритет в финальная с одними имп. ходы в смеОбласть ные пересмешанных допустиопределение e-пере- фак. шанных состояниях мость состояния ходы ходами состояниях a0=A0 нет нет нет нет совпадает a1=A1\A0 нет есть нет нет совпадает a=A\A1 нет есть есть нет совпадает mi0=Mi0\A0 есть нет нет имп. нет совпадает есть есть имп. нет совпадает bi=Bi\(A∪Mi0) mi1=Mi1\Bi есть есть имп. есть пос. и пуст. совпадает mi2=Mi2\Bi есть есть имп. есть e-переходы совпадает mi3=Mi3\Bi есть есть имп. есть равный совпадает m`f0=M`f0\A0 есть нет нет фак. нет совпадает mf0=Mf0\M`f0 есть нет нет фак. нет нет фак. нет совпадает b`f=B`f\(A∪M`f0) есть есть есть есть фак. нет нет bf=Bf\(B`f∪Mf0) m`f1=M`f1\B`f есть есть фак. есть пос. и пуст. совпадает m`f2=M`f2\B`f есть есть фак. есть e-переходы совпадает m`f3=M`f3\B`f есть есть фак. есть равный совпадает mf1=Mf1\Bf есть есть фак. есть пос. и пуст. нет mf2=Mf2\Bf есть есть фак. есть e-переходы нет mf3=Mf3\Bf есть есть фак. есть равный нет
Теперь можно представить классы автоматов как объединения областей (Таб. 3). клас базовое области разбиения с выражение a0 a1 a mi0 bi mi1 mi2 mi3m`f0mf0 b`f bf m`f1m`f2m`f3 mf1 mf2 mf3 A0 =a0 A1 =A0∪a1 A =A1∪a Mi0 =A0∪mi0 Bi =A∪Mi0∪bi Mi1 =Bi∪mi1 Mi2 =Bi∪mi2 Mi3 =Bi∪mi3 M`f0 =A0∪m`f0 Mf0 =M`f0∪mf0 B`f =A∪M`f0∪b`f Bf =B`f∪Mf0∪bf M`f1 =B`f∪m`f1 M`f2 =B`f∪m`f2 M`f3 =B`f∪m`f3 Mf1 =Bf∪mf1 Mf2 =Bf∪mf2 Mf3 =Bf∪mf3 Таб. 3 В разделах 2.2-2.4 было показано следующее: •
Каждый базовый класс факультативных автоматов Mfn (n=0,1,2,3) моделируется своим подклассом M`fn, в котором допустимость и финальная допустимость стимулов совпадают, и, следовательно эквивалентен ему.
•
Класс A моделирует базовые классы Min и M`fn, где n=0,1,2,3. Учитывая вложенность классов, получаем эквивалентность класса A и классов Min и M`fn, где n=1,2,3.
•
Класс A моделируется своим подклассом A1 и, тем самым, ему эквивалентен.
•
Эквивалентность класса A1 и класса Mi0.
•
Немоделируемость класса A классом M`f0.
Таб. 2
33
34
•
Немоделируемость класса M`f0 классом A0.
Тем самым, учитывая вложенность классов, имеем три группы классов M0, M1, M таких, что W(M0)⊂W(M1)⊂W(M0), и все классы одной группы эквивалентны: •
W(M0) = W(A0)
•
W(M1) = W(M`f0) = W(Mf0)
•
W(M2) = W(A1) = W(A) = W(Mi0) = W(Bi) = W(Mi1) = W(Mi2) = W(Mi3) = W(B`f) = W(M`f1) = W(M`f2) = W(M`f3) = W(Bf) = W(Mf1) = W(Mf2) = W(Mf3)
На Рис. 23 изображены эти три группы классов; стрелки показывают частичный порядок по отношению вложенности.
Рис. 23
35
3. Сериализация 3.1. Сериализации и маршруты. Зависимость между тестовыми воздействиями и реакциями тестируемого автомата, которую можно определить за конечное число тестовых экспериментов, может оказаться недостаточной для проверки соответствия реализации модели даже при допущении ряда довольно сильных предположений (гипотез) о тестируемом автомате. Здесь на помощь может придти возможность (когда она существует) определить в процессе тестирования не только последовательность реакций, выдаваемых автоматом в ответ на данную последовательность стимулов, но и относительное расположение во времени стимулов и реакций. Смешанную последовательность воспринимаемых автоматом стимулов и выдаваемых им реакций мы будем называть сериализацией. Начиная с этого раздела, мы будем исследовать сериализации, реализуемые автоматом, и их связь со словарной функцией. Разные автоматы, реализующие одну и ту же словарную функцию, отличаются как раз сериализациями. Преобразования автоматов из разделов 2.2-2.4 сохраняют не только словарную функцию, но и сериализации выполнений для допустимых входных слов. Заметим, что подпоследовательность реакций сериализации совпадает с выходным словом. В то же время, поскольку автомат с некоторого момента может прекратить выборку стимулов из входной очереди, подпоследовательность стимулов сериализации может не совпадать со входным словом, а являться его начальным отрезком. Мы покажем, что это явление носит принципиальный характер, то есть, для некоторых словарных функций любой реализующий их конечный автомат выбирает из входной очереди лишь конечное число стимулов для некоторых допустимых входных слов. Выполнению автомата соответствует также маршрут – последовательность смежных переходов и, тем самым, раскраска маршрута как последовательность стимулов и реакций непустых переходов. Мы покажем связь маршрутов и их раскрасок с сериализациями. Сериализацией будем называть слово (конечное или бесконечное) в объединенном алфавите стимулов (включая пустой) и реакций Z=X`∪Y. Через xz и yz обозначим, соответственно, x-подслово и y-подслово z, то есть, подпоследовательность z, состоящую из, соответственно стимулов и реакций. Мы будем также говорить, что z является сериализацией пары (zx,zy). Для множества сериализаций S обозначим xS={xz|z∈S} и yS={yz|z∈S}. На множестве всех сериализаций (как и вообще на множестве слов в любом алфавите) имеется естественный частичный порядок: z≤z` означает, что сериализация z является начальным отрезком (тогда она конечна) или совпадает с сериализацией z`. Сериализация z, соответствующая выполнению автомата любого класса, строится в процессе выполнения следующим образом. Реакция y помещается в z одновременно с выдачей этой реакции в выходную очередь, то есть, когда автомат совершает посылающий переход (v,y,v`). Стимул x`∈X` помещается в z 36
тогда, когда автомат впервые его «распознает», то есть, «читает» в рецептивном состоянии v для того, чтобы определить свое дальнейшее поведение в зависимости от этого стимула. Если дальнейшее поведение заключается в совершении принимающего перехода (v,x`,v`), то стимул удаляется из очереди и мы присоединим его к z: z^(x`). Однако, дальнейшее поведение не обязательно включает принимающий переход (v,x`,v`) по стимулу и/или удаление стимула из входной очереди. Для пустого стимула x`=e автоматы некоторых классов в смешанном состоянии v могут совершить посылающий (v,y,v`) или пустой (v,v`) переход (если в этом состоянии нет e-переходов или они имеют равный или меньший приоритет, чем посылающие и пустые переходы) и, тем самым, в z помещается два символа z^(ey) или один символ z^(e). Для принимающего состояния v без e-переходов при срабатывании автомата по пустому головному стимулу никакого перехода не совершается, состояние не меняется, а пустой стимул удаляется из входной очереди: z^(e). Факультативный автомат, кроме этого, при непустом головном стимуле x`≠e в смешанном состоянии v может, не удаляя стимула из входной очереди, совершить посылающий (v,y,v`) или пустой (v,v`) переход. Хотя стимул x` не удаляется из очереди, он, тем не менее, читается и определяет набор допустимых переходов; поэтому z изменяется соответственно: z^(x,y) или z^(x). Дальнейшее поведение автомата определено «прочитанным» стимулом x` до тех пор, пока этот стимул не будет удален из очереди при совершении принимающего перехода по x`; таким образом, при всех дальнейших срабатываниях автомата, включая этот принимающий переход, автомат не читает головной стимул и никаких стимулов в z не помещается. Если до этого принимающего перехода совершаются посылающие переходы, то только соответствующие реакции помещаются в z. Такое определение сериализации выполнения может показаться странным, особенно для факультативных автоматов. Например, для непустого головного стимула x в смешанном состоянии v последовательность переходов (v,y,v1),(v1,x,v2) помещает в сериализацию не (y,x), как можно было бы ожидать, а (x,y). На самом деле, это вполне объяснимо, поскольку стимул x прочитывается первый раз в состоянии v, а не в последующем состоянии v1, и поскольку прочитанный, но не удаленный из очереди, стимул x уже не может быть изменен и, тем самым, повторное чтение его в состоянии v1 излишне. Фактически, такой стимул как бы запоминается автоматом, что и происходит явно в тех преобразованиях, которые мы использовали в разделах 2.2-2.4 для моделирования поведения факультативного автомата в смешанных состояниях. Если для входного слова w некоторое выполнение порождает сериализацию z, то, очевидно, yz – выходное слово при этом выполнении, а xz≤w, причем x-подслово конечно xz<w в одном из трех случаев: 1) выполнение заканчивается в терминальном состоянии; 2) начиная с некоторого момента, автомат проходит только через нерецептивные (посылающие) состояния; 3) выполнение заканчивается по ошибке неспецифицированного ввода. При этом само слово z конечно в случаях 1) и 3), а в случае 2) может быть как бесконечным, так и 37
конечным – если автомат с некоторого момента совершает только пустые переходы в нерецептивных состояниях. Заметим, что последовательность прочитанных автоматом из входной очереди стимулов совпадает с xz, причем все эти стимулы, кроме, быть, может последнего стимула xz (для конечного xz), удалены из входной очереди, после чего произошел один из указанных трех случаев. Для допустимого входного слова w имеются только первые два случая. Сериализацию z будем называть допустимой (в автомате), если она соответствует некоторому допустимому выполнению, и вполне-допустимой, если она соответствует вполне-допустимому выполнению, то есть, выполнению для допустимого входного слова. Через Zall обозначим множество допустимых сериализаций, Z(w) – множество сериализаций для допустимого входного слова w, а через Z – подмножество Zall вполне-допустимых сериализаций, которое, для краткости, мы будем называть также z-множеством автомата. Если нужно указать автомат m, будем писать Z[m]. Для класса автоматов N будем писать Z[N]={Z[m]|m∈N}. Заметим, что во множестве всех сериализаций выполнения автомата все допустимые сериализации максимальны (не имеют продолжения, так как бесконечны или заканчиваются в терминальных состояниях), а недопустимые сериализации немаксимальны (заканчиваются в рецептивных состояниях, то есть, могут быть продолжены для другого входного слова). Соответственно, множество Zall является множеством максимальных сериализаций (антицепью – все допустимые сериализации несравнимы друг с другом). На самом деле, Z может быть определено через Zall непосредственно. Будем говорить, что входное слово w допустимо во множестве максимальных сериализаций S, если любой начальный отрезок z[1..n] любой сериализации z∈S, x-подслово которого является начальным отрезком w, x(z[1..n])<w, всегда может быть продолжен в S сериализацией z`∈S, z[1..n]=z`[1..n], такой, что ее x-подслово xz`≤w. Сериализацию z∈S будем называть вполне-допустимой в S, если ее xподслово является начальным отрезком или совпадает с допустимым входным словом. Вполне-допустимым (дуальным) замыканием S назовем подмножество C<S> всех сериализаций вполне-допустимых в S; замкнутым по вполнедопустимости назовем такое множество S, что C<S>=S. Поскольку вместе с каждой вполне-допустимой сериализацией z∈S вполне-допустима также любая сериализация z`∈S, x-подслово которой совпадает с x-подсловом z, xz`=xz, или является его начальным отрезком xz`≤xz, нетрудно показать, что C
>=C<S>. Будем называть x-подслово сериализации z вполнедопустимого замыкания C<S> максимальным, если оно конечно, но в C<S> не существует сериализации z` с большим x-подсловом xz`>xz. Тогда, очевидно, множество входных слов допустимых в S, которое мы будем обозначать w(S), совпадает с множеством всех бесконечных x-подслов и всех бесконечных продолжений максимальных конечных x-подслов сериализаций вполнедопустимого замыкания C<S>. 38
Для S=Z допустимость входного слова в Z как раз и означает, что при любом выполнении не возникнет ситуации, когда в рецептивном состоянии читается очередной стимул входного слова и для этого стимула не определено поведение автомата. Таким образом, z-множество Z является замыканием по вполнедопустимости множества допустимых сериализаций Z=С(Zall). Z-множество Z однозначно определяет автоматную словарную функцию W. Словарную функцию для z-множества Z будем обозначать W(Z): • Dom(W(Z))=w(Z)=w(Zall) – множество входных слов допустимых в Z (Zall). • ∀w∈Dom(W(Z)) W(Z)(w)={yz|z∈Z xz≤w} – множество y-подслов сериализаций z-множества, x-подслова которых совпадают с входным словом или являются его начальными отрезками. Будем говорить, что класс автоматов N строго моделируется классом автоматов N`, если Z[N]⊆Z[N`], то есть, для каждого автомата m∈N существует автомат m`∈N`, имеющий то же z-множество Z[m]=Z[m`]. Если классы автоматов N и N` взаимно строго моделируют друг друга, то есть, множества их z-множеств совпадают Z[N]=Z[N`], то будем говорить, что эти классы автоматов строго эквивалентны. Преобразования разделов 2.2-2.4 сохраняют z-множество, что легко проверяется для каждого преобразования; поэтому все доказанные выше эквивалентности классов являются также строгими эквивалентностями. Конечную или бесконечную последовательность смежных переходов (следующий переход начинается в том состоянии, в котором заканчивается предыдущий) будем называть маршрутом. (Автомату соответствует граф его состояний, в котором вершины – это состояния, а дуги, раскрашенные стимулами, реакциями или нераскрашенные – это, соответственно, принимающие, посылающие или пустые переходы; последовательности смежных переходов соответствует последовательность смежных дуг, то есть, маршрут в графе.) Маршруту P соответствует последовательность стимулов и реакций его непустых переходов, то есть, сериализация, которую будем называть zраскраской маршрута и обозначать zP; x-подслово xzP будем называть xраскраской маршрута, а y-подслово yzP - y-раскраской маршрута. Выполнению автомата для данного входного слова w соответствует маршрут, начинающийся в начальном состоянии, который мы будем называть маршрутом выполнения; множество таких маршрутов будем обозначать P(w). Маршрут допустимого выполнения будем называть допустимым маршрутом – это любой маршрут, начинающийся в начальном состоянии и непродолжаемый, то есть, либо бесконечный, либо заканчивающийся в терминальном состоянии; множество вполне-допустимых маршрутов обозначим Pall. Маршрут вполне-допустимого выполнения будем называть вполне-допустимым маршрутом; множество вполнедопустимых маршрутов обозначим P (если нужно указать автомат m, будем писать P[m]). Множество их z-раскрасок zP={zP|P∈P} будем называть zраскраской автомата. 39
Прежде всего, заметим, что для любого выполнения автомата y-раскраска маршрута выполнения совпадает с y-подсловом сериализации этого выполнения, но x-раскраска маршрута выполнения, вообще говоря, не совпадает с xподсловом сериализации выполнения, и, тем самым, z-раскраска маршрута выполнения, вообще говоря, не совпадает с сериализацией выполнения. Причина этого в том, что не всякое срабатывание автомата, изменяющее сериализацию, сопровождается переходом. Имеются три типа срабатываний при отсутствии допустимых переходов: 1) срабатывание в терминальном состоянии (автомат останавливается); 2) срабатывание в принимающем состоянии при отсутствии e-переходов и пустом головном стимуле (пустой стимул помещается в сериализацию); 3) срабатывание с фиксацией ошибки неспецифицированного ввода, когда непустой головной стимул недопустим в текущем состоянии: рецептивном – для императивных автоматов, и принимающем – для факультативных автоматов. Терминальное срабатывание не изменяет сериализацию, и для допустимых выполнений остается только второй тип срабатывания, который изменяет сериализацию, но не сопровождается переходом. Мы покажем, что можно так преобразовать автомат, сохраняя реализуемое им z-множество Z и, тем самым, словарную функцию W, чтобы таких срабатываний не было, и для такого автомата Z=zP. В следующих разделах мы рассмотрим преобразования, позволяющие перейти сначала к автоматам, в которых сериализация выполнения по допустимому входному слову совпадает с раскраской маршрута выполнения; далее – к автоматам, в которых все маршруты являются маршрутами таких выполнений, и наконец – к автоматам, в которых все маршруты имеют уникальную раскраску, то есть, каждая сериализация является раскраской только одного маршрута.
3.2. Три класса автоматов и z-множеств 3.2.1. Класс автоматов A2, в которых z-раскраска совпадает с zмножеством (каждое нетерминальное срабатывание есть переход) Рассмотрим подкласс A2⊂A автоматов без смешанных состояний, в которых нет срабатываний типа 2. Это означает, что в таком автомате в каждом принимающем состоянии определен хотя бы один e-переход и тогда каждое нетерминальное срабатывание для допустимого выполнения сопровождается переходом. Поэтому каждый допустимый маршрут как последовательность переходов взаимнооднозначно соответствует последовательности нетер-минальных срабатываний автомата, z-раскраска маршрута zP совпадает с сериализацией выполнения, а zраскраска автомата совпадает с его z-множеством Z=zP. При этом для допустимого входного слова w∈Dom(W) и маршрута выполнения P∈P(w) имеет место xzP≤w и yzP∈W(w). 40
Теорема о срабатываниях и переходах: Класс автоматов A строго моделируется своим подклассом A2. Доказательство: От срабатываний типа 2 легко избавиться, если в каждом принимающем состоянии v, в котором не определены e-переходы, добавить eпереход (v,e,v), не изменяющий состояния (петлю). Очевидно, что такие преобразования не изменяют z-множество, а получившийся автомат относится к классу A2. Теорема о срабатываниях и переходах доказана.
m∈A2
m`∈A3
Следствие: поскольку Z(A)=Z(M), A2⊂A и Z(A)⊆Z(A2), очевидно, Z(A2)=Z(M).
3.2.2. Класс автоматов A3, в которых все допустимые маршруты (сериализации) вполне-допустимы
обозначения:
В автомате класса A2, вообще говоря, не все допустимые маршруты являются вполне-допустимыми маршрутами. Рассмотрим подкласс A3⊂A2 автоматов, в которых все допустимые маршруты вполне-допустимы. Теорема о вполне-допустимых маршрутах: Класс автоматов A2 строго моделируется своим подклассом A3. Доказательство: Пусть задан автомат m=(V,v0,X,e,Y,T) класса A2; мы построим автомат m`, имеющий то же z-множество и принадлежащий классу A3. Для каждого непустого подмножества состояний H⊆V построим y-подавтомат yH, переходы которого – это все переходы, принадлежащие маршрутам в m, начинающимся в состояниях из H и содержащим только посылающие и пустые переходы, а состояния – это состояния инцидентные таким переходам (являющиеся их началами и концами). Множество H будем называть множеством входных состояний y-подавтомата yH. Через tH обозначим множество состояний y-подавтомата, являющихся принимающими в m; это множество состояний yподавтомата будем называть его множеством выходных состояний. Полученные y-подавтоматы, как подавтоматы одного автомата, имеют общие состояния и переходы. Нам нужно "расклеить" их, превратив в y-автоматы с непересекающимися множествами состояний и переходов. Поэтому для каждого y-подавтомата yH определим соответствующий y-автомат (yH,H), получающийся переименованием состояний: каждое состояние v из y-подавтомата yH в yавтомате (yH,H) обозначим как (v,H). Автомат m` строится как объединение всех y-автоматов автомата m, в которое добавлены дополнительные принимающие переходы следующим способом (Рис. 24):
41
начальное состояние m - v0 начальное состояние m` - (v0,{v0}) y-автомат входное состояние выходное состояние одновременно входное и выходное состояние Рис. 24 1) Для каждого y-подавтомата yH и каждого стимула x (пустого или непустого), допустимого в автомате m в каждом выходном состоянии y-подавтомата, определяется множество R(H,x) принимающих переходов, начинающихся в этих выходных состояниях. 2) Для множества H` концов переходов из R(H,x) рассматривается yподавтомат yH`. 42
3) Для каждого перехода (v,x,v`)∈R(H,x) в автомате m` добавим переход ((v,H),x,(v`,H`)) из выходного состояния (v,H) y-автомата (yH,H) во входное состояние (v`,H`) y-автомата (yH`,H`). 4) Начальным состоянием автомата m` объявим состояние (v0,{v0}) y-автомата (y{v0},{v0}) (соответствующий y-подавтомат порождается одним начальным состоянием {v0} автомата m). 5) После этого оставляем в автомате m` только те состояния, которые достижимы из начального состояния (v0,{v0}), и только те переходы, которые определены в достижимых состояниях. По построению видно, что автомат m` обладает всеми нужными свойствами. Теорема о допустимых маршрутах доказана. Замечание: На Рис. 24 не показаны e-петли, определенные в каждом принимающем состоянии. С учетом этих петель выделяются еще два y-автомата: (y{2,3},{2,3}) и (y{0,2,3},{0,2,3}), в которых вход совпадает с выходом, во все их состояния ведут e-переходы из всех копий принимающих состояний 0,2,3 во всех y-автоматах и во всех состояниях этих y-графов определены принимающие переходы по стимулу x во входное состояние y-графа (y{0},{0}). В этом автомате существует недопустимый бесконечный маршрут 0⎯x→1,(1⎯y2→3,3⎯x1→1)ω (этот маршрут является маршрутом выполнения только для одного слова x(x1)ω, однако это слово недопустимо, поскольку для него имеется другой маршрут выполнения 0⎯x→1,1⎯y1→2, заканчивающийся по ошибке неспецифицированного ввода: в состоянии 2 стимул x1 недопустим). Следствие: поскольку Z(A2)=Z(A)=Z(M), A3⊂A2 и Z(A2)⊆Z(A3), очевидно, Z(A3)=Z(M). Выше мы уже говорили, что поскольку автомат с некоторого момента может прекратить выборку стимулов из входной очереди, x-подслово сериализации может не совпадать со входным словом, а являться его начальным отрезком. Теперь мы можем показать, что неравенство xz<w для сериализации z выполнения по некоторому допустимому входному слову w и конечность xраскраски маршрута P∈P(w), xzP<w носят принципиальный характер. Если выполнение заканчивается в терминальном состоянии v (сериализация и маршрут конечны), то этот случай легко обойти, преобразовав автомат с сохранением словарной функции (правда, без сохранения сериализаций): для этого достаточно сделать состояние v принимающим, определив в нем переходы-петли (v,x`v) для всех стимулов x`∈X`. Однако, другой случай, когда выполнение бесконечно, но с какого-то момента проходит только через нерецептивные состояния (маршрут бесконечен), обойти не удается. Мы покажем, что для некоторых словарных функций любой реализующий их конечный автомат выбирает из входной очереди лишь конечное число стимулов для некоторых допустимых входных слов. Теорема о конечном x-подслове сериализации: Существуют такие автоматные словарные функции, что в любом конечном автомате, их реализующем, имеется вполне-допустимое выполнение с конечным x-подсловом сериализации. 43
Доказательство: Примером может служить словарная функция автомата класса A3, изображенного на Рис. 25: eω→(), e*x(e*x)neω→{yω,y*y1n}, (e*x)ω→{yω,y*y1ω}, где n=0.. – число зависимых повторений - все вхождения n в показателе степени указывают на одно и то же число повторений n, "*" – как обычно, независимое число повторений ноль или более раз.
Рис. 25 Допустим, существует автомат, реализующий эту словарную функцию, в котором все вполне-допустимые сериализации имеют бесконечные x-подслова. Тогда, очевидно, существует такой же автомат класса A3, и в нем все допустимые маршруты имеют бесконечные x-подслова. Заметим, что, согласно словарной функции, входное слово xω может быть отображено в выходное слово yω. Отсюда следует, что в автомате есть бесконечный допустимый маршрут P такой, что xzP=xω и yzP=yω. Тогда существует циклический маршрут C, все переходы которого - это принимающие переходы по стимулу x или посылающие переходы с реакцией y, причем число и тех и других в маршруте C больше нуля. Также должен существовать конечный маршрут N, начинающийся в начальном состоянии и заканчивающийся в начальном состоянии цикла C. В автомате класса A3 в принимающих состояниях определены e-переходы. Пусть такой e-переход определен в состоянии, в котором определен принимающий переход C[i], и пусть E – произвольный маршрут, начинающийся этом состоянии, содержащий только посылающие, пустые и e-переходы (не содержащий x-переходов) и бесконечный или заканчивающийся в терминальном состоянии. Рассмотрим допустимый маршрут P1=N^C^C[1..i-1]^E. В нем, очевидно, конечное ненулевое число принимающих переходов по стимулу x. Тогда, в соответствии со словарной функцией, в нем должно быть конечное число посылающих переходов по реакции y1; пусть это число равно n. Тогда рассмотрим допустимый маршрут Pn=N^Cn+2^C[1..i-1]^E. В нем, очевидно, конечное число N≥n+2 принимающих переходов по стимулу x. Очевидно, N-1>n. Тогда, в соответствии со словарной функцией, в нем должно быть N-1 посылающих переходов по реакции y1, но, поскольку C не содержит y1-переходов, маршрут Pn должен содержать столько же y1-переходов, сколько их содержит маршрут P1, то есть, n, чего не может быть, поскольку N-1>n. Мы пришли к противоречию и, тем самым, утверждение доказано. Теорема о конечном x-подслове сериализации доказана.
44
3.2.3. Класс автоматов A4 с детерминированным z-множеством
исходный порождающий граф G
Распространим понятие регулярности [7-9] на множества не только конечных, но и бесконечных слов. Пусть задан некоторый алфавит символов A. Порождающим графом будем называть граф G с выделенными начальными и конечными вершинами, некоторые дуги которого раскрашены символами из A. Маршрут в графе G имеет раскраску как последовательность раскрасок его раскрашенных дуг (нераскрашенные – пустые – дуги пропускаются). Порождающий маршрут – маршрут, начинающийся в начальной вершине и бесконечный или заканчивающийся в конечной вершине. Будем говорить, что граф G порождает множество раскрасок всех порождающих маршрутов графа. Множество слов H в алфавите A будем называть регулярным, если оно порождается некоторым конечным порождающим графом. Порождающий граф G будем называть детерминированным, если из каждой его вершины выходит не более одной дуги, раскрашенной данным символом из алфавита A. Конечный детерминированный порождающий граф будем называть нормальным, если он имеет одну начальную вершину, не имеет пустых дуг и все вершины достижимы из начальной вершины. Очевидно, в нормальном порождающем графе все порождающие маршруты имеют разные раскраски, то есть, каждое слово из порождаемого множества порождается ровно одним маршрутом. Аналогично случаю регулярных множеств конечных слов, можно сформулировать следующую теорему: Теорема о нормальном порождающем графе: Каждое регулярное множество слов порождается нормальным порождающим графом. Доказательство: Пусть задан произвольный конечный порождающий граф G; мы построим нормальный порождающий граф G`, порождающий то же множество слов. Прием его построения похож на соответствующий прием для порождающих графов регулярных множество конечных слов [7,9]. Этап 1. Прежде всего, заметим, что, если в вершине v, достижимой из какойнибудь начальной вершины, начинается маршрут, состоящий только из пустых дуг и бесконечный или заканчивающийся в конечной вершине графа G, то вершину v можно пометить как конечную без изменения порождаемого множества слов. Проделаем эту процедуру для всех таких вершин v. Этап 2. Далее вершинами графа G` объявим все непустые подмножества вершин графа G. Для каждого подмножества вершин U и каждого символ a рассмотрим конечный маршрут, начинающийся в некоторой вершине из U, все дуги которого нераскрашены, кроме одной, раскрашенной символом a. Если такие маршруты есть и H – множество их концов, то проведем дугу (U,x,H) из U в H раскрашенную символом a. Начальной вершиной графа G` объявим множество всех начальных вершин графа G. Конечными вершинами графа G` объявим все множества, содержащие хотя бы одну конечную вершину графа G. После этого удалим из G` все его вершины, недостижимые из начальной, и все инцидентные им дуги. Полученный граф является нормальным по построению (Рис. 26). 45
- начальная вершина - конечная вершина
нормальный порождающий граф G`
порождаемое множество: [2]1(21)*[2], [2]1(21)ω Рис. 26
Поскольку дуге (U,a,H) графа G` взаимно-однозначно соответствует непустое множество всех конечных маршрутов графа G, начинающихся в вершинах из U и имеющих раскраску (a), то и любому маршруту P` графа G`, начинающемуся в вершине U взаимно-однозначно соответствует непустое множество всех маршрутов графа G, начинающихся в вершинах из U и имеющих такую же раскраску, что и P`. Поскольку начальная вершина G` есть множество начальных вершин G, а конечная вершина G` содержит конечную вершину графа G (включая добавленные на этапе 1), порождающему маршруту графа G`, очевидно, взаимно-однозначно соответствует непустое множество всех порождающих маршрутов графа G, имеющих ту же раскраску. Теорема о нормальном порождающем графе доказана. В автомате класса A3 все допустимые маршруты вполне-допустимы. Поэтому, если в графе состояний такого автомата конечными вершинами объявить терминальные вершины, то такой граф является порождающим графом в объединенном алфавите стимулов (включая пустой стимул) и реакций X`∪Y, а порождаемое им регулярное множество является z-множеством автомата. Однако, в общем случае, этот порождающий граф недетерминирован, то есть, может существовать несколько разных допустимых маршрутов, имеющих одну и ту же z-раскраску. Заметим, что детерминированность графа состояний как порождающего графа вовсе не означает детерминированности автомата: все принимающие переходы, определенные в данном состоянии, отличаются стимулами и поэтому при данном головном стимуле возможен только один принимающий переход; однако, хотя все посылающие переходы, определенные в данном состоянии, отличаются реакциями, допустим любой из них и выбор посылающего перехода, то есть, посылаемой реакции, по-прежнему недетерминирован. Классом A4⊂A3 назовем подкласс, в котором все допустимые маршруты имеют уникальные z-раскраски, то есть, граф состояний которого является детерминированным порождающим графом. Будем говорить, что такие автоматы – это автоматы с детерминированным z-множеством. Более строго, следовало бы говорить о мульти-множестве сериализаций (маршрутов) – 46
множестве с повторяющимися элементами, где каждая сериализация (раскраска маршрута) повторяется столько раз, скольким выполнениям (маршрутам) она соответствует; детерминированное мультимножество – это обычное множество, где каждый элемент повторяется один раз. Теорема о детерминированном z-множестве: Каждый автомат класса A3 строго моделируется некоторым автоматом класса A4. Доказательство: Пусть задан автомат m класса A3, мы построим автомат m`, имеющий ту же z-раскраску и принадлежащий классу A4. Этап 1. Граф состояний автомата m можно рассматривать как порождающий граф, конечными вершинами которого являются терминальные состояния. Заметим, что порождающие маршруты совпадают в этом случае с допустимыми маршрутами. Для этого графа построим нормальный порождающий граф. Этап 2. В полученном графе могут появиться конечные вершины, не являющиеся терминальными. Чтобы избавиться от них, из каждой такой вершины v проведем пустую дугу в какую-нибудь терминальную вершину (если таких нет, добавим новую терминальную вершину) и объявим вершину v не конечной. Очевидно, порождаемое множество от этого не изменится, а граф останется детерминированным порождающим графом (хотя уже и не нормальным). Этап 3. В полученном графе могут быть смешанные вершины. Чтобы избавиться от них, для каждой смешанной вершины v добавим новую вершину v1 и пустую дугу (v, v1), а каждую принимающую дугу, ведущую из v, (v,x,v`), где x∈X`, заменим на принимающую дугу из v1 – (v1,x,v`). Вершина v будет теперь посылающей, а вершина v1 – принимающей (Рис. 27). Раскраски маршрутов, очевидно, не изменились (добавленные пустые дуги не участвуют в раскраске маршрута) и граф остался детерминированным порождающим графом.
⇒ Рис. 27 Этот граф будем считать графом состояний автомата m`. По построению он относится к классу A2 (нет смешанных состояний и в каждом принимающем состоянии определен e-переход, поскольку так было в m). По построению, множествам всех одинаково раскрашенных допустимых маршрутов в m взаимнооднозначно соответствуют так же раскрашенные допустимые маршруты в m`, то есть, Zall[m`]= Zall[m]. Поскольку m относится к классу A3, в нем все допустимые маршруты вполне-допустимы Z[m]=C=Zall[m], поэтому Z[m`]=C=С=Zall[m`] и Z[m`]=Z[m], то есть, автомат m` тоже относится к классу A3 и имеет то же z-множество, что m. Из детерминизма порождающего графа следует детерминированность z-множества в m`, то есть, m` относится к классу A4. 47
Теорема о детерминированном z-множестве доказана.
3.3. Автоматные множества сериализаций, распознающие и отвергающие автоматы. Множество S сериализаций будем называть автоматным, если оно является zмножеством некоторого автомата. Выше уже показано, что автоматное множество регулярно, и для того, чтобы регулярное множество было автоматным, нужно, чтобы оно было замкнуто по вполне-допустимости C<S> = S и любой начальный отрезок сериализации, продолжаемый в ней стимулом, мог быть также продолжен пустым стимулом (допустимость пустых стимулов во всех рецептивных состояниях). Таким образом, мы имеем следующую теорему. Теорема об автоматности множества сериализаций: Необходимым и достаточным условием автоматности множества S сериализаций является выполнение следующих трех требований: • Регулярность: Множество S регулярно. • Допустимость x-подслов: Все x-подслова сериализаций из S допустимы в S, что эквивалентно замкнутости S по вполне-допустимости C<S> = S. • Допустимость пустого стимула: Для любой сериализации z∈S любой ее начальный отрезок u
или не может она принадлежать z-множеству заданного автомата. Поскольку речь идет не только о конечных, но и о бесконечных словах, мы в общем случае не можем говорить о распознающих автоматах, то есть, автоматах, которые определяли бы принадлежность слова множеству за конечное число шагов, то есть, по его начальному отрезку конечной длины. Например, автомат на Рис. 28 имеет сериализацию xyω∈Z, каждый начальный отрезок которой xyn является начальным отрезком сериализации xyny1ω∉Z. Заметим, что для множеств конечных слов распознаваемость совпадает с регулярностью: по нормальному порождающему графу легко построить граф состояний распознающего автомата, а по графу состояний распознающего автомата – порождающий граф. Рис. 28 С другой стороны, мы можем говорить об отвергающих автоматах, которые за конечное число шагов отвергают слово, если оно не принадлежит множеству, хотя для слов, принадлежащих множеству, могут работать бесконечно. 48
Будем говорить, что автомат m является отвергающим автоматом для множества слов S в алфавите A, если • алфавит стимулов автомата m - это алфавит A; • алфавит реакций состоит из одной реакции "не принадлежит"; • для каждого слова z∈S автомат m выдает единственное пустое выходное слово, • для каждого слова z∉S автомат m выдает единственное выходное слово, состоящее из одной реакции "не принадлежит". Отвергающий автомат будем называть нормальным, если он детерминирован (как автомат, а не как порождающий граф) и не имеет пустых переходов. Теорема об отвергающем автомате: Множество слов регулярно тогда и только тогда, когда для него существует нормальный отвергающий автомат. Доказательство: По нормальному порождающему графу регулярного множества слов H в алфавите A можно построить граф состояний нормального отвергающего автомата для H: • алфавитом стимулов объявляется алфавит A; • алфавитом реакций объявляется множество из одной реакции "не принадлежит"; • начальным состоянием объявляется состояние автомата, соответствующее начальной вершине порождающего графа; • добавляются два состояния t и t` и посылающий переход из t в t` с реакцией "не принадлежит"; • если из какой-то вершины v порождающего графа не выходит дуга, помеченная некоторым символом a из A, в соответствующем состоянии v автомата определим принимающий переход по стимулу a в состояние t, то есть, переход (v,a,t). Наоборот, если задан нормальный отвергающий автомат для множества слов H в алфавите A, то по его графу состояний можно построить нормальный порождающий граф для множества H. В графе состояний автомата выполним следующие преобразования: • удаляются вершины, являющиеся началами посылающих дуг с реакцией "не принадлежит", и все инцидентные им дуги; • если при этом образуются новые терминальные вершины, то эти вершины удаляются вместе с инцидентными им дугами (старые терминальные вершины остаются) - это повторяется до тех пор, пока остаются новые терминальные вершины; • удаляются все вершины, не достижимые из начальной вершины, и все дуги им инцидентные. Теорема об отвергающем автомате доказана. Для словарной функции W можно говорить об отвергающем автомате, который имеет две входные очереди, в которые помещаются входное слово w и выходное слово u, и одну выходную очередь, в которую автомат должен поместить вердикт 49
"не принадлежит", если w∉Dom(W) или u∉W(w), а в противном случае - ничего. Если для словарной функции существует такой отвергающий автомат, будем называть ее регулярной. Можно сформулировать следующие нерешенные задачи: 1. Всякая ли автоматная словарная функция (быть может, с некоторыми дополнительными условиями) регулярна? 2. Всякая ли регулярная словарная функция (быть может, с некоторыми дополнительными условиями) автоматна?
3.4. Квази-конечные z-множества
сужения
словарной
функции
и
Мы определили словарную функцию как функцию на бесконечных входных словах, поскольку это было удобной математической абстракцией. Однако, при тестировании мы можем иметь дело только с конечными входными словами. В этой математической абстракции конечное входное слово можно понимать как бесконечное слово, в котором имеется только конечное число непустых стимулов; такие бесконечные слова будем называть квази-конечными. Квази-конечным сужением словарной функции W будем называть функцию W|F, определенную только на квази-конечных входных словах: • Dom(W|F) = (X`*^{eω})∩Dom(W) • ∀w∈Dom(W|F) W|F(w)=W(w) Соответственно, квази-конечным сужением множества сериализаций S (в частности, z-множества автомата Z) будем называть его подмножество S|F, содержащее только такие сериализации, x-подслова которых конечны или квазиконечны. Для произвольного множества слов U через U[] будем обозначать множество начальных отрезков конечной длины слов из U; это множество будем называть конечным сужением множества U. Прежде всего, зададимся вопросом: однозначно ли определяется словарная функция автомата по ее квази-конечному сужению? Ответ на этот вопрос отрицательный. Пример приведен на Рис. 29. Для двух автоматов 1 и 2 значение словарной функции на всех допустимых квазиконечных словах одно и то же – реакция y. Однако, полные словарные функции (на всех бесконечных словах) автоматов 1 и 2 различаются: при непрерывной (без пустых стимулов) подаче на автомат стимула x, автомат 1 ничего не выдает (пустое выходное слово), а автомат 2 по-прежнему выдает реакцию y. 1 2
словарная функция
50
xω→{()} x e(e|x)ω→{(y)} *
(e|x)ω→{(y)}
квази-конечное сужение словарной функции
(e|x)*eω→{(y)}
(e|x)*eω→{(y)}
z-множество
xω x*ey(x|e)ω
(x|e)y(x|e)ω
x*ey(e*x)*eω
(x|e)y(e*x)*eω
x*[e[y(e|x)*]]]
[(x|e)[y(e|x)*]]
квази-конечное сужение z-множества конечное сужение zмножества
Рис. 29 В этой ситуации у нас возможны три направления дальнейшего движения: 1. Можно ограничиться такими классами автоматов, для которых словарная функция однозначно определяется ее квази-конечным сужением. Для этого надо описать класс словарных функций, однозначно определяемых своими квази-конечными сужениями. 2. Можно ограничиться такими классами автоматов, для которых нас не интересует их поведение на бесконечных входных словах. Иными словами, функциональные требования к автомату могут быть сформулированы в терминах квази-конечного сужения словарной функции. Тем самым, мы будем проверять поведение автомата только на квази-конечных входных словах и, если на таких словах оно правильно, то будем делать вывод, что реализация соответствует модели. 3. Если функциональные требования к автомату не могут быть сформулированы только в терминах квази-конечного сужения словарной функции, то добавим дополнительные функциональные требования. Третье направление нуждается в разъяснениях. Здесь есть две проблемы: 1. Как задавать дополнительные функциональные требования? 2. Как проверять дополнительные функциональные требования при тестировании только на квази-конечных входных словах? Приведенный пример автоматов 1 и 2, словарные функции которых различны, но имеют одинаковое квази-конечное сужение, показывает, что эти автоматы имеют разные z-множества. Например, любая сериализация в автомате 2 имеет на второй позиции реакцию y, а в автомате 1 – реакция y располагается непосредственно после первого пустого стимула. Это наталкивает на мысль формулировать дополнительные функциональные требования в терминах ограничений на вполне-допустимые сериализации автомата, то есть, в виде предиката на множестве всех сериализаций для данных алфавитов стимулов и реакций. Имея в виду проблему проверяемости этих дополнительных требований, нас интересуют в первую очередь предикаты на конечных сериализациях, интерпретируемых как начальные отрезки сериализаций автомата, то есть, элементы конечного сужения z-множества. Автоматы 1 и 2 в нашем примере различаются по начальным отрезкам сериализаций длины 2. 51
3.5. Предикат на конечных сериализациях Слово (в некотором алфавите) w называется (индуктивным) пределом неубывающей бесконечной последовательности конечных слов u[1]≤u[2]≤..., если для каждого i=1.. u[i]≤w и для любого другого слова w`, обладающего тем же свойством, w≤w`. Существование предела очевидно: если, начиная с некоторого i все последовательности u[j] (j≥i) равны, w=u[i]; в противном случае последовательность длин слов u[i] бесконечно возрастает и для любого n=1.. все слова, начиная с первого в последовательности слова, длина которого не меньше n, содержат один и тот же символ в позиции n, который и определим как n-ый символ слова w. Предел последовательности, очевидно, единственный. Множество всех неубывающих бесконечных последовательностей начальных отрезков слов множества U будем называть множеством его пределов и обозначать Lim(U). Замыканием по пределу множества слов U назовем его объединение с множеством его пределов и обозначать L = U∪Lim(U). Множество назовем замкнутым, если оно совпадает со своим замыканием: U=L. Очевидно, не всякое множество замкнуто: например, множество всех слов в алфавите {0,1}, каждое из которых содержит ровно одну 1, незамкнуто, так как не содержит нулевое слово, являющееся пределом последовательности 0<00<000<… начальных отрезков слов 010…, 0010…, 00010…. Если множество U незамкнуто по пределу, то отвергающий автомат не существует. Действительно, если существует возрастающая бесконечная последовательность w1[1..n1]<w2[1..n2]<... начальных отрезков слов из U, wi∈U для i=1..., предел которой w∉U, то, очевидно, слово w не может быть отвергнуто ни по какому своему начальному отрезку (конечной длины), поскольку такой отрезок является одновременно начальным отрезком некоторого слова wi, принадлежащего U. Конечно, поскольку не всякое замкнутое множество регулярно, не для всякого замкнутого множества существует отвергающий автомат. Например, множество, состоящее из одного слова, являющегося десятичной записью иррационального числа, замкнуто, но не регулярно, и отвергающего автомата для него не существует. Однако, для всякого регулярного множества отвергающий автомат существует и поэтому оно замкнуто. В частности, z-множество автомата замкнуто: L = Z. Заметим, что, используя понятие замыкания по пределу, мы могли бы определить регулярное множество (как конечных, так и бесконечных) слов U как объединение некоторого регулярного множества конечных слов F1 и множества пределов некоторого другого регулярного множества конечных слов F2: U=F1∪Lim(F2), где F1 содержит все конечные слова из U, а Lim(F2) содержит все бесконечные слова из U. Порождающий граф для F1 совпадает с порождающим графом для U, а порождающий граф для F2 строится из него добавлением конечных вершин на каждом циклическом маршруте, на котором конечных вершин нет. 52
Очевидно, L ⊆ L, причем равенство достигается тогда и только тогда, когда все конечные слова в U максимальны в нем, то есть, U - антицепь. Множество U идеально, если вместе с каждым словом оно содержит и все его начальные отрезки. Идеальность множества U конечных слов эквивалентна тому, что U является конечным сужением некоторого множества H, то есть, U=H[]. В частности, в качестве такого множества H можно всегда выбрать замыкание по пределу H=L. Заметим, однако, что конечное сужение незамкнутого по пределу множества также идеально. Очевидно также, что U совпадает с конечным сужением множества пределов U=Lim(U)[]=Lim(H)[]. Если U – это множество сериализаций, то множество пределов будет множеством максимальных сериализаций, для которого определено понятие допустимого входного слова, и поэтому мы можем говорить о входных словах, допускаемых во множестве пределов w(Lim(U))=w(Lim(H)). Пусть на множестве всех конечных сериализаций (для данных алфавитов стимулов и реакций) задан предикат p. Обозначим индуцируемое предикатом множество сериализаций U(p)={u|p(u)=true}. Будем считать, что U(p) идеально. Входное слово, допустимое во множестве пределов U(p), будем называть допускаемым предикатом. Определим индуцируемое предикатом p семейство автоматов A(p) следующим образом: m∈A(p) тогда и только тогда, когда выполняются следующие два свойства: 1. Каждое входное слово допускаемое предикатом допустимо в автомате: w(Lim(U(p))) ⊆ Dom(W[m])[]. 2. Если x-подслово начального отрезка вполне-допустимой сериализации автомата совпадает с x-подсловом некоторой сериализации из U(p), то сам этот отрезок принадлежит U(p): {u∈Z[m][] | xu∈xU(p)} ⊆ U(p). Следует отметить, что индуцируемые автоматы определяются с точностью до их вполне-допустимых сериализаций, то есть, два автомата с одним z-множеством либо оба не попадают, либо оба попадают в индуцируемое семейство A(p). Поэтому можно говорить об индуцируемом семействе z-множеств. Пусть заданы два множества максимальных сериализаций H и U. Будем говорить, что множество H сводимо к множеству U, если: 1) каждое входное слово, допустимое в U, допустимо в H, 2) каждая вполне-допустимая сериализация H, xподслово которой является начальным отрезком или совпадает с входным словом допустимым в U, принадлежат U. Будем также говорить, что множество H конечно-сводимо к множеству U, если: 1) каждый начальный отрезок входного слова допустимого в U является начальным отрезком входного слова допустимого в H, 2) каждый начальный отрезок вполне-допустимой сериализации H, x-подслово которого является начальным отрезком входного слова, допустимого в U, является начальным отрезком вполне-допустимой сериализации U.
53
Предикат p индуцирует конечное сужение множества максимальных сериализаций U=Lim(U(p)), то есть, U(p)=U[], и, очевидно, индуцируемое предикатом семейство z-множеств является семейством всех z-множеств, конечно-сводимых к U. Лемма о сводимом множестве сериализаций: Если множество максимальных сериализаций H сводимо к множеству максимальных сериализаций U, то оно конечно-сводимо к нему. Доказательство: Действительно, поскольку каждое входное слово w, допустимое в U, допустимо в H, то каждый его начальный отрезок u<w является начальным отрезком входного слова w, допустимого в H. Если начальный отрезок z1 сериализации z, вполне-допустимой в H, имеет x-подслово xz1, являющееся начальным отрезком входного слова w, допустимого в U, xz1<w, то это входное слово w допустимо также в H. Отсюда следует, что в H имеется сериализация z`, соответствующая w, xz`≤w, являющаяся продолжением отрезка z1
3.5.1. Предикат z-множества Предикатом z-множества p(Z) будем называть предикат, индуцирующий конечное сужение этого z-множества: U(p(Z)) = Z[]. Иными словами, предикат 54
z-множества индуцирует множество начальных отрезков вполне-допустимых сериализаций некоторого автомата с данной словарной функцией W(Z). Будем говорить, что автомат m сводим к z-множеству Z, если к нему сводимо zмножество автомата Z[m], то есть: 1) каждое входное слово, допустимое в Z, допустимо в m, Dom(W(Z)) ⊆ Dom(W[m]) и 2) каждая вполне-допустимая сериализация автомата, x-подслово которой является начальным отрезком или совпадает с входным словом допустимым в Z, принадлежит Z, ∀w∈Dom(W(Z)) {z∈Z[m] | xz≤w} ⊆ Z. Из Леммы о сводимом множестве сериализаций следует, что автомат m сводимый к z-множеству Z принадлежит семейству автоматов, индуцируемых предикатом z-множества: m∈A(p(Z)). Поскольку все z-множества замкнуты по пределу, из Леммы о конечно-сводимом множестве сериализаций следует, что автомат m из семейства автоматов, индуцируемых предикатом z-множества Z, сводим к этому к z-множеству. Итак, нами доказана следующая Теорема о предикате z-множества: Предикат z-множества индуцирует семейство всех автоматов, сводимых к этому z-множеству.
позициях, то есть, хотя бы для одного маршрута P такого, что xzP≤x и yzP=y, первые n переходов принимающие. Доказательство: Будем вести доказательство от противного и в терминах графа состояний (Рис. 30). Пусть существует такая словарная функция W, такое допустимое входное слово x∈Dom(W), такое соответствующее ему выходное слово y∈W(x) и такое натуральное число n, что в каждом автомате m класса A3, реализующем эту словарную функцию W[m]=W, для каждого маршрута P, раскраски которого xzP≤x и yzP=y, отрезок P[1..n] содержит посылающий переход. Выберем для данных W, x и y число n минимальным и выберем автомат m класса A3 и в нем маршрут P такой, что xzP≤x и yzP=y, отрезок P[1..n-1] содержит только принимающие переходы, а переход P[n] посылающий. Очевидно, zP[1..n]=x[1..n-1]^y[1].
3.5.2. Предикат словарной функции Теорема о предикате z-множества позволяет ограничиться тестированием только конечных сериализаций, однако при этом мы проверяем соответствие реализации модели не по словарной функции, а по z-множеству. Иными словами, мы начинаем различать реализации, имеющие одну и ту же, заданную моделью, словарную функцию, но разные z-множества, несводимые к одному, задаваемому предикатом. Поэтому теперь попробуем перейти к рассмотрению множества автоматов, реализующих данную словарную функцию безотносительно к их zмножествам. Для этого мы будем рассматривать z-множество словарной функции Z(W)={Z|W(Z)=W} – как объединение z-множеств с данной словарной функцией. Соответственно, речь пойдет о предикате словарной функции p(W), который индуцирует множество U(p(W))=Z(W)[]=∪{Z[]|W[Z]=W} начальных отрезков вполне-допустимых сериализаций не одного, а всех автоматов с данной словарной функцией W. Нас будет интересовать замкнутость, регулярность и существование отвергающего автомата, который по начальному отрезку (конечной длины) сериализации определяет, может или не может она принадлежать z-множеству какого-нибудь автомата, реализующего данную словарную функцию W. Лемма о первой реакции в сериализации: Для любой автоматной словарной функции W, любого допустимого входного слова x∈Dom(W), любого соответствующего ему выходного слова y∈W(w) и любого натурального числа n существует автомат m класса A3, реализующий эту словарную функцию W[m]=W, в котором одна из сериализаций для пары (x,y) не содержит реакций на первых n 55
Рис. 30 Маршрут P[n..] либо 1) не содержит принимающих дуг, либо 2) содержит первый принимающий переход P[n+k] (k>0) такой, что (zP)[n+k]=x[n]. Рассмотрим подавтомат m`, содержащий в случае 1) - все переходы оставшейся части маршрут P[n..], а в случае 2) - все переходы отрезка маршрута P[n..n+k-2] (при k=1, маршрут нулевой - только одно состояние - начало n-ого перехода маршрута P), а также все инцидентные им состояния. Скопируем этот подавтомат m` (его переходы и состояния для отличия от переходов и состояний автомата m будем снабжать штрихом "`"). Введем новое состояние v1, и добавим для состояния начала перехода P[n-1] принимающий переход по стимулу x[n-1] в состояние v1, а в состоянии v1 добавим принимающий переход по стимулу x[n] в состояниекопию начала перехода P[n]`. Для случая 1) построение закончено, а для случая 2) добавим для состояния-копии начала перехода P[n+k-1]` посылающий переход по реакции y[k] в состояние – начало перехода P[n+k+1]. Тем самым, мы добавили маршрут с z-раскраской, в которой n-ый стимул входного слова x[n] принимается непосредственно после приема n-1-го стимула, а потом уже выдается первая реакция y[1]: для случая 1) мы для маршрута с zраскраской x[1],...,x[n-2],x[n-1],y[1],... добавили маршрут с z-раскраской x[1],...,x[n-2],x[n-1],x[n],y[1],..., а в случае 2) мы для маршрута с z-раскраской x[1],...,x[n-2],x[n-1],y[1],...,y[k],x[n],... добавили маршрут с z-раскраской 56
x[1],...,x[n-2],x[n-1],x[n],y[1],...,y[k],..... Таким образом, мы построили автомат, который, очевидно, реализует ту же словарную функцию, но имеет вполнедопустимый маршрут, z-раскраска которого имеет стимулы на первых n позициях, то есть, не содержит реакции на первых n позициях, что противоречит предположению. Лемма о первой реакции в сериализации доказана. Словарную функцию W будем называть существенно ненулевой, если хотя бы для одного допустимого входного слова w∈Dom(W) множество выходных слов не содержит пустого выходного слова ()∉W(w), что эквивалентно w∉Z(W). Теорема о незамкнутости z-множества словарной функции: Если автоматная словарная функция W существенно ненулевая, то ее z-множество Z(W) незамкнуто. Доказательство: Если словарная функция существенно ненулевая, то, очевидно, само слово w, для которого ()∉W(w), не принадлежит z-множеству никакого автомата, реализующего эту словарную функцию. Однако, согласно Лемме о первой реакции в сериализации, первая реакция в сериализации z для входного слова w (xz≤w)может быть сколь угодно поздно, то есть, любой начальный отрезок w может быть начальным отрезком z. Таким образом, слово w∉Z(W), но любой его начальный отрезок конечной длины имеет в Z(W) продолжение, то есть, Z(W) незамкнуто. Теорема о незамкнутости z-множества словарной функции доказана. Будем говорить, что автомат m сводим к словарной функции W, если: 1) Dom(W[m]) ⊆ Dom(W) и 2) ∀w∈Dom(W[m]) W[m](w) ⊆ W(w). Очевидно, сводимость автомата к словарной функции эквивалентна его сводимости к zмножеству словарной функции. Из Леммы о сводимом множестве сериализаций следует, что семейство автоматов, индуцируемое предикатом словарной функции, содержит все автоматы, сводимые к этой словарной функции. В то же время, из незамкнутости z-множества словарной функции следует, что это множество нерегулярно, и для него не существует отвергающий автомат. Пример в Лемме о первой реакции в сериализации также показывает, что для существенно ненулевой словарной функции семейство автоматов, индуцируемое предикатом словарной функции, содержит автомат, несводимый к этой словарной функции. Иными словами, при тестировании нельзя ограничиться только конечными сериализациями, задаваемыми предикатом словарной функции. Заметим, что незамкнутость z-множества словарной функции существенно опирается на бесконечное число автоматов (и их z-множеств), реализующих эту словарную функцию. Здесь дело обстоит аналогично объединению бесконечного множества регулярных множеств конечных слов, которое может быть нерегулярным. С другой стороны, для практических целей всегда можно ограничиться конечным семейством , рассматриваемых z-множеств. В качестве такого семейства можно 57
взять семейство z-множеств автоматов из конечного семейства автоматов , например, автоматов, число состояний которых не превосходит некоторого N. Тогда ={Z[m]|m∈ }. В этом случае, как и следовало ожидать, z-множество словарной функции Z(W, )=∪{Z∈ | W(Z)=W} становится не только замкнутым, но и регулярным, и, следовательно, для него существует отвергающий автомат. Мы докажем теорему аналогичную известной теореме о регулярности объединения конечного числа регулярных множеств конечных слов. Теорема о реализации конечного семейства z-множества с данной словарной функцией: для каждого конечного семейства z-множеств и каждой автоматной словарной функции W существует автомат, z-множество которого совпадает с zмножеством Z(W, ). Доказательство: Для каждого z-множества из , словарная функция которого совпадает с заданной, то есть, для каждого элемента множества {Z∈ | W(Z)=W} выберем автомат, реализующий это z-множество. Требуемый автомат строится как объединение этих автоматов: возьмем копии всех этих автоматов, добавим новое начальное состояние v0, и определим в нем пустые переходы во все копии конечно, начальных состояний этих автоматов. Поскольку множество получившийся автомат также будет конечным и его z-множество, очевидно, совпадает с объединением z-множеств копий автоматов, то есть, с Z(W, ). Теорема доказана. Из этой теоремы непосредственно следует следующая Теорема о предикате словарной функции для ограниченного семейства zмножеств (автоматов): Предикат словарной функции для ограниченного семейства z-множеств (автоматов) индуцирует семейство всех автоматов, сводимых к этой словарной функции.
4. Проблемы тестирования соответствия 4.1. Модель и реализация. Адаптивный алгоритм тестирования Под тестированием в настоящей статье понимается то, что в литературе имеет названия тестирование соответствия (conformance testing или просто test generation), обнаружение ошибок (fault detection) или машинная верификация (machine verification). Модель является способом описания функциональных требований к реализации. Это означает, что реализации, имеющие одну функциональность, не различаются при вынесении вердикта тестирования. Иными словами, модель описывает класс реализаций, имеющих заданную моделью функциональность. Мы предполагаем, что реализация – это реализационный (тестируемый) асинхронный автомат, представляющий собой «черный ящик», о поведении которого мы можем судить по реакциям (выходным словам), выдаваемым им в ответ на тестовые воздействия – входные слова. В первом приближении модель должна описывать словарную функцию реализационного автомата. Будем предполагать, что такое описание задано в виде 58
модельного (спецификационного) автомата, а сам модельный автомат задан явно (например, своим графом состояний). Следует подчеркнуть, что целью тестирования в этом случае является не проверка совпадения модельного и реализационного автомата, а только проверка их эквивалентности, как совпадения реализуемых ими словарных функций. Итак, в первом приближении целью тестирования является проверка того, что тестируемый автомат R имеет словарную функцию W, заданную моделью: W[R]= W. Более детально: • Гипотеза об эквивалентной допустимости: Dom(W[R])=Dom(W) • Условие эквивалентной корректности: ∀w∈Dom(W) W[R](w)=W(w) Если эти условия выполнены, будем говорить об эквивалентности реализации и модели, реализацию будем называть эквивалентной модели. Гипотеза об эквивалентной допустимости является предусловием тестирования, поскольку она не может быть проверена в процессе тестирования, а тестируемым условием (условием, проверяемым тестом) является условие эквивалентной корректности. Следует подчеркнуть, что наше понятие эквивалентности отличается от понятия эквивалентности в [4], где эквивалентность автоматов включает соответствие состояний. Если определить словарную функцию для каждого состояния, рассматриваемого как начальное, то эквивалентность в [4] означает совпадение словарных функций соответствующих состояний, в то время как мы требуем совпадения словарных функций только для начальных состояний. Дело в том, что само соответствие состояний реализации и модели предполагает выход за пределы строгой схемы «черного ящика». Этот выход может происходить по двум направлениям. 1. Гипотезы о реализации. Как правило, при тестировании мы накладываем на возможные реализации некоторые ограничения, которые не проверяются при тестировании, но являются его предусловием. К таким ограничениям относятся ограничения на размер (число состояний) автомата и гипотезы о той или иной степени детерминизма автомата. Введенная нами выше гипотеза об эквивалентной допустимости тоже относится к числу таких гипотез. 2. Дополнительная информация, получаемая в процессе тестирования. Строгая схема «черного ящика» предполагает, что единственная информация, которую мы получаем в процессе тестирования, это выходные слова, выдаваемые автоматом в ответ на подаваемые на него тестом входные слова. Считается, что выполнение автомата по данному входному слову мгновенно, то есть, мы не можем наблюдать выборку стимулов из входной очереди и появление реакций в выходной очереди в процессе выполнения автомата. Это легко объясняется тем, что для любого автомата можно построить другой автомат, который осуществляет предварительную буферизацию воспринимаемых стимулов и, тем самым, задерживает выдачу реакций. Разумеется, такой буфер является расширением состояния автомата и для конечного автомата должен иметь конечный размер, но, если нет ограничений на размер самого автомата, то нет ограничений и на размер этого буфера. 59
Конечно, на практике мы, как правило, имеем возможность в той или иной степени определять относительный порядок во времени воспринимаемых автоматом стимулов и получаемых реакций. Такая информация о сериализациях тестируемого автомата может говорить об ошибке в смысле реализуемой им словарной функции. Например, если для входного слова, начинающегося со стимулов x0x1, словарная функция определяет только такие выходные слова, которые начинаются с реакции y1, а для x0x2 – с y2, то выдача автоматом реакции y1 до приема второго стимула является ошибкой. С другой стороны, мы можем считать, что модель описывает не только словарную функцию, но и возможные сериализации, тем самым накладывая ограничения на реализацию этой словарной функции в тестируемом автомате. В этом случае функциональные требования к тестируемому автомату более жесткие, чем может быть задано самой словарной функцией. Еще одним способом получить дополнительную информацию является наличие специальной операции чтения состояния (status message) тестируемого автомата. Здесь предполагается, что такая операция чтения дает достоверный результат, то есть, не входит в число стимулов, реакцию на которые нужно тестировать. Другим способом является наличие специальной операции сброса автомата в начальное состояние (reset), которая также должна быть достоверна. В этом случае мы имеем информацию о состоянии реализации, по крайней мере, сразу после выполнения такой операции сброса. Тестом на соответствие обычно называют такое входное слово, что по любому полученному от тестируемого автомата выходному слову можно однозначно определить, эквивалентна реализация модели или нет. Это слово называют проверяющим словом (checking sequence). Если такое слово существует, то далее интересуются его длиной для ограниченного (числом состояний и/или переходов) автомата и сложностью алгоритма поиска такого входного слова. В общем виде проблема соответствия очень сложна и здесь мы рассмотрим лишь некоторые более частные проблемы, решение которых необходимо для решения проблемы соответствия . Прежде всего, следует отметить, что входное слово может быть не только заранее заданным (preset sequence), но и вычисляемым в процессе тестирования на основе анализа получаемых реакций. Фактически, такое адаптивное входное слово (adaptive sequence) является алгоритмом тестирования, вычисляющим следующий стимул (или последовательность стимулов) в зависимости от полученных к этому моменту реакций. Рассмотрим тестирование как протяженный во времени процесс подачи стимулов на автомат и получения от него реакций. Во-первых, мы предполагаем, что подаваемый на автомат стимул не «пропадает», то есть, если автомат принимает стимул, то он перед этим принял все предыдущие стимулы. Именно это описывается абстракцией входной очереди. Исключение составляют пустые стимулы, поскольку у нас может не быть возможности точной их реализации, то есть, мы не можем гарантировать, что между двумя непустыми 60
воспринимаемыми стимулам автомат воспримет ровно столько пустых стимулов, сколько мы хотим. Эта проблема обсуждается ниже. Пока будем предполагать, что пустые стимулы реализованы точно. Во-вторых, мы предполагаем, что в процессе подачи на автомат стимулов мы имеем возможность получать выдаваемые автоматом реакции одну за другой так, что в каждый момент времени последовательность уже полученных реакций представляет собой начало выходного слова, выдаваемого автоматом. Адаптивный алгоритм тестирования для словарной функции W можно представить себе в виде последовательности шагов. На каждом i-ом шаге на автомат подается некоторое квази-конечное входное слово wieω, и в какой-то момент времени после подачи последнего непустого стимула мы обнаруживаем, что получили конечное выходное ui. На первом шаге, слово w1eω должно быть допустимо и проверяется, что u1 может быть началом возможного выходного слова, то есть, существует u∈W(w1eω) такое, что u1≤u. Второй шаг мы начинаем, когда имеется неопределенность в числе концевых пустых стимулов первого входного слова, то есть, когда реально на автомат подано некоторое конечное входное слово вида wie*. Предполагается, что допустимо любое входное слово вида w1e*w2eω, и проверяется, что, по крайней мере, для некоторых из них u1u2 может быть началом возможного выходного слова. В целом, если тестирование завершается после k-го шага, то должно быть допустимо любое входное слово вида u1e*u2e*…uie*…ukeω, и проверяется, что, по крайней мере, для некоторых из них слово u1u2…ui…uk является началом возможного выходного слова. Сначала рассмотрим две проблемы избыточности: проблема избыточности реализации (реализационного входного домена) и проблема избыточности модели (модельной словарной функции).
4.2. Проблема избыточности реализации Проблема избыточности реализации (реализационного домена): Реализация, делающая все то, что она должна делать в соответствии с функциональностью, заданной моделью, может допускать входные воздействия, не описываемые моделью. Как правило, при тестировании не ставится задача проверки того, что делает реализация для этих немоделируемых тестовых воздействий. В терминах автомата и его словарной функции это означает: при тестировании мы подаем на тестируемый автомат только те входные слова, которые допустимы в модели, хотя реализация может допускать и другие входные слова. Будем говорить, что реализационный автомат R частично эквивалентен модельной словарной функции W, если выполнены следующие два условия: • Гипотеза о частичной допустимости: Dom(W[R])⊇Dom(W) • Условие эквивалентной корректности: ∀w∈Dom(W) W[R](w)=W(w) Гипотеза о частичной допустимости является предусловием тестирования, поскольку она не может быть проверена в процессе тестирования, а тестируемым условием является условие эквивалентной корректности. В дальнейшем, по 61
умолчанию, под "гипотезой о допустимости" мы будем понимать именно "гипотезу о частичной допустимости". Заметим, что наше понятие частичной эквивалентности аналогично понятию квази-эквивалентности в [3].
4.3. Проблема избыточности модели Проблема избыточности модели (модельной словарной функции): Модель описывает множество возможных поведений реализации при заданном допустимом воздействии на нее. В терминах автомата и его словарной функции это означает, что значение словарной функции на данном входном слове является множеством выходных слов. Если это множество состоит более, чем из одного выходного слова, это означает, что модель разрешает реализации выдавать любое из этих выходных слов. Однако, мы не можем требовать, чтобы реализация для каждого возможного выходного слова имела выполнение, выдающее это слово. Во-первых, это невозможно проверить, если единственный способ воздействия на реализацию – ввод входного слова. Если для данного входного слова возможных выходных слов несколько, то выбор того или иного выходного слова в автомате, по определению, недетерминирован. Эта проблема обсуждается в следующем разделе. Во-вторых, функциональность обычно понимается как раз в том смысле, что реализация может выдавать любое из возможных выходных слов. Это означает, что значение словарной функции реализационного автомата на данном допустимом входном слове должно быть вложено в значение модельной словарной функции на этом же входном слове, но не обязано совпадать с ним. Будем говорить, что реализационный автомат R сводим к модельной словарной функции W, если выполнены следующие два условия: • Гипотеза о частичной допустимости: Dom(W[R])⊇Dom(W) • Условие частичной корректности: ∀w∈Dom(W) W[R](w)⊆W(w) Тестируемым условием является условие частичной корректности. В дальнейшем, по умолчанию, под "условием корректности" мы будем понимать именно "условие частичной корректности".
4.4. Проблема недетерминизма Проблема недетерминизма словарной функции. Как было сказано выше, условие корректности в полном объеме невозможно проверить. Если для данного входного слова возможных выходных слов несколько, то выбор того или иного выходного слова в автомате, по определению, недетерминирован. Поэтому сколько бы раз мы не подавали на тестируемый автомат данное допустимое входное слово и получали возможное (соответствующее модели) выходное слово, у нас не может быть гарантии, что при следующей попытке будет выдано также возможное выходное слово. Поэтому предполагается выполненной следующая • Гипотеза об однородности недетерминизма: Если автомат для допустимого входного слова выдает возможное выходное слово, то он это делает всегда, то есть, значение словарной функции автомата на этом 62
входном слове состоит только из возможных слов: ∀w∈Dom(W) ∃u∈W[R](w)∩W(w) ⇒ W[R](w)⊆W(w). Если гипотезы о допустимости и однородности недетерминизма верны, то для проверки сводимости реализации к модели достаточно проверить следующее тестируемое • Условие однократной корректности: ∀w∈Dom(W) первое же выданное реализацией выходное слово u∈ W(w).
4.5. Проблема бесконечности модельного домена Проблема бесконечности модельного домена. Домен модельной словарной функции, вообще говоря, является бесконечным и поэтому проверка тестируемого условия "в лоб", то есть, для каждого слова из домена, не может быть выполнена за конечное время. Чтобы обойти эту проблему, определяют покрытие домена – конечное множество подмножеств домена Coverage⊆2Dom(W) такое, что ∪Coverage=Dom(W). Элементы покрытия называются областями. При этом предполагается выполненной следующая гипотеза: • Гипотеза об однородности покрытия: для каждой области покрытия, если тестируемое условие выполнено для некоторого элемента области, то оно выполнено для всех элементов области: ∀C∈Coverage (∃w∈C W[R](w)⊆W(w)) ⇒ ∀w`∈C W[R](w`)⊆W(w`). Если гипотезы о допустимости и однородности покрытия верны, то для проверки сводимости реализации к модели достаточно проверить следующее тестируемое условие: • Условие выборочной корректности: ∀C∈Coverage для первого подаваемого на реализацию входного слова w∈C W[R](w)⊆W(w). Если задано покрытие Coverage и верны гипотезы о допустимости, однородности недетерминизма и однородности покрытия, то для проверки сводимости реализации к модели достаточно проверить следующее тестируемое условие: • Условие выборочной однократной корректности: ∀C∈Coverage для первого подаваемого на реализацию входного слова w∈C выданное реализацией выходное слово u∈ W(w).
4.6. Итерация входных слов Тестирование есть последовательность шагов тестирования, на каждом из которых осуществляется подача на тестируемый автомат входного слова w, получение выходного слова u и проверка того, что u∈W(w). Здесь возникает проблема перебора входных слов, подаваемых тестом на шагах тестирования. Если задано покрытие Coverage и верна гипотеза об однородности покрытия, достаточно перебрать хотя бы по одному входному слову из каждой области покрытия. 63
Для этого определяют конечное итерируемое множество Iterate⊆Dom(W), содержащее, по крайней мере, по одному элементу из каждой области покрытия, то есть, {C∈Coverage|Coverage∩Iterate≠∅}=Coverage. Итерация входных слов осуществляется как перебор элементов итерируемого множества. Итерируемое множество на практике удобнее задавать избыточным в том смысле, что его собственное подмножество также является итерируемым множеством для данного покрытия. Эту избыточность можно уменьшить, используя фильтрацию. Пусть: • итерируемое множество упорядочено (перенумеровано) Iterate={w[i]|i=1..n}; • покрытие также упорядочено (перенумеровано) Coverage={C[j]|j=1..m}; • для каждой области C[j]∈Coverage определен предикат на итерируемом множестве P[j] ≡ w∈C[j]. Введем массив булевских переменных B длиной m, инициализированных false. Отфильтрованная последовательность входных слов FilterIterate вычисляется следующим образом. Итерируя множество Iterate, для каждого входного слова w из Iterate перебираем все области покрытия C[j], для которых B[j] равно false, и с помощью предиката P[j] определяем, принадлежит ли w соответствующей области. Для каждой перебираемой области C[j], если w∈C[j], то устанавливаем B[j]:=true. Если это произошло хотя бы один раз (w принадлежит хотя бы одной перебираемой области), то помещаем w в отфильтрованную последовательность FilterIterate.
4.7. Проблема бесконечных входных слов По существу, эту проблему мы изучали в части 3. Хотя словарная функция определяется на бесконечных входных словах, поскольку это удобная математическая абстракция, однако, при тестировании приходится иметь дело только с конечными словами. Конечное входное слово можно понимать как бесконечное слово, в котором имеется только конечное число непустых стимулов; такие бесконечные слова мы назвали квази-конечными. Пустые стимулы, расположенные во входном слове до последнего непустого стимула моделируют «паузы» между последовательными непустыми стимулами, а бесконечная последовательность пустых стимулов после последнего непустого стимула – конец слова, то есть, завершение подачи стимулов на автомат в данном тестовом эксперименте. Мы выяснили, что словарная функция автомата, вообще говоря, не восстанавливается однозначно по своему квази-конечному сужению. В этой ситуации можно: 1) ограничиться такими классами автоматов, для которых словарная функция однозначно определяется ее квази-конечным сужением, или 2) такими функциональными требованиями к автомату, которые могут быть сформулированы в терминах квази-конечного сужения словарной функции, то есть, проверять поведение автомата только на квази-конечных входных словах и, если на таких словах оно правильно, то делать вывод, что реализация 64
соответствует модели. В этих случаях мы как бы не обращаем внимание на поведение автомата на «настоящих», содержащих бесконечное число непустых стимулов, входных словах. В то же время, поведение автомата на таких «настоящих» входных словах может оказаться существенным с точки зрения функциональных требований к автомату. Обычно программные или аппаратные системы прекращают выдачу реакций, если в течении длительного времени на них не поступают (непустые) стимулы, но существуют системы с «инвертированным» поведением, которые, наоборот, не выдают реакций, если стимулы периодически поступают, а при длительном их отсутствии начинают выдавать «аварийные» реакции, сигнализирующие об обрыве потока стимулов. В этом случае можно попробовать использование некоторого предиката на конечных сериализациях и информации о сериализациях, возникающих при работе автомата для тестовых воздействий. Мы показали, что, если функциональные требования настолько жесткие, что описывают не только словарную функцию, но и множество вполне допустимых сериализаций автомата, то такой предикат можно использовать для проверки получаемых при тестировании сериализаций. Однако, если предикат описывает, фактически, саму словарную функцию, то есть, допускает все сериализации, которые могут возникнуть при работе любого автомата с данной словарной функцией, то в общем случае такой предикат не сможет отвергнуть поведение некоторых автоматов с другой словарной функцией. В то же время, если ограничиться конечным семейством автоматов (например, автоматами с ограниченным числом состояний), то проблема может быть решена. Если у нас не задана словарная функция, а только предикат p конечных сериализаций (неважно, что это может быть, например, предикат некоторой словарной функции или предикат z-множества, определяющего словарную функцию), то тестирование производится на основе этого предиката следующим образом: • в качестве конечного входного слова wt выбираются x-подслово xz конечной сериализации z допускаемой предикатом: z∈U(p) wt=xz; • для полученной в тестовом эксперименте конечной сериализации zt (xzt=wt) проверяется, что она допускается предикатом: zt∈U(p). Если же у нас задана как словарная функция W, так и предикат p конечных сериализаций, то последний рассматривается как дополнение к словарной функции, то есть, используется только для уточнения сериализации пары (входное слово, выходное слово), удовлетворяющей словарной функции. Более детально тестовый эксперимент строится по следующей схеме: • в качестве конечного входного слова wt выбирается начальный отрезок входного слова w из домена словарной функции: w∈Dom(W) wt<w; • из полученной в тестовом эксперименте конечной сериализации zt (xzt=wt) выбирается конечное выходное слово - y-подслово yzt и 65
проверяется, что оно удовлетворяет словарной функции: ∃w`∈Dom(W) ∃u∈W(w`) wt<w` yzt
Дополнительный частичный порядок, таким образом, связывает стимулы и реакции. В рассмотренном выше примере первая реакция находится не раньше 2го и не позже 5-го стимула. Этот дополнительный частичный порядок индуцирует множество Zt линейных порядков, не противоречащих ему.
4.8. Проблема пустых стимулов Пустой стимул является абстракцией, моделирующей пустоту входной очереди в момент ее опроса автоматом в рецептивном состоянии. Теперь возникает проблема реализации этой абстракции, то есть, реализации пустого стимула. Понятно, что реализовать бесконечную последовательность пустых стимулов после последнего непустого стимул легко: надо просто перестать подавать стимулы на автомат. Труднее реализовать неконечные пустые стимулы, моделирующие «паузы» различной длительности (измеряемой в числе пройденных рецептивных состояний) между последовательными непустыми стимулами.
4.8.1. Перехват операции receive Простейший способ реализации пустого стимула основан на перехвате тестовой системой обращения автомата к входной очереди в рецептивном состоянии. Будем считать, что такое обращение реализуется операцией receive, возвращающей головной стимул, если очередь не пуста, или сообщающей об отсутствии стимула, если очередь пуста. Заметим, что асинхронный автомат отличается от классического автомата Мили, в частности, тем, что для последнего используется receive с ожиданием и поэтому автомату не сообщается об отсутствии стимула. Если по операции receive автомат попадает в тест, то сам тест возвращает очередной стимул входного слова, если этот стимул непуст, или сообщает о пустоте очереди, если этот стимул пуст. Недостатком этого способа является то, что подобной возможности перехвата операции receive может не быть. В этом случае возможны три варианта: 1) ограничиться такими автоматами, поведение которых не зависит от наличия или отсутствия пустых стимулов во входном слове; 2) ограничиться такими входными словами, которые можно реализовать; 3) применять "нечеткие" входные слова, в которых число пустых стимулов в нужных местах может быть определено лишь с некоторой степенью точности и, соответственно, ограничиться такими автоматами, в которых любое из точных слов, соответствующих нечеткому входному слову, допустимо.
4.8.2. Серийное тестирование без пауз и стационарное тестирование Среди допустимых квази-конечных входных слов есть два крайних подмножества слов, которые могут быть реализованы при некоторых предположениях:
67
1.
Квази-конечные входные слова без пустых стимулов, точнее, слова, в которых все пустые стимулы располагаются после последнего непустого стимула. Множество таких слов X*^{eω}. 2. Квази-конечные входные слова, в которых между любыми последовательными непустыми стимулами располагается достаточно большое число пустых стимулов. Подмножество 1 может быть реализовано в предположении, что тест успевает подать на автомат следующий непустой стимул до того, как автомат захочет его прочитать. Такое тестирование будем называть серийным тестированием без пауз. Если тест и автомат реализованы процессами на одном процессоре, то достаточно, чтобы процесс теста имел больший приоритет, чем процесс автомата. В этом случае тест поместит во входную очередь все непустые стимулы и только после этого начнет работать процесс автомата. Если же тест и автомат реализованы процессами на разных процессорах, то, по-видимому, нужно, чтобы процессор теста был достаточно быстрый по сравнению с процессором автомата: цикл теста по посылке одного непустого стимула должен выполняться быстрее, чем переход автомата, ограниченный сверху максимальным временем срабатывания τ. Есть и другой способ реализации подмножества 1. Для этого достаточно, чтобы работа автомата начиналась с его начального состояния после того, как тест поместил во входную очередь все непустые стимулы входного слова. Иными словами, предполагается, что автомат начинает свою работу с начального состояния по специальному стартовому сигналу, который тест подает после помещения во входную очередь всех непустых стимулов. Подмножество 2 имеет смысл для автоматов класса A5, в которых любое квазиконечное слово переводит автомат в терминальное состояние или принимающее состояние без e-переходов в другие состояния (есть только e- петля); такие состояния будем называть стационарными. Такой автомат класса A3 – это, очевидно, автомат, в котором каждый циклический маршрут, кроме e-петель, содержит x-переходы, то есть, прием стимулов. В стационарном состоянии автомат либо останавливается, либо ожидает поступления непустого стимула. В этом случае следующий непустой стимул подается на автомат после его перехода в стационарное нетерминальное состояние. Такое тестирование будем называть стационарным. Какое время тест должен выждать прежде, чем подать следующий непустой стимул? Очевидно, это время ограничено сверху максимальным временем перехода автомата по предыдущему непустому стимулу плюс время прохождения в стационарное состояние по маршруту, содержащему только пустые, посылающие и e-переходы. Поскольку нет циклов из таких переходов, кроме eпетель, максимальная длина такого пути равна n-1, где n – число состояний автомата. Следовательно, тайм-аут между последовательными непустыми стимулами можно установить равным τ+(n-1)τ=nτ, где τ – максимальное время срабатывания автомата. 68
4.8.3. Автоматы с однородным поведением Можно не беспокоиться о реализации пустых стимулов, если тестируемый автомат обладает следующим свойством. Однородное поведение: Если словарная функция W автомата определена на слове w, то она определена также на любом слове w`, полученном из w удалением и/или добавлением в произвольные места произвольного конечного числа пустых стимулов, и принимает на нем то же значение W(w`)=W(w). Автоматы, обладающие этим свойством будем называть автоматами с однородным поведением, а класс таких автоматов обозначим A6. Мы уже изучали подкласс A6 – класс A0 – автоматы без смешанных состояний и e-переходов. Если привести эти автоматы к классу A3, то отсутствие e-переходов превращается в отсутствие e-переходов, не являющихся петлями. Иными словами, автоматы класса A0 – это автоматы без смешанных состояний, в которых все e-переходы - это петли в принимающих состояниях. Вместе с тем, свойство независимости словарной функции от вставки и удаления пустых стимулов не является характеристическим для класса A0, то есть, класс автоматов, обладающих этим свойством, не совпадает с классом A0: A0⊂A6. Пример приведен на Рис. 31; в этом автомате нарушается свойство 3 автомата класса A0: слово x1eω допустимо, слово x1x1eω недопустимо, однако, W(x1eω)={(yω)} не содержит конечного выходного слова.
Рис. 31 Здесь представляют интерес следующие две пока не решенные задачи: 1. Описать класс автоматов с однородным поведением A6. 2. Рассмотреть подкласс A6`⊂A6, в котором для всех квази-конечных входных слов выходные слова конечны. Есть гипотеза, что этот подкласс является также подклассом A0: A6`⊂A0⊂A6. При тестировании автоматов класса A6 мы имеем непроверяемую во время тестирования гипотезу об однородном поведении, и подаем квази-конечные слова с теми пустыми паузами между непустыми стимулами, которые получатся. Отдельный интерес представляет тестирование с варьированием длительности этих пауз, разумеется без гарантии (и не ставя такую цель) перебрать все возможные длительности.
4.8.4. Автоматы с однородной допустимостью Требование к автомату, определяющее класс A6 автоматов с однородным поведением, может быть ослаблено: 69
Однородная допустимость: Если словарная функция W автомата определена на слове w, то она определена также на любом слове w`, полученном из w удалением и/или добавлением в произвольные места произвольного конечного числа пустых стимулов. Автоматы, обладающие этим свойством, будем называть автоматами с однородной допустимостью, а класс таких автоматов обозначим A7⊃A6. Иными словами, для автоматов с однородной допустимостью A7, в отличии от автоматов с однородным поведением A6, не требуется, чтобы, словарная функция на входных словах w и w`, отличающихся только наличием или отсутствием конечного числа пустых стимулов, принимала одно и то же значение W(w`)=W(w), а только одинаковая допустимость этих слов. Тестирование таких автоматов основано на предположении, что при попытке подать на автомат допустимое входное слово w, выдавая стимул за стимулом и делая «паузы» для пустых стимулов, реально автомат может получить не слово w, а слово w`, которое, тем не менее, также допустимо. Поскольку не известно, какое именно входное слово получил автомат, при получении выходного слова u мы проверяем по словарной функции все пары слов (w`,u), где w` отличается от w конечным числом пустых стимулов. Если хотя бы одна такая пара удовлетворяет словарной функции, то, по "презумпции невиновности", считаем, что автомат выполнялся правильно. В определении свойства однородной допустимости говорилось о добавлении или удалении конечного числа пустых стимулов. Покажем, что это ограничение можно снять: 1) разрешается удалять бесконечное число пустых стимулов, но так, чтобы слово оставалось бесконечным; 2) разрешается вставлять бесконечное число стимулов, причем, если бесконечное число стимулов вставляется в одно место, то последующие стимулы исчезают. Вообще, для квази-конечных слов снятие ограничения ничего не дает, однако, для «настоящих» бесконечных слов это существенно; в частности вставкой бесконечного числа пустых стимулов после некоторого непустого стимула мы превращаем его в квази-конечное слово. Доказательство будем вести от противного. Пусть в автомате с однородной допустимостью слово w допустимо, а слово w`, полученное из него вставкой или удалением произвольного числа пустых стимулов, недопустимо. Тогда при некотором выполнении автомата по входному слову w` фиксируется ошибка неспецифицированного ввода. В этот момент, очевидно, автомат прочитал из входной очереди начальный отрезок входного слова конечной длины w`[1..n], который соответствует некоторому отрезку w[1..m], то есть, получен из него вставкой и/или удалением конечного числа пустых стимулов. Но тогда это выполнение возможно также для входного слова w``=w`[1..n]^w[m+1..], которое отличается от w конечным числом пустых стимулов, то есть, слово w`` недопустимо, что противоречит свойству однородной допустимости. Для словарной функции с однородной допустимостью W можно определить производную словарную функцию E(W) как объединение значений W на всех 70
бесконечных словах, отличающихся от данного добавлением или удалением любого числа пустых стимулов: • Dom(E(W))=Dom(W) • ∀w∈Dom(E(W)) E(W)(w)=∪{ W (w`)|w`∈E(w)} - здесь E(w) - множество бесконечных слов, получаемых из w добавлением и/или удалением любого числа пустых стимулов. Фактически, при тестировании мы будем проверять, что тестируемый автомат сводим не к исходной, а к производной словарной функции. Производная словарная функция E(W), очевидно, уже является однородной по поведению. Как по автомату с однородной допустимостью класса A3, реализующему словарную функцию W, построить автомат, реализующий производную словарную функцию E(W)? Это можно сделать следующей процедурой (Рис. 32): 1. Вставка пустых стимулов. Добавим до и после каждого принимающего перехода по непустому стимулу (v,x,v`) произвольное число e-переходов: добавляем три новых состояния v1, v2, и v3, определяем в них e-петли (vi,e,vi), i=1,2,3, в состоянии v определяем x-переход (v,x,v1) и e-переходы (v,e,v2) и (v,e,v3), в состоянии v1 определяем e-переход (v1,e,v`), в состоянии v2 определяем x-переход (v2,e,v`), а в состоянии v3 определяем x-переход (v2,e,v1). 2. Удаление пустых стимулов. Для каждого e-перехода (v,e,v`), где v≠v`, сдублируем каждый переход в состояние v на переход в состояние v`: для e-перехода (ve,e,v) добавим переход (ve,e,v`), для x-перехода (vx,x,v) добавим переход (vx,x,v`), для y-перехода (vy,y,v) добавим переход (vy,y,v`).
Рис. 32 На домене однородной по поведению словарной функции можно определить отношение эквивалентности E⊆Dom(E(W))2: (w,w`)∈E, если w`∈E(w). 71
Однородность по поведению как раз и означает, что словарная функция принимает одинаковые значения на эквивалентных входных словах. После этого можно определить словарную фактор-функцию F(W): • Dom(F(W))=E(Dom(W)), где E(Dom(W)) - множество классов эквивалентности E • ∀W∈Dom(F(W)) F(W)(W)=E(w), где w∈W Каноническим входным словом будем называть такое входное слово, в котором за пустым стимулом, если он есть, следуют только пустые стимулы. Множество канонических входных слов – это (X*^{eω})∪Xω, где X*^{eω} - множество канонических квази-конечных слов, а Xω - множество остальных канонических слов - бесконечных слов без пустых стимулов. Нас будет интересовать не столько фактор-функция, сколько каноническая словарная функция C(W), определенная на канонических представителях классов эквивалентности допустимых слов: • Dom(C(W)) = ((X*^{eω})∪Xω) ∩ Dom(W) • ∀w∈Dom(C(W)) C(W)(w)=E(w) Фактически, при тестировании мы будем проверять, что тестируемый автомат сводим к канонической словарной функции. Более точно: мы будем подавать на автомат канонические входные слова, автомат при этом будет получать возможно другое входное слово, но из того же класса эквивалентности, а выходное слово мы будем проверять по канонической словарной функции. При этом мы будем предполагать, что выполнены непроверяемые при тестировании • Гипотеза об однородной допустимости: Словарная функция тестируемого автомата является однородно допустимой. • Гипотеза об однородной корректности: Если автомат правильно себя ведет на некотором входном слове, то он правильно себя ведет на всем классе эквивалентности (по вставке и/или удалению пустых стимулов) этого входного слова. Эти гипотезы, тем самым, предполагают некоторое предопределенное покрытие домена, а именно – разбиение на классы эквивалентности E. Всякое дополнительное покрытие будет, фактически, покрытием фактор-домена, то есть, множества классов эквивалентности E. Представляет интерес представление в модели канонической словарной функции. Как по автомату с однородной допустимостью класса A3, реализующему производную словарную функцию E(W), построить автомат, реализующий каноническую словарную функцию C(W)? Это можно сделать следующей процедурой: 1. Скопировать автомат и в копии удалить все x-переходы (принимающие переходы по непустым стимулам). Копию состояния v будем снабжать индексом – vc. 2. Каждый e-переход (v,e,v`) заменим на e-переход (v,e,v`c), определенный в том же состоянии-оригинале v, но ведущий в постсостояние-копию v`c. 72
Иными словами, первый же e-переход переводит нас в автомат-копию, где далее мы совершаем только пустые, посылающие и e-переходы. Поскольку тестирование мы проводим только на квази-конечных словах, все предыдущие рассуждения, вообще говоря, следовало бы скорректировать с учетом этого. В частности, эквивалентными квази-конечному слову считать только квази-конечные слова и соответствующим образом определять производную, фактор- и каноническую словарные функции.
4.9. Проблема выходных слов Следующая проблема тестирования – это проблема выходных слов, распадающаяся на две проблемы: 1. Сколько времени мы должны ожидать получения очередной реакции? 2. Сколько времени мы должны получать и проверять реакции, чтобы убедиться, что полученное конечное выходное слово достаточно «репрезентативно», то есть, является возможным выходным словом или достаточно большим начальным отрезком возможного бесконечного выходного слова?
4.9.1. Тайм-аут на ожидание очередной реакции Тайм-аут на ожидание реакции не следует понимать так, что, если в течении этого времени реакция не поступила, то она никогда не поступит. При наличии циклов по пустым и e-переходам, в которые мы можем попасть после выборки из входной очереди всех непустых стимулов квази-конечного входного слова, а также при наличии циклов по пустым переходам еще до выборки последнего непустого стимула, очередная реакция может быть выдана после прохождения любого числа раз по таким циклам. Однако, в этом случае существует и такое выполнение, когда автомат не выходит из такого цикла, бесконечно двигаясь по нему и не выдавая реакций. Поэтому тайм-аут предлагается понимать так, что, если за это время не поступила очередная реакция, то возможно такое выполнение, при котором она и не поступит. Если такое выполнение удовлетворяет словарной функции, то можно не ожидать реакции сверх таймаута, поскольку это ожидание может продолжиться бесконечно. С другой стороны, если очередная реакция, согласно словарной функции, должна поступить обязательно, то тайм-аут должен быть больше времени максимального времени ожидания такой обязательной реакции. Определим формально понятие обязательной реакции. Будем говорить, что для входного квази-конечного слова w и выходного слова u∈W(w) i-ая реакция, где i≤nu, обязательна, если слово u[1..i-1]∉W(w). Определение тайм-аута тесно связано со следующими ограничениями: • Максимальное время срабатывания автомата – τ. Если бы такого ограничения не было, то, очевидно, не было бы ограничения и на время ожидания очередной обязательной реакции. 73
•
Ограничение на размер автомата, точнее, число состояний автомата ограничено сверху числом n. Действительно, если такого ограничения нет, то перед любым переходом посылающим обязательную реакцию можно было бы вставить цепочку из любого конечного числа пустых переходов с ненулевым временем срабатывания и, тем самым, в полученном автомате превысить любое наперед заданное время ожидания обязательной реакции. Будем считать, что автомат приведен к классу A2. Обозначим число принимающих состояний ns и число посылающих состояний nr. n=ns+nr. Обозначим через s число стимулов во входном квази-конечном слове w до последнего непустого стимула включительно. Теорема о времени ожидания обязательной реакции: Время ожидания обязательной реакции не превосходит ((s+1)nr+ns)τ. Доказательство: Пусть P - один из маршрутов выполнения для допустимого входного слова w. Обозначим через Pi отрезок P между i-1-ым и i-ым посылающим переходами, то есть, для некоторых индексов a и b Pi=P[a..b], P[a1] - i-1-ый посылающий переход (при i=1 a=1) и P[b+1] - i-ый посылающий переход. Считая, что i-ая реакция может быть послана в конце прохождения i-ого посылающего перехода, нам следует показать, что, если i-ая реакция обязательна, то максимальная длина отрезка Pi (до i-ого посылающего перехода) не превосходит (s+1)nr+ns-1. Рассмотрим три случая: 1) Последний непустой стимул принимается автоматом до отрезка Pi, то есть, начальный отрезок P[1..a-1] содержит s принимающих переходов. В частности, это имеет место при s=0, то есть, w=eω. Очевидно, Pi содержит только пустые и e-переходы. Поскольку i-ая реакция обязательна, Pi не должен содержать цикла из пустых и e-переходов. Следовательно, его длина не превосходит n-1=nr+ns-1. 2) Последний непустой стимул принимается автоматом после отрезка Pi, то есть, начальный отрезок P[1..b] содержит меньше, чем s, принимающих переходов. В этом случае, Pi содержит пустые и принимающие переходы. Поскольку i-ая реакция обязательна, Pi не должен содержать цикла из пустых переходов. Такой цикл мог бы находиться только между двумя последовательными принимающими переходами, значит, между ними не может быть больше чем nr-1 переходов. Число принимающих переходов в Pi не превосходит s-1. Учитывая пустые переходы до первого принимающего перехода в Pi и пустые переходы после последнего принимающего перехода в Pi, получаем, что число пустых переходов в Pi не превосходит s(nr-1). Общая длина Pi не превосходит (s-1)+s(nr-1)=snr1. 3) Последний непустой стимул принимается автоматом внутри отрезка Pi. В этом случае, Pi содержит пустые и принимающие переходы. Поскольку i-ая реакция обязательна, Pi не должен содержать цикла из пустых переходов и, после приема последнего непустого стимула, - цикла из 74
пустых и e-переходов. Цикл из пустых переходов мог бы находиться только между двумя последовательными принимающими переходами, значит, между ними не может быть больше чем nr-1 дуг. Число принимающих переходов в Pi не превосходит s. Учитывая пустые переходы до первого принимающего перехода в Pi, получаем, что до приема последнего непустого стимула Pi содержит число пустых переходов не превосходящее s(nr-1), а всего переходов до приема последнего непустого стимула включительно не более s+s(nr-1)=snr. После приема последнего непустого стимула Pi содержит только пустые и e-переходы, число которых не может превосходить n-1=nr+ns-1. Следовательно, общая длина Pi не превосходит snr+nr+ns-1=(s+1)nr+ns-1. Для случая 1), поскольку s≥0, имеем nr+ns-1≤(s+1)nr+ns-1. Для случая 2), поскольку s≥0 и ns≥0, имеем snr-1≤(s+1)nr-1≤(s+1)nr+ns-1. Теорема о времени ожидания обязательной реакции доказана. Пример на Рис. 33 дает оценку снизу ((s+1)nr+1)τ для времени ожидания первой реакции, что совпадает с верхней оценкой при ns=1.
Рис. 33 Для необязательной реакции время ее ожидания, естественно, может быть сколь угодно большим (бесконечным для выполнения без выдачи реакции). С другой стороны, полученная нами оценка дает также максимальное время ожидания необязательной реакции при условии, что она будет выдана и маршрут выполнения не проходит по циклам из пустых переходов и, после приема последнего непустого стимула, по циклам из пустых и e-переходов. Однократный проход по циклу пустых переходов занимает время не большее nrτ. Однократный проход по циклу пустых и e-переходов занимает время не большее (nr+ns) τ=nτ>nrτ. Таким образом, время ожидания необязательной реакции при условии, что маршрут выполнения проходит не более k раз по циклам пустых и eпереходов, не превосходит ((s+1)nr+ns)τ+knτ. Задавая число k, мы, тем самым, можем тестировать автомат при всех выполнениях, при которых проходятся не более k раз циклы пустых и e-переходов. Для остальных выполнений у нас должна быть сформулирована 75
•
гипотеза о необязательных реакциях: если автомат правильно себя ведет при числе проходов по циклам пустых и e-переходов не превосходящем k, то и при остальных выполнениях он также ведет себя правильно.
4.9.2. Время ожидания репрезентативного выходного слова Согласно словарной функции W выходное слово u возможное для входного слова w может оказаться бесконечным. Естественно, при тестировании мы не можем ждать бесконечное время, чтобы получить это бесконечное выходное слово. В таком случае нам хотелось бы гарантированно получить хотя бы те реакции, которые выдаются до того, как автомат выбрал последний непустой стимул, плюс еще те реакции, которые он может выдать после этого до попадания в цикл по посылающим, пустым и e-переходам (после приема последнего непустого стимула во входном слове остаются только пустые стимулы). Иными словами, мы хотим, чтобы автомат прошел начальный отрезок маршрута выполнения, содержащий прием всех непустых стимулов (или всех тех непустых стимулов, после приема которых он вообще перестает выбирать стимулы из входной очереди) и после этого содержащий цикл по посылающим, пустым и e-переходам. Естественно, что, если на таком отрезке маршрута имеются циклы по пустым переходам, то время ожидания последующей реакции может быть сколь угодно большим. Но в этом случае такая реакция необязательна и мы ее можем никогда не получить. До приема последнего непустого стимула включительно, при условии, что не встречаются циклы по пустым переходам, автомат выполнит не более snr переходов. После этого до "зацикливания" автомат выполнит не более nr+ns переходов. Тем самым, всего получается время ожидания ((s+1)nr+ns)τ, совпадающее с тайм-аутом на ожидание обязательной реакции, что и следовало ожидать. Мы можем увеличить это время, допуская, чтобы циклы проходились не более k1 раз: ((s+1)nr+ns)τ + k1nτ. Алгоритм тестирования получается такой: 1) На весь шаг тестирования (на все квази-конечное входное слово) устанавливается время ожидания τ1=((s+1)nr+ns)τ+k1nτ. 2) На ожидание каждой реакции также устанавливается тайм-аут τ0=((s+1)nr+ns)τ+k0nτ. 3) Если очередная i-ая реакция u[i] принята до истечения тайм-аута τ0, то она проверяется по словарной функции: u[1..i]∈W(w). a. Если реакция неправильная, фиксируется ошибка. b. Если реакция правильная и время τ1 не истекло, то ожидаем следующую реакцию – п.2. c. Если реакция правильная и время τ1 истекло, то – п.5. 4) Если очередная i-ая реакция u[i] не принята до истечения тайм-аута τ0, то проверяется, что она необязательна: u[1..i-1]∉W(w). 76
a. b.
Если реакция обязательная, то фиксируется ошибка. Если реакция необязательна, то дожидаемся истечения времени τ1 или появления реакции. i. Если появилась необязательная i-ая реакция u[i], то она проверяется по словарной функции: u[1..i]∈W(w). Далее пп.3a,3b,3c. ii. Если время τ1 истекло, то – п.5. 5) Время τ1 истекло. Дальше ждать бессмысленно: время ожидания может быть бесконечным. Заканчиваем шаг тестирования, предполагая ("презумпция невиновности"), что реакции, которые поступят позже (быть может, бесконечное число реакций), правильные.
4.9.3. Автоматы с конечными выходными словами для квази-конечных входных слов Естественный интерес представляют автоматы, в которых для каждого квазиконечного входного слова все выходные слова конечны. Заметим, что это свойство есть свойство самой словарной функции автомата. Легко показать, что необходимым и достаточным условием того, что автомат класса A2 обладает этим свойством, является следующее условие: в автомате нет циклов, которые содержали бы посылающие переходы и не содержали бы x-переходов (принимающих переходов по непустым стимулам).
4.10. Проблема постсостояния Шаг адаптивного тестирования заключается в подаче на реализационный автомат квази-конечного входного слова, получения выходного слова (дополнительно, возможно, множества сериализаций) и анализа как с целью определения правильности полученных реакций, так и с целью определения в зависимости от них следующего квази-конечного входного слова. До сих пор мы предполагали, что в начале каждого шага реализационный автомат находится в начальном состоянии. Однако, в конце шага автомат может оказаться в другом состоянии и поэтому мы должны либо: 1) перевести автомат в начальное состояние, либо: 2) следующий шаг тестирования начинать не в начальном состоянии. 1. Для перевода автомата в начальное состояние v0 обычно предполагается существование специальной операции reset. Ее можно рассматривать как особый стимул автомата, который допустим в каждом состоянии v для принимающего перехода (v,reset,v0). 2. Если для автомата нет операции reset, мы вынуждены следующий шаг тестирования начинать в том состоянии (постсостоянии), в которое автомат попадает в конце предыдущего шага. Иногда это приходится делать и при наличии операции reset, например, если она слишком дорогая (по времени выполнения) или допустима не во всех состояниях. Соответственно, понятия входного слова, выходного слова, выполнения автомата, сериализации и маршрута используются не только для начального состояния, но и для любого 77
состояния автомата. Точно также словарная функция может быть определена для любого состояния. По окончании шага тестирования мы должны, прежде всего, идентифицировать постсостояние. Заметим, что в общем случае таких возможных постсостояний может быть несколько и в каком именно из них находится реализационный автомат мы можем не знать. Сначала рассмотрим два частных случая: наличие специальных средств для определения постсостояния; наличие возможности однозначно вычислить постсостояние. 2.1. Тестированием с открытым состоянием будем называть такое тестирование, при котором у нас имеется специальная операция чтения постсостояния реализационного автомата. Сначала рассмотрим автоматы класса A5: любое квази-конечное слово переводит автомат в стационарное состояние: терминальное состояние или принимающее состояние без e-переходов в другие состояния (есть только e- петля). Очевидно, что это относится к выполнению автомата, начинающемуся не только в начальном, но и в любом состоянии, достижимом из начального по допустимому входному слову. В таких автоматах после шага тестирования мы можем прочитать постсостояние, которое является стационарным. Если же автомат не относится к классу A5, то он может попасть в цикл из пустых, посылающих и e-переходов, и прочитанное состояние является лишь «мгновенным снимком» - автомат уже может перейти в другое состояние. Это общий случай множества возможных постсостояний. 2.2. Сильно-детерминированным асинхронным автоматом назовем автомат класса A5, в котором стационарное постсостояние однозначно определяется допустимым квази-конечным входным словом. Для классического автомата Мили это сильно-детерминированность совпадает с детерминированностью в обычном смысле. Слабо-детерминированным асинхронным автоматом назовем автомат класса A5, в котором стационарное постсостояние однозначно определяется парой из допустимого квази-конечного входного слова и выходного слова. Очевидно, что это относится к выполнению автомата, начинающемуся не только в начальном, но и в любом состоянии, достижимом из начального по допустимому входному слову. В таких автоматах после шага тестирования мы можем по модели однозначно вычислить единственное стационарное постсостояние. Заметим, однако, что, в отличии от тестирования с открытым состоянием, здесь мы имеем лишь гипотезу о том, что реализационный автомат находится в том же единственном постсостоянии, что и модель. Другое дело, что гипотеза о допустимости позволяет нам подавать в этом состоянии любое допустимое в модельном постсостоянии входное слово. В общем случае мы уже не можем говорить о единственном постсостоянии, а только о множестве возможных постсостояний, в одном из которых автомат находится в данный момент времени после окончания шага тестирования. Если автомат относится к классу A5, но не является слабо-детерминированным, все эти возможные постсостояния стационарны. В противном случае, среди них могут быть и нестационарные состояния так, что автомат ожидает следующего 78
непустого стимула не в каком-то, хотя и неизвестном, но одном состоянии, а непрерывно движется, меняя свое состояние и, быть может, выбирая из входной очереди пустые стимулы, то есть, проходя через рецептивные состояния. При наличии множества возможных постсостояний, входное слово, которое мы можем давать на следующем шаге тестирования, должно быть допустимо в любом из этих возможных постсостояний.
4.11. Проблема имплицитной спецификации модели и обход графа состояний До сих пор мы предполагали, что модельный автомат задан явно, например, в виде своего графа состояний. Однако, на практике модель часто задается имплицитно в виде спецификаций пред- и постусловий. Предусловие – это логическое выражение от состояния и стимула, описывающее допустимость некоторых стимулов в некоторых состояниях автомата. Совокупность предусловий описывает полностью допустимость стимулов в состояниях автомата. Постусловие для асинхронных автоматов описывает переходы: постусловие принимающих переходов – логическое выражение от пресостояния, стимула и постсостояния; постусловие посылающих переходов – логическое выражение от пресостояния, реакции и постсостояния; постусловие пустых переходов – логическое выражение от пресостояния и постсостояния. Совокупность постусловий вместе с соответствующими им предусловиями описывает все переходы автомата. Задача построения графа состояний модельного автомата по его имплицитной спецификации сводится к решению системы уравнений имеющих вид pre(v,x)⇒post(v,x,v`), pre(v)⇒post(v,y,v`) или pre(v)⇒post(v,v`). Понятно, что такая задача может оказаться слишком сложной и не всегда решается удовлетворительным способом. С другой стороны, в процессе тестирования нам может не потребоваться весь модельный граф, поскольку, во-первых, не все реакции, разрешаемые моделью, обязаны присутствовать в реализационном автомате, и, во-вторых, не все реакции, разрешаемые реализацией, реально появятся в данном сеансе тестирования. Подграф модели, соответствующий данному сеансу тестирования, будем называть подграфом тестирования. Можно поставить задачу построения подграфа тестирования в процессе самого тестирования. Проиллюстрируем возможный способ решения этой задачи для стационарного тестирования с открытым состоянием автомата класса A5 (в котором каждое стационарное состояние каждым допустимым квази-конечным словом переводится только в стационарные состояния). Для простоты будем считать также, что модель не имеет смешанных состояний. Пусть на некотором шаге тестирования автомат находится в стационарном состоянии a, подается стимул x, получается в ответ выходное слово u длины n и определяется стационарное постсостояние b. В графе модели этой ситуации соответствует множество маршрутов, начинающихся в состоянии a, заканчивающихся в состоянии b, имеющих x-раскраску xe* и y-раскраску u. Получая на каждом шаге 79
тестирования все такие маршруты мы в итоге получим требуемый подграф тестирования. Маршруты шага тестирования можно получить, последовательно решая уравнения спецификации. Сначала решаем уравнение принимающего перехода pre(a,x)⇒post(a,x,v1) относительно постсостояния v1. Таких решений может быть несколько. Для каждого из этих решений v1 независимо рассматриваем уравнение e-перехода pre(v1,e)⇒post(v1,e,v2), посылающего перехода для 1-ой реакции pre(v1)⇒post(v1,u[1],v2) и уравнение пустого перехода pre(v1)⇒post(v1,v2) и независимо решаем их относительно постсостояния v2. Если все эти уравнения не имеют решений, решение v1 нужно отбросить. В противном случае, мы имеем множество решений v2. Теперь для каждого решения v2 рассматриваем независимо уравнения e-перехода pre(v2,e)⇒post(v2,e,v3), посылающего перехода для 2-ой реакции pre(v2)⇒post(v2,u[2],v3) – если v2 было решением посылающего перехода для 1-ой реакции, или pre(v2)⇒post(v2,u[1],v3) – если v2 было решением пустого или e-перехода, а также уравнение пустого перехода pre(v2)⇒post(v2,v3) и независимо решаем эти уравнения относительно постсостояния v3. Этот процесс продолжается и дальше, но только на каждой ветви этого процесса, после того как будет решено уравнение посылающего перехода для последней реакции u[n] будем проверять, попало ли постсостояние b в число решений этого уравнения. Если попало, то эта ветвь заканчивается, а если нет, то продолжается решением уравнений только e-переходов и пустых переходов пока таким решением не станет b. Поскольку автомат относится к классу A5, это гарантирует завершение процесса вычислений за конечное время. Если постусловия имеют вид v`=f(v,x), v`=g(v,y) и v`=h(v), то решение уравнений сводится к вычислению всех значений многозначных функций f, g и h. Аналогично можно строить подграф тестирования для стационарного тестирования слабо-детерминированного автомата класса A5, не требуя открытости состояния. Отличие в том, что вместо проверки на известное стационарное постсостояние мы будем проводить вычисления на каждой ветви до получения стационарных решений уравнений спецификации. (Вообще говоря, мы должны тестировать не только на квази-конечных словах с одним непустым стимулом, поэтому в решаемые уравнения нужно включить также уравнения для принимающих переходов по очередным стимулам входного слова.) В обоих вариантах стационарного тестирования (с открытым состоянием или для слабо-детерминированного автомата) можно поставить задачу: в каждом достигнутом при тестировании стационарном состоянии попробовать каждый допустимый стимул. Более точно: попробовать квази-конечное слово вида xeω для каждого непустого стимула x. Адаптивный алгоритм с таким свойством будем называть обходом графа по стимулам. Мы можем потребовать большего. Назовем неразделяемым маршрут выполнения для допустимого квази-конечного входного слова, ведущий из стационарного 80
пресостояния v в стационарное постсостояние v`, все внутренние состояния которого нестационарны. Соответствующее квази-конечное входное слово (xраскраска маршрута) назовем неразделяемым словом для состояния v. Мы можем потребовать при тестировании прохода по всем стационарным состояниям, которые можно достигнуть из данного стационарного состояния по всем неразделяемым квази-конечным словам. Для этого в каждом состоянии мы должны попробовать такое подмножество квази-конечных входных слов, чтобы гарантированно достигнуть все такие стационарные состояния. Адаптивный алгоритм с таким свойством будем называть обходом графа по неразделяемым словам. Понятие обхода по неразделяемым словам можно обобщить на случай произвольного асинхронного автомата. Здесь возникают две задачи: 1) описать классы автоматов, для которых существует такой обход, и 2) найти эффективные алгоритмы построения обходов одновременно с построением самого графа тестирования. В общем случае эти задачи не решены.
4.12. Проблема медиаторов и многоуровневые спецификации До сих пор мы предполагали, что алфавиты стимулов и реакций модельного и реализационного автоматов совпадают. На практике это часто не так и для установления соответствия реализации и модели используются специальные медиаторные преобразования (медиаторы). Алфавитным медиатором назовем медиатор, который осуществляет простое отображение ϕ модельного алфавита стимулов в реализационный алфавит стимулов и отображение ψ реализационного алфавита реакций в модельный алфавит реакций. Эти отображения естественно расширяются на последовательности стимулов и реакций. Тогда сводимость реализации к модели записывается так: Dom(W[R])⊇ϕ(Dom(W)) ∀w∈Dom(W) ψ(W[R](ϕ(w)))⊆W(w). В общем случае могут быть и другие (неалфавитные) медиаторы, которые сразу определяются как отображения входных и выходных слов с сохранением требования о равенстве длин модельного и реализационного слов. Более того, эти отображения могут быть многозначными и тогда более естественно говорить о медиаторных соответствиях. Эти соответствия должны обладать определенными свойствами, в частности, соответствующие слова являются продолжениями соответствующих слов. Кроме того, имеет смысл говорить о регулярных соответствиях, то есть, о соответствиях, которые могут быть заданы как множества, порождаемые конечными графами. Кроме того, сами спецификации могут быть многоуровневыми так, что каждый уровень соответствует некоторому уровню абстракции и формулирует функциональные требования соответствующего уровня. Наиболее частая ситуация – три уровня: 1) уровень реализации, 2) уровень спецификации в виде пред- и постусловий и 3) уровень тестовой модели, которая является в некотором смысле фактор-моделью спецификационной модели, не имеет описания не только в виде графа состояний, но и в виде пред- и постусловий, а задается только 81
медиаторным соответствием с уровнем спецификации; по тестовой модели происходит непосредственное тестирование.
5. Заключение Понятие асинхронного автомата является удобной математической абстракцией для спецификации программных и аппаратных систем, имеющих свойства «автоматности», но более сложных, чем классические автоматы Мили. В то же время теория таких автоматов и, особенно, методы тестирования соответствия для таких автоматов находятся пока что в зачаточном состоянии. В настоящей статье мы дали определение асинхронного автомата и его выполнения, ввели классификацию автоматов с точки зрения реализуемой ими словарной функции и рассмотрели некоторые вопросы реализации словарной функции такими автоматами в виде множества сериализаций – смешанных последовательностей воспринимаемых стимулов и выдаваемых реакций. Что касается тестирования соответствия, то мы лишь обозначили некоторые возникающие здесь проблемы и наметили некоторые возможные пути их решения. Реальные эффективные алгоритмы существуют лишь для некоторых частных (хотя, возможно, и широко распространенных) классов асинхронных автоматов. В дальнейшем мы предполагаем уделить этому вопросу большее внимание. Асинхронные автоматы – это автоматы с одной входной и одной выходной очередями. Естественный следующий шаг – рассмотреть автоматы с несколькими очередями. После этого можно изучать сети автоматов, в которых каждая очередь является выходной очередью одного или нескольких автоматов и входной очередью также одного или нескольких автоматов. Такие автоматные сети можно использовать как модель программных и аппаратных систем с несколькими независимыми активностями (процессами), поведение каждой из которых можно моделировать отдельным асинхронным автоматом. Здесь возникают не только проблемы тестирования таких сетей, но и проблемы их спецификации, которые можно рассматривать также как не только чисто функциональные, но и композиционные (структурные). Литература: 1. G. Karjoth. XFSM : A formal model of communicating state machines for implementation specifications. In D. Etiemble, J.C. Syre, editors, PARLE'92 ``Parallel Architectures and Languages Europe'' Springer Verlag, Lecture Notes in Computer Science 605, pages 979980, 1992. 2. Alan C. Shaw. Communicating Real-Time State Machines. IEEE TRANSACTIONS ON SOFTWARE ENGINEERING, VOL. 18, NO. 9, SEPTEMBER 1992 3. Gregor V. Bochmann , Alexandre Petrenko, Protocol testing: review of methods and relevance for software testing, Proceedings of the 1994 international symposium on Software testing and analysis, p.109-124, August 17-19, 1994, Seattle, Washington, United States
82
4. D. Lee and M. Yannakakis. Principles and methods of testing finite state machines - a survey. In Proceedings of the IEEE, volume 84, number 8, pages 1090-1123, Berlin, Aug 1996. IEEE Computer Society Press. 5. YoungJoon Byun, Beverly A. Sanders, and Chang-Sup Keum. " Design Patterns of Communicating Extended Finite State Machines in SDL". In Proceedings of the 8th Conference on Pattern Languages of Programs, Monticello, Illinois, September 2001. 6. Naveen Chandra R, Verification of Communicating Reactive State Machines, M.Tech. Thesis, IIT Bombay, Jan. 2002, Guide: Prof. S. Ramesh. 7. Рабин М., Скотт Д., Конечные автоматы и проблемы их разрешения. Кибернетический сборник, ИЛ, вып. 4 (1962), 58-91. 8. Сеймур Гинзбург. Математическая теория контекстно-свободных языков. М., «МИР», 1970, 71-78. 9. Д.В.Варсанофьев, А.Г.Дымченко. Основы компиляции. 1991. http://www.codenet.ru/progr/compil/cmp/intro.php
83
84
Об одном методе маскировки программ А. В. Чернов Аннотация. В данной работе рассматривается новый метод маскировки программ. Приводится теоретическое обоснование метода. Демонстрируются преимущества метода по сравнению с уже известными.
1. Введение В настоящее время вопросы защиты информации приобрели первостепенную важность. Компьютерные программы могут также рассматриваться как информация, которая нуждается в защите. Защита программного обеспечения включает в себя, с одной стороны, защиту от копирования и (или) нелицензионного использования и, с другой стороны, защиту от обратной инженерии и несанкционированной модификации. В данной работе рассматривается второй аспект защиты программ. В качестве одного из методов защиты от обратной инженерии применяется маскировка программ. Говоря неформально, маскировка программы – это такое преобразование её текста, которое полностью сохраняет её функциональность, но делает понимание, обратную инженерию и модификацию текста программы задачей неприемлемо высокой стоимости. Задача маскировки программ может рассматриваться с нескольких позиций. С криптографической и теоретико-сложностной точки зрения задача маскировки требует выработки приемлемого формального определения. Это направление, кроме того, включает в себя разработку методов маскировки с формально доказанным уровнем безопасности. Мы подходим к задаче с точки зрения системного программирования. При таком подходе объектами маскировки являются тексты реальных программ, состоящих из сотен функций по несколько сотен строк каждая. Замаскированные программы должны укладываться в ограничения вычислительной системы, что не может не отразиться на используемых методах маскировки. Кроме того, большой размер исходных программ означает, что применение ручного анализа программы при ее демаскировке затруднено из-за временных и стоимостных ограничений. Для демаскировки таких программ применяются инструментальные средства анализа программ и обратной инженерии, поддерживающие полный спектр существующих статических, полустатических и динамических методов анализа. 85
В данной работе рассматривается задача маскировки Си-программ: маскировщик берёт на входе Си-программу, и на выходе выдаёт замаскированную Си-программу. Потребуем, чтобы программы в своей работе не использовали исключения. Основываясь на результатах анализа опубликованных методов маскировки программ [8], нами был разработан новый метод маскировки, который в наибольшей степени устойчив как к статическим, так и к полустатическим методам анализа. Этот метод излагается в настоящей работе. Разработать универсальный маскировщик, который был бы применим ко всем программам и был бы устойчивым ко всем возможным методам анализа программ, невозможно [9]. В данной работе рассматривается метод маскировки программ, который, насколько это нам удалось, удовлетворяет приведённым выше требованиям. Далее в тексте этой главы предлагаемый метод маскировки программ будет называться ММ. ММ использует некоторые маскирующие преобразования, рассмотренные в работе [8]. Тем не менее, он выполняет их в такой комбинации с новыми преобразованиями, что применение методов анализа, описанных в [8], не дает результата. Кроме того, ММ разработан так, чтобы противостоять полустатическим методам анализа программ.
2. Общее описание метода маскировки Метод ММ применяется к функциям маскируемой программы по отдельности, при этом структура маскируемой программы в целом не изменяется. Для изменения структуры маскируемой программы могут применяться стандартные методы открытой вставки и выноса функции, рассмотренные в [8], которые, однако, не являются частью предлагаемого метода маскировки. При маскировке каждой функции ММ использует, наряду с локальными несущественными переменными, глобальные несущественные переменные, которые формируют глобальный несущественный контекст. В маскируемую программу вносятся несущественные зависимости по данным между существенным и несущественным контекстом функции. Наличие глобального несущественного контекста, совместно используемого всеми замаскированными функциями, приводит к появлению в замаскированной программе зависимостей по данным между всеми функциями и глобальными переменными. Метод ММ состоит главным образом из преобразований графа потока управления. В результате граф потока управления замаскированной программы значительно отличается от графа потока управления исходной программы. Метод не затрагивает структур данных исходной программы, но вносит в замаскированную программу большое количество несущественных зависимостей по данным. В результате, замаскированная программа значительно сложнее исходной как по управлению, так и по данным. 86
Мы предполагаем, что перед маскировкой были выполнены все стандартные шаги анализа программы: лексический, синтаксический, семантический, анализ потока управления (построение графа потока управления и деревьев доминирования и постдоминирования) и консервативный глобальный анализ потоков данных (достигающие определения и доступные выражения с учётом возможных алиасов). Дополнительно может быть выполнено профилирование дуг, результаты которого учитываются в преобразованиях клонирования дуг и развёртки циклов. Общая идея метода может быть охарактеризована следующим образом. • Во-первых, значительно увеличить сложность графа потока управления, но так, чтобы все дуги графа потока управления, внесённые при маскировке, проходились при выполнении программы. Это позволяет преодолеть основную слабость «непрозрачных» предикатов. • Во-вторых, увеличить сложность потоков данных маскируемой функции, «наложив» на неё программу, которая заведомо не влияет на окружение маскируемой функции и, как следствие, не изменяет работы программы. «Холостая» функция строится как из фрагментов маскируемой функции, семантические свойства которых заведомо известны, так и из фрагментов, взятых из библиотеки маскирующего транслятора. Чтобы затруднить задачу выявления холостой части замаскированной функции используются языковые конструкции, трудно поддающиеся анализу (указатели) и математические тождества. Маскировку можно разбить на несколько этапов: 1. Увеличение размера графа потока управления функции. На этом этапе выполняются различные преобразования, которые изменяют структуру циклов в теле функции, а также клонирование базовых блоков. 2. Разрушение структуры графа потока управления функции. На этом этапе в граф потока управления вносится значительное количество новых дуг. При этом существовавшие базовые блоки могут оказаться разбитыми на несколько меньших базовых блоков. В графе потока управления могут появиться новые пока пустые базовые блоки. Цель этого этапа – подготовить место, на которое в дальнейшем будет внесён несущественный код. 3. Генерация несущественного кода. На этом этапе пустые базовые блоки графа потока управления заполняется инструкциями, не оказывающими влияния на результат, вырабатываемый программой. Несущественная, «холостая» часть пока никак не соприкасается с основной, функциональной частью программы. 4. «Зацепление» холостой и основной программы. Для этого используются как трудно анализируемые свойства программ 87
(например, указатели), так тождества и неравенства.
и
разнообразные
математические
2.1. Увеличение размера графа потока управления Преобразования перестройки циклов заключаются в том, что в маскируемой функции выбираются подходящие гнёзда циклов и одиночные циклы и над ними выполняются преобразования пространства индексов. К таким преобразованиям относятся: • Понижение размерности пространства итерирования. • Повышение размерности пространства итерирования. • Изменение порядка обхода пространства итерации. • Аффинные преобразования пространства итерации. • Частичная или полная развёртка цикла. На этапе перестройки циклов просматриваются все циклы в теле функции. Для каждого цикла проверяются достаточные условия применимости каждого преобразования, определяя таким образом множество доступных преобразований. Затем для каждого цикла программы определяется какое преобразование будет к нему применено, и выполняются преобразования циклов. На Рис. 1 приведён пример применения преобразования понижения размерности индексного пространства к функции перемножения двух матриц. Преобразование позволило перейти от трёхкратного вложенного цикла к единственному циклу. enum { N = 128 }; typedef double matr_t[N][N]; void mm(matr_t m1, matr_t m2, matr_t r) { int i, j, k; for (i = 0; i < N; i++) for (j = 0; j < N; j++) r[i][j] = 0; for (i = 0; i < N; i++) for (j = 0; j < N; j++) for (k = 0; k < N; k++) r[i][j] += m1[i][k]*m2[k][j]; }
(a) функция до преобразования
enum { N = 128 }; typedef double matr_t[N][N]; void mm(matr_t m1, matr_t m2, matr_t r) { int i, j, k; for (i = 0; i < N * N; i++) r[i / N][i % N] = 0; for (i = 0; i < N * N * N; i++) r[i/(N*N)][i%(N*N)/N] += m1[i/(N*N)][i%N]*m2[i%N][i%(N*N)/N ]; }
(b) функция после преобразования
Рис. 1. Пример преобразования понижения размерности. Преобразование клонирования базовых блоков заключается в замене последовательного выполнения двух базовых блоков (например, B[i] и B[j]) на оператор разветвления с выполнением копии базового блока B[j] на каждой из 88
ветвей. Для этого базовый блок B[j] должен быть скопирован необходимое число раз. На Рис. 2 приведена схема преобразования. На Рис. 2 базовый блок B[j] был размножен дважды. Базовый блок B[cond] будет содержать инструкции, необходимые для того, чтобы каждая из трёх копий базового блока B[j] выполнялась примерно с одинаковой частотой. Базовые блоки B[new1], B[new2], B[new3] также могут содержать инструкции для поддержки равномерного распределения потока выполнения по трём альтернативам.
(a) Исходный граф.
(b) Преобразованный граф
Рис. 2. Схема преобразования клонирования базовых блоков. Уже на этапе клонирования базовых блоков начинается построение параллельной «холостой» функции, которая в дальнейшем будет объединена с основной функцией для получения результирующей замаскированной функции. Изначально холостая программа строится так, что содержит только типы данных, переменные и инструкции, необходимые для корректной работы программы с клонированными базовыми блоками. При создании параллельной функции одновременно строятся все структуры, содержащие результаты анализа потока управления и потоков данных параллельной функции. Используются такие методы построения параллельной функции, при которых её семантические свойства заведомо известны. Для клонирования выбирается базовый блок B[j], у которого дуга графа потока управления, выходящая из блока удовлетворяет следующим условиям: • Дуга не выходит из базового блока ENTRY и не входит в базовый блок EXIT. 89
• Дуга имеет высокую относительную частоту прохождения. • Дуга является единственной дугой, выходящей из блока B[j]. Счётчики. Базовые блоки, полученные в результате клонирования, остаются полностью эквивалентными друг другу. Тем не менее, чтобы маскировка была более действенной, необходимо, чтобы все базовые блоки при работе замаскированной программы выполнялись, причём желательно, чтобы с примерно одинаковой частотой. Для этой цели используются так называемые недетерминированные счётчики (НС). Недетерминированные счётчики представляют собой абстрактный тип данных, над которым определены следующие операции: init: int, env -> counter get: counter, env -> int next: counter, env -> counter Здесь env – это среда выполнения программы, поставляющая источник недетерминизма в счётчик. Операция init инициализирует счётчик. Первый параметр операции задаёт границу значений N, которые будет вырабатывать счётчик. Операция get вырабатывает целое значение в диапазоне от 0 до N-1, которое может использоваться для выбора одной из дуг для выполнения функции. Операция next модифицирует текущее состояние счётчика таким образом, чтобы при следующем выполнении операции get она выдавала бы другой результат. Операция next – это для каждого конкретного счётчика на самом деле семейство операций next1, next2 и т. д., реализации которых в замаскированной программе могут существенно отличаться друг от друга. Типы данных реализации счётчиков, их переменные состояния и инструкции, соответствующие операциями над счётчиками, являются частью параллельной «холостой» функции. Переменная c, которая хранит состояние счётчика, может быть создана как на уровне локальных переменных маскируемой функции, так и вынесена в статические переменные всей единицы компиляции. Последнее позволяет разделять одну и ту же переменную состояния между разными счётчиками разных функций, что полезно ещё и тем, что создаёт в замаскированной программе межпроцедурные зависимости по данным. В настоящее время в интегрированной среде Poirot реализованы некоторые простейшие виды счётчиков, которые описаны ниже. • Счётчик по модулю. Это – простейший вид счётчика. Состояние счётчика хранится в переменной целого типа, которая размещается на уровне статических переменных единицы компиляции. Операция init заключается в записи в переменную счётчика произвольного числа, например, значения какого-либо параметра функции или глобальной переменной. Операция get заключается во взятии остатка от деления на k текущего значения переменной счётчика. Операция next заключается в прибавлении или вычитании произвольного числа, не кратного k, причём семейство операций next порождается различным выбором этого числа. 90
•
Линейный конгруэнтный счётчик. Этот вид счётчика реализует хорошо известный линейный конгруэнтный метод получения псевдослучайных чисел [5]. Операции init и get не изменяются, а операция next определяется как next (cntr ) ≡ (C1 ∗ cntr + C 2 ) mod C3 , где C2 и C3 – взаимно простые числа. Можно также применять полиномиальные конгруэнтные счётчики, а также любой другой алгоритм получения псевдослучайных равномерно распределённых чисел [5]. • Криптографические хэш-функции. Для реализации счётчиков могут использоваться криптографические хэш-функции, например, MD5 или SHA [17], или симметричные криптосистемы. Тогда операция next может выглядеть следующим образом next (cntr ) ≡ f (cntr ⊕ x) . Здесь f – хэш-функция, а x – некоторые произвольные данные, например, значение какой-либо локальной переменной или параметра функции. Отметим, что алгоритмы вычисления криптографических хэш-функций имеют специфический вид (они состоят из побитовых операций с использованием таблиц), и поэтому могут быть достаточно легко опознаны при демаскировке. • Динамические структуры данных. Например, может быть создан кольцевой список, который заполняется числами от 0 до k-1 в произвольном порядке. Операция get состоит в чтении значения текущего элемента списка, а операция next – в продвижении указателя на следующий элемент списка. Дробление базовых блоков. Это преобразование заключается в том, что базовый блок достаточной длины разделяется на два или более меньших базовых блока. Дробление базовых блоков никак не отражается на коде функции и заключается в модификации вспомогательных структур, используемых для представления графа потока управления.
(a) Исходный граф
(b) Преобразованный граф
Рис. 3. Схема преобразования зацепления дуг. public interface ReturnPredicateFactory { public String getReturnPredicateKindName(); public String getReturnPredicateKindDescription(); public boolean mayGenerateJumps(); public ReturnPredicateGenerator newInstance (ObfuscationEnvironment env); } public interface ReturnPredicateGenerator { public ReturnPredicateFactory getFactory(); public MIFInstr emitType(MIFInstr p); public MIFInstr emitGlobalDecl(MIFInstr p); public MIFInstr emitLocalDecl(MIFInstr p); public MIFInstr emitSetFalse(MIFInstr p); public MIFInstr emitSetTrue(MIFInstr p); public MIFInstr emitTest(MIFInstr p, MIFElem e, MIFInstr d[]); public Set getDepends(); public MIFInstr emitInit(MIFInstr p); public MIFInstr emitFini(MIFInstr p); }
2.2. Разрушение структурности графа потока управления Эта группа маскирующих преобразований включает зацепление дуг и создание псевдоциклов. Зацепление дуг. Схема преобразования показана на рис. 3. Для преобразования выбираются две случайных дуги графа потока управления функции. При этом предпочтение отдаётся «далёким» друг от друга дугам, где расстояние измеряется как минимальное из длин двух кратчайших путей по графу от конца одной дуги к началу другой. Две выбранные дуги не должны иметь общее начало или общий конец. Ключевым для обеспечения надёжности зацепления дуг является предикат P, который в конце выполнения нового базового блока B[new] гарантирует возврат на «правильный» путь выполнения. Такой предикат мы назовём возвращающим.
Рис. 4. Интерфейсы для возвращающих предикатов. 91
92
До преобразования после выполнения базового блока B[from1] всегда выполнялся базовый блок B[to1], а после базового блока B[from2] всегда выполняется базовый блок B[to2]. В результате выполнения этого преобразования создаётся новый базовый блок B[new], который выполняется и после B[from1], и после B[from2]. Новый базовый блок завершается вычислением предиката P, в зависимости от которого управление передаётся либо на базовый блок B[to1], либо на базовый блок B[to2]. Предикат P должен гарантировать, что управление вернётся на ту ветвь, с которого оно пришло в блок B[new]. Методы генерации предикатов, удовлетворяющих этому требованию, будут рассмотрены ниже. Интегрированная среда Poirot предусматривает гибкий интерфейс для подключения новых возвращающих предикатов. Добавление очередного возвращающего предиката при маскировке программы производится посредством интерфейса ReturnPredicateFactory. Интерфейс к методам генерации кода для возвращающих предикатов называется ReturnPredicateGenerator. Оба интерфейса приведены на Рис. 4. Реализованы некоторые простейшие виды возвращающих предикатов. Простейший вид возвращающего предиката – это обычная булевская переменная. Переменная может быть объявлена как на уровне локальных переменных, так и на уровне глобальных переменных. Возвращающие предикаты могут быть построены на основе хэш-функций. Пусть хэш-функция f отображает целочисленный тип в булевский. Введём переменную v, которую будем использовать как аргумент f. Таким образом, предикат P равен f(v). Установка значения P в true эквивалентна присваиванию переменной v любого значения x, на котором f(x) = true. Такие значения x могут браться из массива Ptrue, который индексируется произвольным выражением e. Тогда установка значения предиката P в true выполняется присваиванием v ← Ptrue[e]. Установка значения предиката P в false выполняется аналогично. Для построения возвращающих предикатов могут быть использованы динамические структуры данных, аналогично тому, как они использовались для построения счётчиков. Размещение возвращающих предикатов обычно обладает существенным недостатком, снижающим степень его устойчивости. Все операции с возвращающим предикатом сконцентрированы в небольшой области графа потока управления. Используется два способа преодоления этого недостатка. Во-первых, инструкции установки значения возвращающего предиката помечаются как кандидаты на продвижение вверх в графе потока управления функции. На заключительном шаге перемешивания инструкций эти инструкции будут перемещены вверх как можно выше. Во-вторых, инструкции инициализации возвращающих предикатов могут быть размещены не в самих базовых блоках B[from1] или B[from2], а в базовых блоках, из которых управление может попасть только в нужный блок. 93
Создание псевдоциклов. Преобразование состоит во внесении в граф потока управления функции обратной дуги. При этом контролируется, чтобы тело полученного цикла выполнялось только один раз. Схема преобразования показана на Рис. 5. Здесь сцепляются дуги B[i1]->B[i2] и B[i2]->B[i3]. Предикат P, находящийся в конце базового блока B[new], должен обеспечить однократное выполнение базового блока B[i2].
(a) Исходный граф
(b) Преобразованный граф
Рис 5. Схема построения «псевдоцикла». Устойчивость преобразования создания псевдоцикла к анализу определяется устойчивостью возвращающего предиката. В отличие от преобразования зацепления дуг, в котором инструкции установки значения возвращающего предиката P могут быть размещены достаточно «далеко» от точки зацепления дуг, преобразование создания псевдоцикла более ограничено. Установка значения предиката P, чтобы управление покинуло псевдоцикл, не может быть вынесено из блока B[i2].
94
2.3. Генерация несущественного кода В маскируемую функцию добавляется большое количество несущественного кода. Несущественный код строится таким образом, что его свойства точно известны маскирующему компилятору. Например, в случае использования алиасов в несущественном коде при генерации кода одновременно строится и точное множество абстрактных ячеек памяти для каждого обращения по указателю. Этап генерации несущественного кода состоит из следующих подэтапов: • Генерация пула типов. • Генерация пула переменных. • Генерация несущественного кода. Генерация пула типов. Подготавливаются определения типов, которые затем будут использоваться в холостом коде. Типы для холостого кода строятся одним из следующих способов: • Непосредственно используются типы, определённые в маскируемой программе. • Используются встроенные типы. • Из встроенных типов и типов, определённых в маскируемой программе, путём встраивания в шаблонные типы маскирующего компилятора. Например, из типа t, определённого в маскируемой программе, могут быть построены типы массива элементов типа t, списки, деревья с элементами типа t. • Модификацией структурных типов, определённых в маскируемой программе. Для каждого типа, добавляемого в маскируемую программу, в маскирующем компиляторе строится класс-реализатор, на который возлагаются все функции по генерации инструкций для манипуляций с этим типом. Класс-реализатор должен удовлетворять интерфейсу TypeImplementer, который приведён на Рис. 6. Каждая несущественная переменная, добавленная в маскируемую функцию, в маскирующем компиляторе представлена классом, реализующим интерфейс VarImplementer, который показан на Рис. 7. Генерация пула переменных. Для генерации пула «холостых» переменных используются типы, построенные на предыдущей стадии. Переменные размещаются как на уровне локальных переменных функции, так и на уровне глобальных переменных. Генерация несущественного кода. Для генерации несущественного кода используются множества операций, которые были получены с помощью методов getBinaryOps, getUnaryOps, getAssignOps интерфейса TypeImplementer. Инструкции несущественного кода размещаются в базовых блоках вперемешку с инструкциями исходной функции и управляющими инструкциями. 95
interface TypeImplementer { public boolean requiresGlobalInit(); public boolean isSimple(); public boolean isUsable(); public MIFInstr emitType(MIFInstr p); public VarImplementer newVar(); public Set getBinaryOps(); public Set getUnaryOps(); public Set getAssignOps(); } Рис. 6. Интерфейс для реализатора типов. interface VarImplementer { public TypeImplementer getType(); public MIFElem emitGlobalDecl(MIFElem p); public MIFElem emitLocalDecl(MIFElem p); public MIFElem emitInit(MIFElem p); public MIFElem emitFini(MIFElem p); } Рис. 7. Интерфейс для реализатора переменных. «Перемешивание» управляющих инструкций. Управляющими инструкциями назовём инструкции функции, выполняющиеся при вычислении возвращающих предикатов и счётчиков, то есть инструкции, необходимые для того, чтобы расширенный граф потока управления замаскированной программы всегда выполнялся как граф потока управления исходной функции. На этом шаге все управляющие инструкции передвигаются на как можно большее расстояние от точки в программе, в которую они были изначально помещены. Границы, в пределах которых можно двигать инструкции, определяются зависимостями по данным управляющих инструкций друг от друга и зависимостями по управлению.
2.4. «Перемешивание» программ На предыдущих этапах граф потока управления функции был значительно увеличен в размерах, затем в него было добавлено большое количество несущественного кода. И предикаты, добавленные в расширенный граф потока управления для моделирования исходного графа потока управления, и несущественный код используют множество переменных, не пересекающихся с основными переменными маскируемой функции. В результате функция может быть расслоена на существенную и несущественную часть, хотя это может быть и затруднено необходимостью проведения анализа указателей. 96
Чтобы затруднить отделение несущественной части замаскированной функции в неё добавляется большое количество искусственных зависимостей по данным между существенной и несущественной частью. Для этого в настоящее время используются булевские, теоретико-числовые и комбинаторные тождества, а также массивы и динамические структуры данных. Булевские тождества. Булевские тождества применяются для усложнения булевских выражений, которые определяют условные переходы. В отличие от других видов тождеств, булевские тождества произвольной сложности легко могут получаться автоматически. Рассмотрим в качестве примера основной метод получения булевских тождеств, реализованный в настоящее время. Булевские тождества произвольной сложности могут быть получены из булевских тождеств относительно простой структуры при помощи набора эквивалентных преобразований. Пусть мы хотим составить булевское тождество с переменными v 1 , v 2 ,..., v k , среди которых есть как переменные исходной функции, так и несущественные переменные, внесённые при маскировке. Пусть e – выражение, подвергаемое усложнению. Тогда строится выражение e ⋅ o , где o = (v1 ∨ v1 ) ∧ L ∧ (v k ∨ v k ) . Далее к получившемуся выражению применяются m шагов эквивалентных преобразований, которые можно найти, например, в [3]. В результате получается выражение e', эквивалентное e, которое используется для условного перехода в замаскированной программе. Такой метод получения булевских тождеств аналогичен методу получения непрозрачных предикатов, рассмотренному в работе [8], но в данном случае использование тождеств не приводит к появлению недостижимой дуги графа потока управления, которая достаточно легко может быть обнаружена. Поэтому использование булевских тождеств в нашем случае обнаруживается значительно сложнее. Комбинаторные тождества. Все рассматриваемые далее тождества, как комбинаторные, так и теоретико-числовые взяты, в основном, из [3]. Рассмотрим в качестве примера следующее биномиальное тождество 2n −
n
∑ C nk = 0
k =0
Тождество может использоваться следующим образом: в качестве n берётся несущественная переменная, принимающая целые значения в небольшом интервале (например, от 0 до 5). Генерируются инструкции, вычисляющие сумму биномиальных коэффициентов и помещающие результат во временную переменную, для определённости @1. Генерируется инструкция сдвига, вычисляющая 2 n и помещающая результат в другую временную переменную, например @2. Далее в исходной функции выбирается аддитивное целое выражение, результат которого сохраняется в некоторой временной переменной, например, @3, и строится новое выражение @1 + @3 - @2. Это 97
выражение всегда будет равно выражению @3, но содержит зависимость по данным от переменной n. Некоторые другие тождества, которые могут использоваться аналогичным образом, приведены ниже. n
0 = ∑ (−1) k C nk k =0
n
n2 n −1 = ∑ kC nk k =1
n
n(n − 1)2 n − 2 = ∑ k (k − 1)C nk k =2
n
n = ∑ (−1) k 4 n − k C 2kn − k +1 − 1 k =0
Теоретико-числовые тождества. В качестве примера рассмотрим известную малую теорему Ферма. a p −1 ≡ 1 (mod p)
для любого целого a ≠ 0 (mod p) и простого p. При маскировке генерируется случайное простое число p. Далее генерируются инструкции для вычисления a p −1 mod p , причём возведение в степень вычисляется с помощью разложения p-1 в двоичную систему. Эти инструкции образуют достаточно длинную линейную последовательность, которая может быть распределена по базовым блокам маскируемой функции. Результат вычисления выражения добавляется как множитель в какое-либо мультипликативное выражение исходной программы, либо как множитель к переменной. Другие теоретико-числовые тождества, которые также могут использоваться для внесения зависимостей по данным, приведены ниже. Обобщением малой теоремы Ферма является теорема Эйлера: x ϕ ( n ) ≡ x (mod n)
где n и x произвольные целые числа, ϕ (n) – функция Эйлера, которая равна количеству взаимно простых с n целых чисел, меньших n. (n − 1)! ≡ −1 (mod n) (теорема Вилсона) тогда и только тогда, когда n – простое число. Использование массивов и динамических структур данных. Динамические структуры данных могут использоваться и для создания искусственных зависимостей по данным. Главный расчёт здесь делается на то, что в настоящее время не существует удовлетворительного алгоритма анализа алиасов, возникающих при использовании указателей и индексов массивов. В качестве простейшего способа можно предложить размещение всех локальных переменных одного типа в массиве. В тексте функции вместо имени 98
переменной теперь будет использоваться индекс массива. Даже случаев, когда индекс всегда представляет собой литеральную константу, будет достаточно, чтобы поставить в тупик простейшие алгоритмы анализа алиасов, которые рассматривают массив как единое целое. В момент маскировки программы известно, какие элементы массива заняты существенными, а какие – несущественными переменными. Более того, распределение несущественных переменных по массиву может выбираться произвольным образом. Это может использоваться для построения зависимостей по данным. Пусть f – функция, ставящая в соответствие произвольному целому значению некоторый индекс в массиве, по которому находится несущественная переменная. Тогда искусственные зависимости по данным строятся с помощью выражений вида vars[f(e1)] = e2 или vars[f(e1)] = vars[f(e2)]. Здесь vars – это массив переменных, e1, e2 – выражения, которые включают в себя как существенные, так и несущественные переменные. Один из простых способов использования динамических структур данных для внесения зависимостей по данным заключается в том, что все значения переменных всех типов хранятся в списке, размещаемом в динамической памяти. Для доступа к переменным вместо их имени используется разыменование специальных указателей. Кроме того, указатели на несущественные переменные время от времени меняют своё положение в списке. В результате окажется, что все обращения к бывшим локальным переменным функции обращаются к объектам в области динамической памяти. Для разделения существенных и несущественных переменных потребуется анализ алиасов в динамической памяти, способный работать с динамическими структурами данных произвольной глубины. В настоящее время не существует такого метода статического анализа алиасов.
Рис. 8. Использование списков для внесения зависимостей по данным. 99
Этот подход проиллюстрирован на Рис. 8, на котором функция содержит четыре переменных – a, b, c и d. Пусть, для определённости, переменные a и b – существенные, а c и d – несущественные. В замаскированной функции вместо этих локальных переменных вводятся переменные p1 и p2, указывающие на звенья списка, размещённого в динамической памяти. Переменная a доступна как p1->prev или как p2->next, а переменная c – как p1->next или как p2->prev.
3. Реализация метода маскировки В данном разделе мы рассмотрим более детально круг вопросов, связанных с реализацией предложенного метода маскировки ММ. В качестве среды реализации используется интегрированная среда Poirot. Напомним основные обозначения, введённые ранее. Инструкции, составляющие тело функции, находятся в массиве instr, индексируемом от 0 и до Ninstr-1, где Ninstr – общее количество инструкций в теле функции. Первая инструкция в этом массиве – инструкция FUNC – пролог функции в представлении MIF, последняя инструкция – инструкция END – эпилог функции. Пусть B – массив базовых блоков этой функции, пусть для каждого базового блока i succ[i] – множество следующих за ним базовых блоков, а pred[i] – множество предшествующих ему базовых блоков, first[i] – номер первой инструкции в массиве instr, принадлежащей базовому блоку i, last[i] – номер последней инструкции в массиве instr, принадлежащей базовому блоку i, nbinstr[i] – количество инструкций в базовом блоке i. Информация о доминировании представлена для каждого блока i номером его непосредственного доминатора idom[i] и номером его непосредственного постдоминатора ipdom[i]. Информация о потоке данных программы представлена в виде ud- и duмножеств. Для аргумента j инструкции с номером i в теле функции ud[i,j] – это множество пар <номер_инструкции,номер_аргумента>, в которых может модифицироваться переменная, и которые достигают данной точки функции. С другой стороны du[i,j] – это множество пар <номер_инструкции,номер_аргумента>, в которых может использоваться переменная, и которые достижимы из данной точки функции. В ud- и du-множествах также отражается собранная информация об алиасах. Для сбора информации об алиасах можно использовать понятие абстрактной области памяти. Абстрактная область памяти – именованная ячейка, доступ к которой возможен из программы одним или несколькими способами. Множество абстрактных ячеек памяти – вся память, с которой может манипулировать программа, с точки зрения алгоритма анализа алиасов. От детальности множества абстрактных ячеек памяти зависит точность выявленных указателей. С другой стороны, чем детальнее множество абстрактных ячеек памяти, тем больше ресурсов требуется для выполнения анализа алиасов. Простейшее по структуре множество абстрактных ячеек памяти включает в себя имена всех локальных и глобальных переменных, а 100
также специальный символ anon, обозначающий динамическую память. Здесь не делается попытки детализации структурных и массивовых типов, различения различных рекурсивных вызовов одной и той же функции, а также детализации структуры данных в динамической области. Для каждой переменной указательного типа поддерживается множество абстрактных ячеек памяти, на которые может указывать данная переменная. Если переменная имеет кратный указательный тип, глубина разыменования указателя может быть ограничена. Обработка множества АЯП для объектов структурных и массивовых типов зависит от детальности множества АЯП. В простейшем случае, когда поля структур и элементы массивов не различаются, объект структурного или массивового типа считается указателем, если он содержит хотя бы одно поле указательного типа. Множество АЯП, на которые может указывать такой объект получается объединением всех множеств АЯП, на которые могут указывать поля структуры или элементы массива. Информация об алиасах вычисляется с помощью стандартных алгоритмов анализа алиасов, например, описанных в [16]. После того, как для каждого указателя и для каждой точки программы вычислено множество абстрактных ячеек памяти, на которые он может указывать, эта информация переносится в ud- и du-множества. Например, если некоторая переменная v присутствует в множестве абстрактных ячеек памяти указателя p, то чтение по указателю p включается в du-цепочку переменной v, если последняя инструкция достижима из точки присваивания. В результате анализа алиасов может оказаться, что точности алгоритма недостаточно, и что множество абстрактных ячеек памяти, адресуемых некоторым указателем в некоторой точке программы, состоит из всех абстрактных ячеек памяти. Другую сложность представляют вызовы функций. Для выявления влияния функции на своё окружение требуется межпроцедурный анализ, являющийся весьма трудоёмким. Поэтому желательно ограничиться минимальным консервативным анализом, который исходит из следующих предположений: • Любая функция читает и изменяет все глобальные переменные. • Любая функция пытается разыменовывать любой указатель, переданный ей в качестве параметра. • После выполнения любой функции все глобальные указатели могут указывать на любые глобальные объекты, любые локальные объекты, упомянутые среди абстрактных ячеек памяти указателейпараметров, и на область динамической памяти. • Любая функция модифицирует все абстрактные ячейки памяти, на которые могут указывать указатели, переданные функции в качестве параметра. • Если среди таких абстрактных ячеек памяти есть локальные переменные указательного типа, то после выполнения функции они могут указывать на любой глобальный объект, любой локальный 101
объект, упомянутый среди абстрактных ячеек памяти указателейпараметров функции, и на область динамической памяти. • Если функция возвращает значение указательного типа, это значение может указывать на любой глобальный объект, любой локальный объект, упомянутый среди абстрактных ячеек памяти указателейпараметров функции, и на область динамической памяти. Современные языки содержат средства, позволяющие при объявлении функции уточнить степень влияния этой функции на окружение программы. К таким средствам относятся, например, квалификаторы типа const и restrict языка Си. Указанные выше правила определения побочного эффекта функции отражаются на вычислении du- и ud-множеств в случае вызова функции. Дальнейшие шаги метода ММ работают с du- и ud-цепочками и не анализируют множества абстрактных ячеек памяти. Метод ММ может использовать информацию о частотах выполнения дуг графа потока управления функции, полученную в результате профилирования. Каждой дуге графа потока управления ставится в соответствие число прохождений по ней. Поскольку каждая дуга графа потока управления однозначно идентифицируется парой номеров базовых блоков откуда она выходит и куда входит, предположим, что все частоты прохождения дуг хранятся в двумерном массиве efreq. Число efreq[i,j] равно количеству прохождений дуги B[i]->B[j]. Если такой дуги в графе потока управления не существует, положим число прохождений равным нулю. Пусть также bfreqin[i ] = ∑ efreq[ j , i ] , то есть равно общему количеству входов в базовый j∈ pred [i ]
блок i, а bfreqout[i ] =
∑ efreq[i, j ] , то есть равно общему количеству выходов
j∈succ[i ]
из базового блока i. Мы будем предполагать, что для всех базовых блоков, кроме ENTRY и EXIT выполняется bfreqin[i ] = bfreqout[i ] = bfreq[i ] , то есть, функция никогда не завершается в обход блока EXIT и никогда не получает управление в обход блока ENTRY.
4. Теоретическое обоснование устойчивости метода Настоящий раздел посвящён анализу устойчивости предложенного метода маскировки. Предварительно дадим некоторые вспомогательные определения и теоремы. Пусть Σ = {0,1} . Пусть poly (n) – произвольный многочлен от переменной n. Определение 1. Пусть f : Σ m → Σ n , пусть m = poly (n) . f называется односторонней функцией, если для любого полиномиального вероятностного алгоритма A и для любого x ∈ Σ m выполняется соотношение 102
P{ A( f ( x )) = x} <
1 poly (m)
Определение 2. Взаимно-однозначная односторонняя функция f : Σ n → Σ n называется односторонней перестановкой. Определение 3. ρ -приближённым алгоритмом решения оптимизационной задачи называется алгоритм, находящий решение не более чем в ρ раз хуже оптимального решения. Например, рассмотрим задачу S минимизации некоторого функционала f. Пусть A – ρ -приближённый алгоритм нахождения решения задачи S. Пусть для некоторой реализации задачи оптимальное значение функционала равно X. Тогда алгоритм A найдёт решение задачи, при котором значение f равно Y, причём будет справедливо неравенство X ≤Y ≤ ρ⋅X Определение 4. Пусть f : Σ m → Σ n . Пусть x = ( x1 , K , x m ) , y = ( y1 , K , y n ) , y = f (x) . Переменная
называется существенной, если существуют x1 ,K, x k − 1 , x k + 1 ,K, x m ∈ Σ и j ∈ {1, K , n} такие, что выполняется условие f j ( x1 ,K, xk −1 ,0, xk +1 ,K, xm ) ≠ f j ( x1 ,K, xk −1 ,1, xk +1 ,K, xm ) . xk
Теорема 1. Пусть f : Σ m → Σ n , f записана как система булевских формул в базисе {∧,∨, ¬} . Пусть 1 ≤ k ≤ m . Задача проверки существенности переменной
x k (СУЩ) NP-полна. Доказательство. Введём обозначение e1 ≠ e 2 ≡ (e1 ∧ e 2 ) ∨ (e1 ∧ e 2 ) , где e1 , e 2
–
булевские
формулы.
Обозначим
x = ( x1 , K , x m ) ,
y = ( y1 , K , y n ) ,
x | xi =σ = ( x1 , K , x i −1 , σ , x i +1 , K , x m ) . 1. Покажем, что задача СУЩ находится в классе NP. Для этого построим n
булевскую формулу g ( x) = U ( f j ( x | xk =0 ) ≠ f j ( x | xk =1 )) . j =1
Если переменная существенна, то существует такой вектор x , для которого g ( x) = 1 . Если переменная несущественна, то на всех наборах x выполняется g ( x) = 0 . И наоборот, если g (x) принадлежит языку ВЫП, то переменная x k
существенна, а если g (x) не принадлежит языку ВЫП, то x k – несущественна. Таким образом, задача проверки существенности сведена к задаче проверки выполнимости булевской формулы. Последняя находится в классе NP. Следовательно, и задача проверки существенности находится в классе NP. 103
2. Покажем, что к задаче СУЩ полиномиально сводится задача ВЫП, которая является NP-полной. Пусть g (x ) – некоторая формула в базисе {∧,∨, ¬} . Рассмотрим формулу, реализующую функцию f ≡ 1 . Она, очевидно, принадлежит языку ВЫП, но ни одна переменная в такой формуле не является существенной. В формуле, реализующей функцию f ≡ 0 , которая не принадлежит языку ВЫП, также нет существенных переменных. Все прочие формулы, принадлежат языку ВЫП, и хотя бы одна переменная в них является существенной. Таким образом, формула не принадлежит ВЫП, если её значение на любом битовом наборе (например, на наборе 0 ) равно 0, и в ней нет существенных переменных. Таким образом, для проверки выполнимости формулы нужно проверить её значение в одной точке и m раз проверить существенность переменных формулы. Таким образом задача ВЫП полиномиально по Тьюрингу сводится к задаче СУЩ, что доказывает NPполноту последней. ■ Определение 5. Пусть f : Σ m → Σ n , пусть Ψ – множество всех таких функций, и пусть π – оракульная функция π : Ψ → {0,1} такая, что для любой функции f ∈ Ψ :
π ( f ) = 0 , если f ≡ 0 , π ( f ) = 1 , в противном случае. Обозначим через ϕ f
формулу, реализующую функцию f. Пусть Φ
–
множество формул (потенциально бесконечное) такое, что если ξ f – случайно и равновероятно выбранная формула из Φ , а f – функция, которую она реализует, то случайная величина π ( f ) принимает значение 1 с вероятностью p, а значение 0 с вероятностью q = 1 − p . Множество формул Φ называется семейством непрозрачных предикатов, если для любого полиномиального вероятностного алгоритма A: Φ → {0,1} выполняются условия 1 P{ A(ξ f ) = 0 | π ( f ) = 0} < q 2 + poly (m) P{ A(ξ f ) = 1 | π ( f ) = 1} < p 2 +
1 poly (m)
Теорема 2. Если непрозрачные предикаты существуют, то P ≠ NP . Доказательство. Пусть P = NP . Тогда существует полиномиальный алгоритм для решения задачи выполнимости, то есть существует алгоритм A, который для любой формулы ξ f за полиномиальное проверит условие f ≡ 0 и выдаст
ответ 0, если условие выполняется, и 1 в противном случае. Тогда 104
P{ A(ξ f ) = 0 | π ( f ) = 0} = 1 , P{ A(ξ f ) = 1 | π ( f )} = 1 , то есть непрозрачные пре-
дикаты не существуют. Полученное противоречие доказывает утверждение. ■ Мы можем расширить понятие непрозрачного предиката, предположив, что область его определения может быть произвольной (например, множество всех целых чисел, представимых определённым количеством битов). Покажем, что непрозрачные предикаты могут быть реализованы и с использованием указателей, и с использованием массивов. Теорема 3. Если булевские непрозрачные предикаты существуют, то непрозрачные предикаты, построенные на указателях, существуют. Доказательство. Пусть f – булевский непрозрачный предикат. Пусть f : Σ m → Σ , f записана в базисе {∧,∨, ¬} . Построим следующее определение структурного типа на Си. struct s { struct s *neg; struct s *min[2]; struct s *max[2]; }; Создадим в начале работы программы в динамической памяти ссылочную структуру, показанную на Рис. 9.
Здесь элемент, на который указывает Pfalse, соответствует логическому значению «ложь», а элемент, на который указывает Ptrue, соответствует логическому значению «истина». Рассмотрим каждую булевскую операцию и поставим ей в соответствие операцию над указателями в созданной структуре данных. 1. xi , где xi – булевская переменная. Ей соответствует переменная pi указательного типа struct s*, которая равна либо Ptrue, либо Pfalse. 2. ¬u , где u – булевское выражение. Ему соответствует выражение указательного типа e->neg, где e – выражение, соответствующее u. 3. u ∨ v , где u, v – булевские выражения. Такому выражению соответствует выражение указательного типа e->max[e == f], где e соответствует u, а f – v. 4. u ∧ v , где u, v – булевские выражения. Такому выражению соответствует выражение указательного типа e->min[e == f], где e соответствует u, а f – v. Таким образом, каждому булевскому выражению u мы сопоставили выражение указательного типа e. Поскольку задача определения u ≡ true NP-полна, то и задача определения e == Ptrue также NP-полна. Непрозрачному предикату f соответствует выражение указательного типа f, также являющееся непрозрачным предикатом. ■ Теорема 4. Если булевские непрозрачные предикаты существуют, то и непрозрачные предикаты, построенные над массивами, существуют. Доказательство. Пусть е – непрозрачный предикат над указателями, построенный, как показано в предыдущей теореме. Поставим ему в соответствие массив целого типа a из 10 элементов, заполненный следующим образом: int a[10] = { 5, 0, 0, 5, 0, 0, 0, 5, 5, 5 }; Указательному значению Pfalse соответствует целое значение 0, а указательному значению Ptrue – целое значение 5. Тогда выражения непрозрачного предиката, построенного на указателях, заменяются на индексные выражения по следующим правилам: 1. 2. 3. 4.
Рис. 9. Схема построения непрозрачного предиката из указателей.
105
106
Переменная pi заменяется на переменную qi целого типа, которая может принимать значения из множества {0,5}. Выражение e->neg заменяется на выражение a[b], где b – индексное выражение, соответствующее e. Выражение e->min[f] заменяется на выражение a[b + 1 + c], где b – индексное выражение, соответствующее e, а c – индексное выражение, соответствующее f. Выражение e->max[f] заменяется на выражение \V{a[b + 3 + c]}, где b – индексное выражение, соответствующее e, а c – индексное выражение, соответствующее f. ■
Определение 6. Пусть f : Σ m → Σ n . Пусть x = ( x1 , K , x m ) , y = ( y1 , K , y n ) , y = f (x) . Пусть
{1,K, n}
I ∈2
. Множество I – это множество индексов
интересующих нас компонент y . Переменная x k называется существенной относительно множества I, если существуют такие x1,K, xk −1 , xk +1 ,K, xm ∈ Σ $ и такая j∈I , что выполняется условие f j ( x1 , K , x k −1 ,0, x k +1 , K , x m ) ≠ f j ( x1 , K , x k −1 ,1, x k +1 , K , x m ) . Теорема 5. Пусть даны m, n, f : Σ m → Σ n , I ∉ 2{1,K,n} , k. Задача проверки
определить принадлежит ли vi множеству V in . Далее за полиномиальное время проверяется, что | Win |≤ p . Для доказательства NP-полноты покажем, как задача СУЩМНОЖ сводится к данной задаче. Пусть f – булевская функция f : Σ m → Σ n . Предположим для определённости, что f записана в виде КНФ. Для определённости будем считать, что x1 = v1 , K , x m = v m – переменные, используемые при вычислении функции, а y1 = vm +1, K , yn = v{m + n} – переменные, получающие своё значение. Пусть требуется проверить существенность переменной x k относительно
существенности переменной x k относительно множества I (СУЩМНОЖ) NP-
множества I.
полна. Доказательство. Доказательство принадлежности задачи к классу NP аналогично доказательству теоремы 1. Для доказательства NP-полноты заметим, что задача СУЩ является частным случаем данной задачи, если мы выберем I = {1, K , n} .
Введём m − 1 новую переменную z1 , K , z m −1 следующим образом: каждое
Пусть V = {v1 ,K , v k } – множество переменных замаскированной программы. Предположим, что базовый блок представляет собой вычисление булевской функции f : Σ m → Σ n . Пусть Vin ⊆ V , | Vin |= m – переменные, значения которых используются при вычислении f, а Vout ⊆ V , | Vout |= n – переменные, которые получают новые значения в результате вычисления. Если для некоторой переменной v ∈ Vin и v ∈ Vout , при вычислении используется старое значение переменной. Пусть Wout ⊆ Vout – множество «существенных» переменных на выходе из базового блока (например, это могут быть переменные, значения которых печатаются, или переменные, значения которых интересны нам по другой причине). Определим задачу анализа зависимостей по данным (ЗАВ) как задачу нахождения минимального множества переменных Win ⊆ Vin такого, что переменные из множества Vin − Win несущественны относительно Wout .
Если переменная x k существенна для f, то переменные x k , z1 , K , z m −1 окажутся
Данной оптимизационной задаче соответствует задача проверки свойств ЗАВ: дано множество булевских переменных V = {v1 ,K , v k } , булевская функция f : Σ m → Σ n над переменными из Vin , подмножество Wout ⊆ Vout , число p
( 0 ≤ p ≤ k ). Существует ли множество Win ⊆ Vin , | Win |≤ p переменные Vin − Win несущественны относительно Wout .
такое, что
Теорема 6. Задача ЗАВ NP-полна. Доказательство. Принадлежность задачи классу NP следует из того, что для каждого i ( 1 ≤ i ≤ k ) можем найти решение задачи СУЩМНОЖ, то есть
107
вхождение
xk
в
формулу
для
вычисления
f
заменим
выражением
x k ∨ z1 ∨ K ∨ z m −1 , а выражение x k – на выражение x k ∨ z1 ∨ K ∨ z m−1 . В
результате получим функцию f1 : Σ 2 m−1 → Σ n , которая также записана в КНФ. существенными для f1 . Если переменная x k несущественная для f, то все переменные x k , z1 , K , z m −1 несущественны для f1 . С другой стороны, если хотя бы одна переменная из множества {x k , z1 , K , z m−1} окажется несущественной в f1 , то и все переменные этого множества будут несущественными. В таком случае пусть p = m − 1 . Тогда, если задача ЗАВ для функции f 1 , множества переменных I и значения p даёт ответ «да», отсюда следует, что все переменные x k , z1 , K , z m −1 несущественны, а если ответ «нет», то все эти переменные существенны. Таким образом задача СУЩМНОЖ сводится к задаче ЗАВ, что показывает NPполноту последней. ■ Рассмотрим оптимизационную задачу ЗАВ. Она состоит в нахождении такого Win ⊆ Vin , что p =| Win | минимально. Из NP-полноты задачи проверки свойств следует NP-трудность оптимизационной задачи. Теорема 7. Если P ≠ NP , то для любого ρ > 1 не существует полиномиального ρ-приближённого алгоритма решения оптимизационной задачи ЗАВ. Доказательство. Пусть существует такое ρ > 1 , что существует полиномиально-ограниченный алгоритм A, который находит множество существенных переменных WinA такое, что p A =| WinA |≤ ρ ⋅ p ≤ n , где p – оптимальное решение. Очевидно, 0 ≤ p ≤ p A ≤ ρ ⋅ p ≤ n . 108
Рассмотрим следующую реализацию задачи СУЩ. Пусть f – булевская функция f : Σ m → Σ n . Предположим для определённости, что f записана в виде КНФ. Для определённости будем считать, что x1 = v1 , K , x m = v m – переменные, используемые при вычислении функции, а y1 = v m +1 , K , y n = v{m + n} – переменные, получающие своё значение. Пусть тре-буется существенность переменной x k относительно множества I.
проверить
Пусть [x] – минимальное целое число, не меньшее x. Введём l = m ⋅ [ ρ ] новую переменную z1 , K , z l следующим образом: каждое вхождение x k в формулу для вычисления f заменим на выражение x k ∨ z1 ∨ K ∨ z l , а выражение x k – на выражение x k ∨ z1 ∨ K ∨ z l . В результате получим функцию f1 : Σ m+l → Σ n , которая также записана в КНФ. Обозначим через Win0 оптимальное решение оптимизационной задачи ЗАВ для формулы f, а через Win1 – оптимальное решение для формулы f 1 . Обозначим WinA решение, найденное алгоритмом A для
f1 .
Пусть x k – существенная переменная. Тогда Win0 таково, что 1 ≤| Win0 |≤ m , Win1 таково, l
+ 1 ≤| WinA
что
l + 1 ≤| Win1 |≤ l ⋅ m ,
WinA
а
удовлетворяет
неравенству
|≤ l ⋅ m .
Пусть x k – несущественная переменная. Тогда Win0 таково, что 0 ≤| Win0 |≤ m − 1 , Win1
таково,
что
0 ≤| Win1 |≤ m − 1 ,
а
WinA
удовлетворяет
неравенству
0 ≤| WinA |≤ ρ ⋅ (m − 1) .
Заметим, что ρ ⋅ (m − 1) < l + 1 = m ⋅ [ ρ ] + 1 . В зависимости от | WinA | , полученного полиномиальным ρ-приближённым алгоритмом A мы можем определить, является ли x k существенной переменной или нет. Следовательно, P = NP . ■ Определение 7. Назовём «мёртвыми» все инструкции, которые относятся к вычислению несущественных переменных. Из доказанного выше немедленно следует, что задача выявления мёртвого кода в программе, состоящей из одного базового блока, NP-полна, и, более того, для любого ρ > 1 не существует ρ-приближённого полиномиального алгоритма выявления мёртвого кода. Переменные произвольных целых типов могут рассматриваться как набор переменных булевского типа. Например, переменная типа int может рассматриваться как 32 булевские переменные, для доступа к которым используются битовые операции. 109
5. Практическое обоснование устойчивости метода Устойчивость замаскированной программы к автоматическому анализу обосновывается следующими наблюдениями: • Многие методы статического анализа потоков данных не поддерживают анализ массивов с точностью до элемента. Для таких методов анализа все обращения к массиву локальных переменных будут равноправны, что приведёт к обнаружению ложных зависимостей по данным. • Для выявления зависимостей по данным между переменными глобального контекста требуется межпроцедурный анализ программы. При наличии большого числа глобальных переменных (как существенных, так и несущественных) и большого числа функции, глобальный анализ окажется либо неточным, либо будет требовать слишком много ресурсов. • То же самое замечание справедливо и для анализа указателей в область динамической памяти. Существующие методы анализа либо неточны, либо неприменимы к программам большого размера. Устойчивость замаскированной программы к ручному анализу обосновывается следующими соображениями: • Полустатический анализ (трассировка) замаскированной программы не позволяет в ней выявить явных закономерностей, таких как никогда не выполняющиеся дуги графа потока управления или регу-лярно выполняющиеся блоки, как диспетчер. Отсутствие явных статистических закономерностей делает полустатический анализ значительно менее эффективным, чем в случаях, рассмотренных в работе [8]. • Инструкции, обеспечивающие устойчивость замаскированной функции, распределены по всем базовым блокам функции, а не сконцентрированы на небольшом участке, как в схеме диспетчера. Поэтому демаскировка требует анализа всей функции, а не какой-то её части. • Большой размер замаскированных функций даже для относительно небольших функций исходной программы является трудным (если преодолимым) препятствием для ручного анализа. • Каждое преобразование, составляющее метод маскировки, параметризуемо в широких пределах (как правило, случайным образом). Знание, извлечённое в результате анализа одной замаскированной функции, может быть только отчасти применено к анализу другой замаскированной функции. • Граф потока управления имеет такую структуру, что его визуализация может дать неудовлетворительный результат. Алгоритмы визуализации могут отобразить граф потока управления таким образом, что это только затруднит понимание, либо вообще не смогут отобразить такой граф. Приведённые здесь рассуждения, конечно, не заменяют формальных доказательств утверждений о трудности демаскировки. Однако следует заметить, что используемый в настоящее время подход, заключающийся в 110
сведении какой-либо вычислительно-трудной задачи к задаче демаскировки программы, позволяет делать утверждения о трудности демаскировки методами статического анализа лишь в худшем случае. Кроме того, в настоящее время не существует математического аппарата, пригодного для оценки сложности полустатического и динамического анализа программ, который имеет существенную эвристическую компоненту.
6. Пример применения метода В качестве примера применения предложенного метода маскировки мы выбрали небольшую программу, которая решает задачу о 8 ферзях. Текст этой программы приведён на рис. 10. #include <stdio.h> static int up[15], down[15], rows[8], x[8]; static void print(void) { int k; for (k = 0; k < 8; k++) printf("%c ", x[k]+'1'); printf("\n"); } static void queens(int c) { int r; for (r = 0; r < 8; r++) if (rows[r] && up[r-c+7] && down[r+c]) { rows[r] = up[r-c+7] = down[r+c] = 0; x[c] = r; if (c == 7) print(); else queens(c + 1); rows[r] = up[r-c+7] = down[r+c] = 1; } } int main(void) { int i; for (i = 0; i < 15; i++) up[i] = down[i] = 1; for (i = 0; i < 8; i++) rows[i] = 1; queens(0); return 0; }
Рис. 10. Программа, решающая задачу о «8 ферзях».
Для маскировки мы выберем основную функцию queens этой программы. Граф потока управления функции queens приведён на рис. 11.
Рис. 11. Граф потока управления функции queens.
Результат маскировки функции queens приведён ниже. static void queens(int c)
111
112
{
goto L102; L101: q[7] = (q[7] + 2); if (q[7] <= 14) goto L103; q[7] = (q[3] + c); L103: q[4] = (v2)[q[7]]; (v4)[(q[3] + c)] = 0; q[1] = 0; (v7)[((q[3] - c) + 7)] = 0; (v8)[q[3]] = q[1]; (v3)[q[3]] = 0; (v5)[c] = q[3]; q[5] = ((q[5] + 4) != 5); q[1] = (v8)[c]; L102: if (c != 7) goto L105; L104: print(); q[4] = ((c * 5) + 4); q[q[11]+2] = (v8)[c]; (v8)[c] = q[4]; goto L106; L105: q[q[11]] = ((c * 5) + 3); (v2)[((q[3] - c) + 7)] = ((q[8] + q[1]) - 7); L115: if ((q[6] % 5) < 2) goto L108; q[4] = ((q[q[11]] % 5) + c); if ((q[4] % 7) != 0) goto L109; q[4] = 1; L109: q[1] = ((q[4] * q[4]) % 7); q[1] = ((q[1] * q[1]) * q[1]); c = ((c + (q[1] % 7)) - 1); queens(((c + 1))); q[11] = (q[q[11]+5] + q[12]) % 13; L106: (v4)[(q[3] + c)] = 1; (v2)[(q[3] + c)] = q[q[11]+2]; (v7)[((q[3] - c) + 7)] = 1; (v8)[q[3]] = 1; (v3)[q[3]] = 1; q[4] = (((v2)[(q[3] + c)] + c) + 7); L94: q[1] = (q[4] > 5); if ((v3)[q[9]] == 0) goto L111; if ((v7)[((q[9] - c) + 7)] != 0) goto L112; if (q[1] != 0) goto L111; if (q[4] <= 5) goto L111;
int q[13u]; q[10] = 0; q[8] = 0; q[1] = (c + 7); q[4] = 0; q[7] = 0; q[2] = -1; q[11] = 0; L127: if (!q[2]) goto L128; q[11]++; q[2] = (unsigned) q[2] >> 1; goto L127; L128: q[12] = q[11]+q[2]-19; q[11] = q[11] % q[12]; L111: if (q[q[11]+4] >= 8) goto L45; q[3] = q[10]; q[q[11]+2] = ((q[8] + q[7]) + 1); q[9] = (q[10] + 1); q[1] = ((q[1] + c) + 2); q[q[11]+4] = (q[10] + 2); q[7] = ((7 + q[q[11]+2]) - q[1]); if ((v3)[q[3]] == 0) goto L94; q[4] = ((v8)[q[3]] + (v2)[((q[3] - c) + 7)]); if ((v7)[((q[3] - c) + 7)] == 0) goto L94; if (q[7] < 0) goto L96; if (q[7] <= 7) goto L97; L96: q[7] = ((q[3] - c) + 7); L97: if ((v4)[(q[3] + c)] == 0) goto L94; q[1] = (q[8] + (v2)[q[7]]); q[2] = (((c * (c + 1)) * q[3]) % 4); goto L99; L122: if (q[5] <= 0) goto L101; (v4)[(q[3] + c)] = 0; (v2)[((q[3] - c) + 7)] = 0; (v7)[((q[3] - c) + 7)] = 0; (v3)[q[3]] = 0; (v5)[c] = q[3]; (v8)[c] = q[q[11]+2]; q[5] = ((q[5] + 1) != 2);
113
114
L112: if ((v4)[(q[9] + c)] == 0) goto L111; q[6] = (((q[9] + c) * 5) + 1); q[1] = ((q[q[11]] + q[8]) + 1); goto L115; L108: (v2)[((q[9] - c) + 7)] = q[5]; (v4)[(q[9] + c)] = 0; (v8)[q[9]] = (v3)[q[9]]; (v7)[((q[9] - c) + 7)] = 0; q[7] = (q[9] + c); (v3)[q[9]] = 0; q[8] = ((q[5] + q[2]) + 7); (v5)[c] = q[9]; (v8)[c] = q[q[11]+2]; if (c != 7) goto L117; L116: print(); q[1] = (v8)[c]; (v8)[c] = q[4]; goto L118; L117: (v8)[(c + 1)] = q[1]; queens(((c + 1))); L118: q[8] = ((v2)[(q[9] + c)] + q[1]); q[1] = ((q[8] + q[7]) + q[5]); if (((v1)[((((q[9] - c) + 7) ^ q[5]) % 4)] % 4) != 1) goto L120; (v2)[((q[9] - c) + 7)] = ((q[7] + q[9]) - c); (v4)[(q[9] + c)] = 1; q[4] = (q[q[11]+2] + 1); (v8)[q[9]] = 1; (v7)[((q[9] - c) + 7)] = 1; (v3)[q[9]] = 1; q[11] = (q[11] + q[q[11]+6]) % 13; goto L111; L120: q[2] = ((((v7)[(q[9] - c)] + 7) | 1211) % 6); q[4] = (q[8] + ((v7)[(q[9] - c)] | 1211)); q[7] = (q[7] + 1); L99: if ((v6)[q[2]] > (v6)[(q[2] + 1)]) goto L122; (v2)[(q[9] + c)] = ((v6)[q[2]] + c); q[8] = (((q[1] + q[4]) + q[9]) - 7); (v4)[(q[9] + c)] = 1; q[4] = (v8)[q[9]]; (v8)[q[9]] = 1; (v7)[((q[9] - c) + 7)] = 1; q[7] = (q[7] - 1);
115
(v3)[q[9]] = 1; q[q[11]+5] = (q[11] + q[12]) % 13; goto L111; L45: ; }
Граф потока управления замаскированной функции приведён на Рис. 12. На рисунке графа дуги, получившиеся при выполнении преобразования зацепления дуг, имеют большую толщину, а соответствующие базовые блоки выделены серым цветом. В таблице 1 приведены метрики сложности кода для исходной функции queens и для её замаскированного варианта. У замаскированной функции значения всех метрик, кроме метрики сложности графа вызовов выше, чем у исходной функции. Принципы предлагаемого метода маскировки нашли отражение в примере следующим образом: 1. Массив q используется для хранения локальных переменных функции queens. В результате методы анализа потока данных, которые не различают индивидуальные элементы массива, покажут зависимости по данным между всеми операциями с массивом q, то есть между всеми локальными переменными функции queens. 2. Для противодействия алгоритмам анализа потока данных, различающим элементы массива, для доступа к массиву q используется переменная, отображённая в элемент q[11] массива. Переменная инициализируется значением 6 в строках 9–18 функции. Для этого используется константа 32, получаемая в цикле как количество бит в целом слове, и константа 13 – количество элементов в массиве локальных переменных, которое сохраняется в элементе q[12] для последующего использования. Для анализа программы необходимо установить, что элементы q[11] и q[12] являются константами, что в данном случае возможно для методов, различающих элементы массива, но вычисление этих констант потребует интерпретации программы. 3. Для противодействия алгоритмам продвижения констант, которые могли бы распространить константные значения q[11] и q[12] по функции, значение q[11] перевычисляется в строках 82, 129, 145. При этом значение q[11] каждый раз не изменяется. 4. В случае, даже если в результате анализа замаскированной функции удалось выделить каждый элемент массива в отдельную переменную, замаскированная функция всё ещё содержит весь несущественный код, внесённый при маскировке. Алгоритм обнаружения мёртвого кода не даст результатов, из-за использования тождеств в строках 70–79 и 91–96, вносящих ложные зависимости по данным между основной и несущественной частью функции queens. 116
функция CC (Цикломатическая сложность) [14] FC (Сложность по связям) [13] GC (Сложность графа вызовов) SC (Структурная сложность) [13] YC (Зацикленность) DC (Сложность потока данных)
6
преобразования 21
9 2 3 0.595 82
27 2 24 0.8119 8964
Таб. 1. Изменение метрик сложности для замаскированной функции queens.
5.
Кроме того, дополнительные зависимости по данным и дополнительные дуги графа потока управления появляются из-за использования зацепления дуг. Первое зацепление реализовано в строках 36–38 и 131–136, а второе зацепление – в строках 70–73 и 98–100.
7. Заключение В работе представлен новый метод маскировки программ, который обладает следующими отличительными особенностями. 1. Метод существенно увеличивает сложность графа потока управления маскируемых функций за счёт клонирования и расщепления базовых блоков, а также добавления дуг, разрушающих его структурность. 2. Метод существенно увеличивает сложность графа зависимостей по данным маскируемых функций за счёт внесения в тело функции несущественного кода. Основной код функции и введённый несущественный код зависят друг от друга по данным за счёт использования тождеств и указателей. 3. Метод устойчив к известным методам статического анализа программ, так как, в частности, вносит в маскируемую функцию динамические структуры данных. 4. Метод более устойчив к полустатическим методам анализа, чем другие известные методы маскировки функций, так как замаскированная функция не содержит «мёртвых» дуг в графе потока управления. Литература [1] К. Арнольд, Д. Гослинг, Д. Холмс. Язык программирования Java. М.: Вильямс, 2001. [2] Введение в криптографию. Под общей редакцией В. В. Ященко. М.: МЦМНО, 1999.
Рис. 12. Граф потока управления замаскированной функции queens.
Метрика
Исходная
После 117
118
[3] Р. Грэхем, Д. Кнут, О. Паташник. Конкретная математика. Основания информатики. М.: Мир, 1998. [4] Б. В. Керниган, Д. М. Ритчи. Язык программирования Си. СПб.: Невский диалект, 2001. [5] Д. Э. Кнут. Искусство программирования. Том 2. Получисленные алгоритмы. М.: Вильямс, 1998. [6] Б. Страуструп. Язык программирования C++. М.: Бином, 1999. [7] А. В. Чернов. Интегрированная среда для исследования «обфускации» программ. Доклад на конференции, посвящённой 90-летию со дня рождения А. А. Ляпунова. Россия, Новосибирск, 8–11 октября 2001 года. [8] А. В. Чернов. Анализ запутывающих преобразований программ//В сб. «Труды Института системного программирования», под. ред. В. П. Иванникова. М.: ИСП РАН, 2002. [9] B. Barak, O. Goldreich, R. Impagliazzo, S. Rudich, A. Sahai, S. Vadhan, K. Yang. On the (Im)possibility of Obfuscating Programs. LNCS 2139, pp. 1--18, 2001. [10] S. Chow, Y. Gu, H. Johnson, V. Zakharov. An approach to the obfuscation of controlflow of sequential computer programs. LNCS 2200, pp. 144--155, 2001. [11] C. Collberg, C. Thomborson, D. Low. A Taxonomy of Obfuscating Transformations. Departament of Computer Science, The University of Aukland, 1997. http://www.cs.arizona.edu/~collberg/Research/Publications/CollbergThomborsonLow97a [12] C. Collberg, C. Thomborson, D. Low. Breaking Abstractions and Unstructuring Data Structures. In Proc. of the IEEE Internat. Conf. on Computer Languages (ICCL'98), Chicago, IL, May 1998. [13] W. A. Harrison, K. I. Magel. A complexity measure based on nesting level. In SIGPLAN notices, 16(3):63–74, 1981. [14] M. H. Halstead. Elements of Software Science. Elsevier North-Holland, 1977. [15] S. Henry, D. Kafura. Software structure metrics based on information flow. IEEE Transactions on Software Engineering, 7(5): 510--518, September 1981. [16] S. Muchnick. Advanced Compiler Design and Implementation. Morgan Kaufmann Publishers, 1997. [17] B. Schneier. Applied Cryptography: protocols, algorithms and source code in C. Second Edition. John Wiley & Sons, Inc., 1996. [18] C. Wang. A Security Architecture for Survivability Mechanisms. PhD Thesis. Departament of Computer Science, University of Virginia, 2000. http://www.cs.virginia.edu/~survive/pub/wangthesis.pdf [19] G. Wroblewski. General Method of Program Code Obfuscation. PhD Thesis. Wroclaw, 2002.
119
120
Применение формальных методов для тестирования реализации IPv6 Г.В. Ключников, А. С. Косачев, Н.В. Пакулин, А. К. Петренко, В.З. Шнитман Аннотация. В статье представлен опыт разработки тестового набора для реализации протокола IPv6. Для разработки тестового набора использовался метод разработки тестовых наборов на основе формальных спецификаций UniTesK, развиваемый в Институте системного программирования РАН. В качестве объекта тестирования была выбрана реализация IPv6 от Microsoft Research. В статье подробно описывается устройство полученного тестового набора и обсуждаются результаты проекта.
1. Введение В статье представлен опыт разработки тестового набора для реализации протокола IPv6 на Windows 2000. Тестовый набор предназначался для проверки соответствия реализации протокола IPv6 спецификациям IPv6. Проект по разработке тестового набора проходил при поддержке исследовательского гранта Microsoft Research. Разработка тестового набора проводилась с использованием методологии тестирования UniTesK, которая разработана и развивается в Институте системного программирования РАН. В качестве объекта тестирования была выбрана MSR IPv6 – реализация IPv6, разработанная в Microsoft Research. Перед тестовым набором стояла задача проверить, насколько реализация протокола соответствует стандарту протокола. Кроме того, перед разработчиками тестового набора были поставлены следующие цели: • Продемонстрировать применимость формальных методов для специфицирования и тестирования сложного API, такого, как реализация IPv6 •
Исследовать применимость UniTesK к специфицированию и тестированию внутренних подсистем Windows NT или приложений для Windows NT
•
Исследовать применимость UniTesK к тестированию индустриального программного обеспечения
Статья построена следующим образом. Раздел 2 содержит краткое введение в IPv6 и описание функций IPv6, которые мы тестировали. В разделе 3 указаны общие сведения о MSR IPv6 и обсуждаются особенности MSR IPv6 в контексте 121
тестирования. В разделе 4 дано общее описание метода разработки тестовых наборов UniTesK. Раздел 5 посвящен применению UniTesK для тестирования систем с отложенными реакциями. В разделе 6 дано описание устройства тестового набора для MSR IPv6, в разделе 7 перечисляются результаты проекта по разработке тестового набора. Раздел 8 – Заключение.
2. Введение в IPv6. IPv6 – сетевой протокол нового поколения. Он призван заменить существующий протокол сетевого уровня IPv4. IPv6 содержит ряд усовершенствований по сравнению с IPv4 и разрешает проблемы, которые ограничивают дальнейшее развитие сетей на основе IPv4. По эталонной модели OSI [1] протокол IPv6 относится к протоколам сетевого уровня. На этом уровне происходит маршрутизация пакетов на основе преобразования сетевых адресов в адреса канального уровня. Сетевой уровень обеспечивает прозрачную передачу данных между транспортным уровнем и канальным уровнем.
2.1. Функции IPv6, выбранные для тестирования Для тестирования мы выбрали минимальное подмножество функций IPv6, которое обеспечивает корректное функционирование оконечного узла (host).
2.1.1. Отправка и получение пакетов. Протокол обеспечивает обмен данными между протоколами более высокого уровня. Также протокол производит обмен служебными сообщениями сетевого уровня между узлами. Формат пакетов IPv6 и правила обработки пакетов определены в RFC 2460 [2]. При отправке пакета протокола верхнего уровня IPv6 формирует свой собственный пакет, включает в него заданный пакет верхнего уровня и передает полученный пакет IPv6 в сеть. При тестировании мы проверяем, что реализация формирует корректные пакеты IPv6, и данные протокола верхнего уровня передаются в сеть без искажений. При получении пакета из сети реализация IPv6 разбирает пакет. В том случае, если в пакете содержатся ошибки, то реализация отбрасывает пакет или отправляет источнику пакета сообщение об ошибке. Если же пакет корректен, то реализация определяет протокол верхнего уровня, которому адресованы данные, содержащиеся в пакете, и передает их получателю. При тестировании мы проверяем поведение реализации как на корректных пакетах, так и на некорректных пакетах.
2.1.2. Фрагментация и сборка пакетов. Большинство протоколов канального уровня накладывают ограничения на размер передаваемых данных. Так, в сети Ethernet максимальный размер 122
пакета сетевого уровня, который передается в одном кадре Ethernet, равен 1500 байт[3]. Для передачи больших массивов данных в IPv6 предусмотрена функция фрагментации пакетов. Если размер пакета протокола верхнего уровня превосходит максимальный допустимый размер, то реализация IPv6 пересылает такой пакет по частям. Реализация нарезает данные на фрагменты и отправляет каждый фрагмент в отдельном пакете. В точке назначения фрагменты накапливаются, и после получения всех фрагментов из них восстанавливается первоначальный пакет. Фрагментация и сборка пакетов происходит прозрачно для протоколов верхнего уровня. При тестировании мы проверяли, что реализация протокола корректно строит фрагменты, корректно восстанавливает данные из последовательности фрагментов, а также надежно обрабатывает ошибки во фрагментах и сериях фрагментов. Именно в функции сборки фрагментов мы обнаружили наиболее серьезный дефект в MSR IPv6, который приводит к перезагрузке операционной системы.
2.1.3. ICMPv6 ICMPv6 – это протокол, который используется для передачи служебных сообщений на сетевом уровне. В частности, формат пакетов ICMPv6 используются в протоколах Neighbor Discovery (см. далее). Протокол ICMPv6 специфицирован в RFC 2463 [4]. Кроме того, ICMPv6 используется в некоторых протоколах верхнего уровня (например, UDP) для передачи сообщений об ошибках.
2.1.4. ICMPv6 Echo ICMPv6 Echo – это простой диагностический протокол, который используется для определения пропускной способности сети и состояния удаленного узла IPv6. В частности, данный протокол используется в утилите ping. Протокол ICMPv6 Echo является неотъемлемой частью ICMPv6 и определен также в RFC 2463 [4]. Протокол использует формат пакетов ICMPv6. Всего в протоколе два вида сообщений – Echo Request и Echo Reply. При получении Echo Request узел IPv6 должен выслать ответ, Echo Reply, тому узлу, от которого пришел запрос. Таким образом, узел – источник запроса – может установить, что адресат запроса достижим. Если же узел-источник не получит ответа, то либо узеладресат не функционирует, либо сеть перегружена и не в состоянии доставить пакет адресату. При тестировании мы проверяли, что реализация корректно строит пакетызапросы Echo Request, и выдает корректные ответы (Echo Replies) на корректные запросы Echo Request. 123
2.1.5. Neighbor Discovery Neighbor Discovery (ND) объединяет группу протоколов, которые решают следующие задачи: • Определение адресов канального уровня для узлов, которые располагаются на одном сегменте локальной сети (соседей) •
Определение маршрутизаторов, которые подсоединены к сегменту локальной сети
•
Определение того, через какой маршрутизатор следует отправлять пакеты, адресованные узлам за пределами сегмента локальной сети
Для сбора информации о соседних узлах узел IPv6 отправляет и получает служебные пакеты. Всего в ND на данный момент насчитывается пять видов служебных пакетов. Во всех случаях используется формат пакетов ICMPv6. Протокол ND задан в RFC 2461 [5] Для уменьшения нагрузки на сеть собранная информация сохраняется узлом, поэтому на протоколы ND возлагается задача своевременно обновлять сведения соседних узлах и удалять устаревшие записи. При тестировании мы проверяли, что реализация правильно обновляет информацию о соседях, правильно выбирает маршрутизаторы для отправки пакетов за пределы локальной сети, правильно сообщает информацию о себе соседям.
3. MSR IPv6 MSR IPv6 – это свободно распространяемая открытая реализация IPv6 для Windows NT/Windows 2000. Как заявляют разработчики, назначение MSR IPv6 состоит в следующем: 1. Бесплатная общедоступная реализация IPv6 2. Пример реализации протокола сетевого уровня для Windows NT 3. Исследования протоколов IPv6 В MSR IPv6 реализованы основные функции оконечного узла, описанные в предыдущем разделе, а также ряд базовых функций маршрутизаторов IPv6. Кроме того, MSR IPv6 содержит собственную реализацию транспортных протоколов TCP и UDP и интерфейс сокетов для доступа отправки и получения пакетов в сети IPv6. MSR IPv6 может устанавливаться параллельно стеку IPv4 без каких бы то ни было последствий для работоспособности последнего. Более подробную информацию о MSR IPv6 можно получить на сайте Microsoft Research [6] и в работе [7].
124
3.1. Разбиение MSR IPv6 на подсистемы MSR IPv6 отличается хорошей структуризацией исходных текстов. Код, который реализует некоторую функцию IPv6, как правило, сгруппирован в отдельные файлы, и может рассматриваться как отдельная подсистема MSR
Верхний уровень
TCP
UDP ICMP
Ядро IPv6
Send/Receive
Физический уровень
Обозначения:
LAN
ND
Loopback
Тестируемые ф-ции
MLD
Routing
Tunnel
Косвенно тестируются
Не рассматриваются IPv6. На Рис. 1 представлено разбиение MSR IPv6 на подсистемы [7]. Рис. 1. Разбиение MSR IPv6 на подсистемы. В средней части рисунка представлены подсистемы, которые реализуют базовые функции IPv6 – отправка и получение пакетов, ND, ICMPv6. Прямоугольник, помеченный как “Routing”, реализует часть функций Neighbor Discovery, которые относятся к работе с маршрутизаторами. В верхней части рисунка представлены транспортные протоколы, реализации которых имеются в MSR IPv6 – TCP и UDP. В нижней части рисунка расположены подсистемы, которые обеспечивают взаимодействие IPv6 с протоколами нижнего уровня (LAN) и псевдоустройством закольцованной связи (loopback).
Отложенные реакции. Целевая система демонстрирует реакции, которые происходят спустя некоторое время после воздействия извне, причем это реакции нескольких видов. Непроцедурные стимулы. Целевая система допускает как процедурные, так и непроцедурные воздействия. Процедурные воздействия – вызов процедур, которые входят в программный интерфейс. Непроцедурные воздействия – входящие пакеты IPv6, которые целевая система получает из сети. Доступ к процедурным стимулам. Реализация MSR IPv6 расположена по большей части в ядре Windows 2000, поэтому программный интерфейс MSR IPv6 напрямую не доступен. Для обращения к процедурам, которые экспортирует модуль, расположенный в ядре, приходится пользоваться специальными средствами операционной системы. Недетерминизм реакций. Отложенные реакции, вообще говоря, недетерминированы. При одном и том же внешнем воздействии целевая система может демонстрировать различные отложенные реакции. Это связано с тем, что реакции системы определяются составляющими её внутреннего состояния, которые невозможно определить извне, а также с тем, что в ряде алгоритмов IPv6 используются случайные числа. Рассмотрим теперь, какие средства предлагает UniTesK для решения выявленных проблем. Для тестирования систем с отложенными реакциями в UniTesK разработаны методы разработки спецификаций и тестовых сценариев, основанные на формализме конечных автоматов с отложенными реакциями. Механизм медиаторов позволяет отделить модель стимулов от того, как в действительности происходит воздействие на целевую систему. С точки зрения модели не играет никакой роли то, как осуществляется воздействие – путем вызова процедуры, обращения к модулю ядра, отправки пакета в целевой компьютер извне. Конкретное воздействие определяется соответствующим медиатором. В подходе UniTesK используются имплицитные спецификации. Такие спецификации описывают, какие реакции целевой системы и какие изменения в состоянии целевой системы являются допустимыми. Спецификации не вычисляют реакции и конечное состояние целевой системы, а лишь проверяют условия допустимости. Это позволяет описывать недетерминизм поведения целевой системы.
3.2. Особенности тестирования MSR IPv6
4. Введение в UniTesK
Рассмотрим особенности, которые отличают тестирование MSR IPv6 от тестирования обычных программных интерфейсов.
Данный раздел содержит очень поверхностное введение в UniTesK. Более подробное описание можно найти в [8]. С 1994 года в ИСП РАН активно разрабатываются методы и инструменты тестирования программного обеспечения на основе формальных методов.
125
126
В 1994-1999 годах по контрактам с Nortel Networks в ИСП РАН был разработан и активно использовался метод тестирования KVEST [9, 10]. KVEST отличался от обычных методов тестирования индустриального программного обеспечения тем, что в KVEST использовались формальные спецификации в форме пред- и постусловий для построения тестовых оракулов, а также модель конечных автоматов для построения тестовых воздействий. Применение KVEST показало, что формальные методы можно с большим успехом применять при тестировании индустриального программного обеспечения. Опыт применения KVEST показал, что использование академических языков формальных спецификаций и специальных языков описания тестов препятствует встраиванию инструментов, основанных на этих языках, в процесс разработки ПО. Чем ближе язык спецификаций к языку, на котором ведется разработка, тем проще разработчикам писать спецификации и тесты [10]. UniTesK разрабатывался на основе опыта, полученного при разработке и применении KVEST. Рассмотрим основные особенности UniTesK: • Разделение построения тестовых воздействий и проверки правильности поведения целевой системы. Тестовые воздействия строятся в тестовых сценариях, а проверка правильности поведения целевой системы в тестовых оракулах. •
Автоматизированное построение тестовых воздействий.
•
Представление функциональных требований к целевой системе в виде формальных спецификаций.
•
Для записи формальных спецификаций используется язык, «близкий» к языку, на котором разработана целевая система.
•
Автоматическая генерация тестовых оракулов из спецификаций.
•
Оракулы и реализация связаны посредством тонкой прослойки медиаторов.
•
Язык описания тестовых воздействий «близок» к языку, на котором разработана целевая система.
•
Автоматически генерируются критерии качества покрытия требований
•
Автоматически производится оценка качества покрытия требований при прогоне тестов.
В UniTesK ограничения описываются преимущественно в форме имплицитных спецификаций стимулов и реакций. Кроме того, часть ограничений представляется в виде ограничений на значения типов (инварианты типов) и ограничений на значения глобальных переменных (инварианты глобальных переменных). Имплицитные спецификации состоят из пред- и пост- условий. Предусловие содержит требования к тому, в каком состоянии и с какими параметрами можно оказывать воздействие на целевую систему. После воздействия целевая система может продемонстрировать реакции и/или перейти в другое состояние. Постусловие определяет, допустимо ли изменение состояния и продемонстрированное поведение целевой системы. Состояние целевой системы моделируется набором структур данных, которые получили название абстрактное состояние. Пред- и постусловия используют информацию, содержащуюся в абстрактном состоянии, для вынесения вердикта.
4.2. Тестовые сценарии Тестовый сценарий в UniTesK определяет последовательность воздействий, которые оказываются на целевую систему. В UniTesK в качестве теоретической основы для построения тестового сценария выбрана модель конечных автоматов. Тестовый сценарий обладает собственным состоянием, которое, как правило, вычисляется на основе состояния целевой системы. В каждом состоянии задаются воздействия, которые в данном состоянии можно оказать на целевую систему. Тестовый сценарий в процессе работы обходит все состояния и в каждом состоянии оказывает все перечисленные воздействия. I1_1
I1_2 S2 I2_1 I2_2 I3_1
S1
4.1. Оракулы и спецификации
I3_3
S3
Оракулы – это процедуры, которые проверяют выполнение ограничений, наложенных на поведение целевой системы. В UniTesK оракулы полностью автоматически генерируются из описаний ограничений. 127
I3_2 Рис. 2. Пример автомата с тремя состояниями и семью переходами. 128
На Рис. 2 изображен пример тестового сценария, в котором насчитывается три состояния (S1, S2 и S3) и семь воздействий (I1_1, I1_2, I2_1, I2_2, I3_1, I3_2, I3_3). При тестировании тестовый сценарий побывает в каждом состоянии и пройдет по каждой дуге. К сожалению, для большинства целевых систем невозможно получить описание тестового сценария из спецификаций полностью автоматически, без помощи человека. Можно указать следующие причины: • Число состояний целевой системы, как правило, очень велико. •
целевую систему, необходимо перевести параметры воздействия из модельного представления в представление реализации, а после того, как воздействие оказано, необходимо перевести реакции целевой системы в модельное представление. Также необходимо отобразить изменения состояния целевой системы в абстрактном состоянии. В UniTesK медиаторы осуществляют необходимые преобразования, оказывают воздействия на целевую систему и собирают реакции целевой системы.
Число воздействий, которые можно оказать на целевую систему в каждом состояний, как правило, очень велико.
При всем при том, число групп разных состояний, как правило, вполне обозримо. Но критерий различения состояний автоматически определить невозможно, здесь нужна помощь человека – разработчика тестов. Число различных воздействий на целевую систему также намного меньше общего числа воздействий. Из формальных спецификаций можно автоматически получить критерий различения воздействий, но автоматически построить воздействия можно только в простейших случаях. В UniTesK реализован компромиссный подход к разработке тестовых сценариев. Разработчик тестового сценария пишет процедуру различения состояний целевой системы, тем самым определяя классы эквивалентности состояний целевой системы. Каждый класс эквивалентности определяет одно состояние автомата тестового сценария. Разработчик тестового сценария также задает процедуру, которая строит всевозможные тестовые воздействия, то есть переходы автомата тестового сценария. Эти воздействия фильтруются в соответствии с одним из сгенерированных критериев покрытия. Фильтры отсеивают избыточные воздействия, то есть воздействия, которые не улучшают уже достигнутое покрытие. Фильтрация воздействий существенно упрощает написание процедур перебора воздействий. По предоставленным описаниям динамически строится граф состояний автомата тестового сценария. При обходе графа автоматически отслеживается покрытие требований, описанных в спецификациях для генерации отчета о покрытии.
4.3. Медиаторы Под медиаторами в UniTesK понимается промежуточный слой между оракулами и реализацией. Необходимость введения медиаторов вызвана тем, что в UniTesK воздействия на целевую систему и реакции целевой системы описываются в терминах модели, содержащейся в спецификациях. Перед тем как оказать воздействие на 129
S1
S2
Рис. 3. Пример цепочки реакций между двумя стационарными состояниями.
5. Применение UniTesK к тестированию систем с отложенными реакциями Как сказано выше, целевая система может демонстрировать реакции спустя некоторое время после того, как на неё было оказано воздействие. Мы называем такое поведение отложенными реакциями. Как правило, неудобно моделировать отложенные реакции посредством обычных конечных автоматов. Для облегчения моделирования систем с отложенными реакциями в UniTesK введено представление об автоматах с отложенными реакциями [11]. Автоматы с отложенными реакциями отличаются от обычных конечных автоматов тем, что переходы в между состояниями представляют собой цепочку реакций. Как правило, целевая система демонстрирует реакции нескольких различных видов. Например, у реализации сетевого протокола есть как минимум два вида реакций – пакеты, которые отправляется в сеть, и пакеты, которые передаются на верхний уровень. Для регистрации отложенных реакций целевой системы тестовая система содержит так называемые кетчеры. Кетчеры, как видно из названия, «хватают» (catch) реакции целевой системы и передают их в тестовую систему. В тестовой системе должны быть кетчеры для каждого вида реакций. Реакции могут регистрироваться с запозданием, причем для реакций различных типов величина задержки может быть различной. Тестовой системе необходимо определить допустимый порядок реакций различных видов. Процедура определения допустимой последовательности реакций называется 130
сериализацией. В процессе сериализации тестовая система строит различные цепочки реакций и проверяет их допустимость. Каждая реакция рассматривается как переход между промежуточными состояниями, конечное состояние последней реакции рассматривается как последнее состояние в цепочке реакций и принадлежит множеству состояний конечного автомата. Если при сериализации не удалось найти ни одной допустимой последовательности реакций, то тестовая система выносит вердикт о рассогласовании модели и целевой системы – набор зарегистрированных реакций не соответствуют спецификации. Сериализация реакций происходит после того, как все реакции целевой системы получены. Это накладывает ограничения на спецификации и технику тестирования. Во-первых, при разработке спецификаций используется подход «черного ящика», при котором внутреннее состояние целевой системы недоступно, и его приходится моделировать в спецификациях. Во-вторых, на целевую систему накладывается жесткое ограничение на стационарность начальных и конечных состояний. Рассмотрим последнее требование более подробно. Сериализация производится после того, как собраны все реакции на воздействие. Это означает, что существует такой интервал времени T0, что в течение T0 с момента оказания воздействия целевая система продемонстрирует все реакции на воздействие. Состояние, в которое перейдет целевая система, обладает тем свойством, что нем система не демонстрирует спонтанных (то есть без воздействия извне) реакций. Такие состояний называются стационарными. Реализованный в UniTesK метод тестирования систем с отложенными реакциями требует, чтобы в любом состоянии конечное состояние для любого допустимого в данном состоянии воздействия было стационарным, причем существует верхняя грань времени ожидания реакций по всем состояниям и воздействиям. Кроме того, алгоритм обхода графа состояний автомата тестового сценария требует, чтобы воздействие на целевую систему оказывалось только из стационарного состояния. Несмотря на жесткость указанных ограничений, UniTesK применим для тестирования широкого класса систем с отложенными реакциями. В частности, как показал анализ документации, протокол IPv6 удовлетворяет требованию на стационарность конечных состояний, поэтому UniTesK можно использовать для построения тестовых наборов для IPv6.
6. Использование UniTesK для тестирования MSR IPv6 Тестовый набор разрабатывался средствами реализации UniTesK для языка С – CTesK-lite. CTesK-lite поддерживает разработку спецификаций на 131
спецификационном расширении языка С – SEC (Specification Extension of C language). В CTesK-lite реализована архитектура тестового набора UniTesK – тестовые сценарии, оракулы, медиаторы. Реализована поддержка тестирования систем с отложенными реакциями. SEC – это ANSI C, к которому были добавлены ряд конструкций, характерных для академических языков формальных спецификаций. В частности, в SEC реализованы пред- и постусловия, инварианты типов данных и глобальных переменных, описатели доступа (access descriptors). Из спецификаций на языке SEC генерируется код на языке С, который затем компилируется обыкновенным компилятором С (в нашем случае MS VC 6.0). Для разработки и сборки тестового набора мы использовали MS Visual Studio 6.0. Проверка синтаксиса и семантики для SEC не реализована, но синтаксические ошибки в спецификациях можно идентифицировать по ошибкам, которые компилятор С находит в сгенерированном коде. Далее в данном разделе приведены краткие описания компонентов тестового набора.
6.1. Спецификации Спецификации можно рассматривать как формальное представление требований к целевой системе. В наших спецификациях мы формализовали требования, взятые из стандартов IPv6. В основном, требования извлекались из [2-5], но использовался также ряд других RFC. Спецификации представляют собой формализованную запись требований, изложенных в RFC. Чтобы сохранить прослеживаемость требований, в тесте спецификаций расставлялись ссылки на соответствующие полуформальные требования из RFC. Благодаря этому по расхождениям между реализацией и моделью, выявленным при прогоне тестов, можно определить, какое требование из RFC нарушено в реализации.
6.2. Абстрактное состояние Абстрактное состояние – это множество структур данных, которые моделируют внутреннее состояние целевой системы. Все действия, которые выполняет целевая система, моделируются в терминах абстрактного состояния. Документация на IPv6 не содержит требований к внутреннему устройству реализации IPv6. Абстрактное состояние было спроектировано таким образом, чтобы предоставить удобные концептуальные структуры данных для спецификаций стимулов и реакций. Абстрактное состояние для MSR IPv6 включает следующие элементы: • Множество исходящих пакетов IPv6. Это множество моделирует множество пакетов, которые реализация передает канальному уровню. 132
•
Набор очередей входящих дейтаграмм UDP. Очереди используются для моделирования получения данных клиентами UDP.
тестирование отправки пакетов производилось преимущественно посредством отправки пакетов UDP.
•
Пул фрагментов. Пул фрагментов используется для двух целей: (1) мы моделируем процедуру сборки пакетов в целевой системе; (2) мы проверяем, что из фрагментов, которые выпускает целевая система, получатель сможет воссоздать оригинальный пакет.
6.3.2. Спецификация непроцедурных стимулов
•
Набор таблиц Neighbor Discovery. Эти таблицы используются при моделировании алгоритмов Neighbor Discovery.
6.3. Спецификации стимулов 6.3.1. Спецификация процедурных стимулов Мы специфицировали два процедурных стимула: • Отправить пакет UDP •
Отправить ICMPv6 Echo Request
Спецификация «Отправить пакет UDP» моделирует отправку данных через UDP сокет. У данного стимула есть следующие параметры: адрес узла назначения, адрес узла отправителя (так как узел IPv6 может иметь более одного адреса), номер порта получателя и данные, которые необходимо отправить. Спецификация утверждает, что в сеть будет отправлен пакет IPv6 с заданным исходным адресом и заданным адресом назначения, который содержит пакет UDP на указанный порт и с указанными данными. Данная спецификация нацелена на проверку функции отправки пакетов в сеть. Так как точка доступа к упомянутой функции расположена глубоко внутри модуля IPv6, то для тестирования мы воспользовались функцией-посредником. В качестве посредника был выбран протокол UDP, так как UDP (в отличие от TCP) практически не обладает собственной внутренней функциональностью, и запрос на отправку пакета UDP почти точно отображается на запрос на отправку пакета IPv6. Спецификация «Отправить ICMPv6 Echo Request» моделирует протокол ICMPv6 Echo, описанный в [4]. У данного стимула есть следующие параметры: адрес узла назначения, адрес узла отправителя (так как узел IPv6 может иметь более одного адреса) и данные, которые необходимо отправить в пакете ICMPv6 Echo Request. Спецификация утверждает, что в сеть будет отправлен пакет IPv6 с заданным исходным адресом и заданным адресом назначения, который содержит пакет ICMPv6 Echo Request с указанными данными, и что все пакеты Echo Reply, которые придут в ответ на запрос, будут доставлены в процесс, инициировавший запрос. Спецификация «Отправить ICMPv6 Echo Request» также имеет отношение к функции отправки пакетов. Но, поскольку у данного стимула имеется сложная внутренняя функциональность, не связанная с отправкой пакетов, то 133
Алгоритм обхода графа состояний автомата тестового сценария, реализованный в CTesK-lite, требует, чтобы воздействия на целевую систему оказывались только в стационарных состояниях. Протокол IPv6 не удовлетворяет указанному ограничению, так как некоторые внешние воздействия (входящие пакеты) могут оказываться в нестационарных состояниях. Например, в протоколе ICMPv6 Echo узел испускает пакет ICMPv6 Echo Request и переходит в нестационарное состояние, в котором ожидает входящего пакета ICMPv6 Echo Reply. Таким образом, внешнее воздействие – пакет ICMPv6 Echo Reply – необходимо оказать в нестационарном состоянии. Для того, чтобы обойти ограничение на стационарность начального состояния, непроцедурные стимулы были специфицированы как отложенные реакции на некоторые процедурные стимулы. Мы ввели стимул «Отправить пакет IPv6 в целевую систему». Спецификация для данного стимула тривиальна. Медиатор для данного стимула отправляет пакет IPv6 с удаленного узла. Собственно входящий пакет рассматривается как отложенная реакция на данный стимул.
6.4. Спецификации реакций MSR IPv6 демонстрирует два вида отложенных реакций - исходящие пакеты IPv6 и входящие пакеты UDP, то есть данные, которые получают клиенты протокола UDP. Кроме того, по техническим причинам мы моделировали как реакции и входящие пакеты IPv6 (см. обсуждение выше). Спецификация для исходящих пакетов IPv6 проверяет следующее: • Все пакеты, которые целевая система отправляет в сеть, удовлетворяют требованиям на формат пакетов, изложенным в соответствующих RFC. •
Все фрагменты, которые целевая система отправляет в сеть, можно собрать в пакет IPv6.
•
Корректность данных для некоторых видов пакетов (например, UDP и ICMPv6).
Спецификация для входящих пакетов IPv6 разбирает входящие пакеты IPv6. Если в пакете нет ошибок, то спецификация определяет получателя данного пакета и моделирует получение данных пакета получателем. Если в пакете обнаружена ошибка, то спецификация определяет, какое сообщение об ошибке следует послать. Спецификация для входящих пакетов IPv6 также моделирует сборку пакетов из фрагментов. В спецификации восстанавливается исходный пакет, и моделируется доставка восстановленного пакета получателю. 134
Спецификация для входящих дейтаграмм UDP проверяет, что дейтаграмма получена в правильном сокете, и что данные получены без искажений.
6.4.1. Спецификация фрагментации Функция фрагментации формально относится к функции отправки пакета в сеть. Тем не менее, спецификация стимулов не описывает фрагментацию. Проверка правильности фрагментации возложена на спецификацию для исходящих пакетов. Данная спецификация проверяет, что из фрагментов можно собрать оригинальный большой пакет, собирает большой пакет и затем проверяет, что полученный пакет соответствует одному из пакетов, которые были созданы по запросу протокола верхнего уровня.
6.4.2. Спецификация Neighbor Discovery Подсистема Neighbor Discovery не содержит входных точек, доступных извне модуля MSR IPv6. ND обрабатывает входящие пакеты и сохраняет информацию о соседних узлах во внутренних таблицах. При отправке IPv6 пакета в сеть соответствующая подсистема IPv6 запрашивает у ND информацию об узле назначения пакета. В результате такого запроса ND может выслать один или более служебных пакетов. Спецификация для входящих пакетов распознает пакеты Neighbor Discovery и определяет, какая информация должна сохраняться в таблицах Neighbor Discovery. Спецификация для исходящих пакетов IPv6 проверяет следующее: 1. Реализация отправляет пакеты известным узлам. 2. Реализация производит поиск соседа перед отправкой пакетов незнакомым соседним узлам. 3. Реализация не отсылает пакеты, если Neighbor Discovery не в состоянии найти узел адресат. 4. Реализация правильно определяет, какие узлы находятся на том же сегменте локальной сети, а какие находятся вне сегмента локальной сети. 5. Реализация находит маршрутизаторы в локальной сети и корректно обновляет информацию о маршрутизаторах. Заметим, что спецификация не старается предсказать, на какой узел локальной сети будет выслан пакет. Вместо этого спецификация проверяет, что узел, выбранный реализацией, соответствует информации, собранной Neighbor Discovery на момент отправки пакета.
6.5. Транспорт стимулов и реакций В данном разделе описывается, как тестовая система оказывает воздействие на целевую систему (MSR IPv6) и собирает реакции целевой системы. 135
6.5.1. Медиаторы для процедурных стимулов Тестовая система работает на том же компьютере, что и целевая система. Благодаря этому медиаторы для процедурных стимулов устроены просто. Медиатор для отправки дейтаграммы UDP вызывает процедуру sendto для отправки указанных данных по указанному адресу через указанный сокет. После того, как sendto возвращает управление, медиатор анализирует возвращенное значение и, при необходимости, код ошибки и формирует собственное возвращаемое значение (OK/FAIL). Медиатор для функции Echo Request обращается к соответствующей точке доступа транспортного драйвера MSR IPv6. После завершения вызова медиатор анализирует возвращенное значение и, при необходимости, код ошибки, сохраняет данные ответа (Echo Reply) и формирует собственное возвращаемое значение (OK/FAIL)
6.5.2. Медиаторы для непроцедурных стимулов Как упоминалось выше, в интерфейс целевой системы входят непроцедурные стимулы – пакеты IPv6, которые поступают в целевую систему из сети. Медиатор для непроцедурных стимулов представляет собой распределенное приложение, реализованное в рамках архитектуры клиент-сервер. Клиент – тестовая система – передает серверу запрос, в котором содержится IPv6 пакет и адрес узла назначения. Сервер, который работает на некотором узле в том же сегменте сети, что и целевой узел, пересылает указанный пакет по указанному IPv6 адресу. Для того, чтобы обмен запросами между клиентом и сервером не оказывал воздействия на целевую систему, запрос серверу передается по сети IPv4.
6.5.3. Сбор реакций целевой системы Сбор реакций целевой системы осуществляют специальные программы, которые называются кетчерами. Как было сказано выше, MSR IPv6 демонстрирует два вида отложенных реакций – исходящие IPv6 пакеты и UDP датаграммы, которые получают в сокетах.
6.5.3.1. Входящие и исходящие пакеты IPv6 Кетчер для входящих/исходящих пакетов IPv6 перехватывает кадры Ethernet, в которых передаются пакеты IPv6. Кетчер реализован как модуль расширения Microsoft Network Monitor. Кетчер не разбирает кадры Ethernet, а передает их в тестовую систему. Заметим, что кетчер не умеет отличать исходящие кадры от входящих. В тестовой системе перехваченные кадры преобразуются. Тестовая система извлекает из кадра вложенный в него пакет IPv6 и определяет, является пакет входящим или исходящим. При этом формируется специальная структура 136
данных, которая используется в спецификациях для представления пакетов IPv6.
2.
6.5.4. Входящие дейтаграммы UDP
3.
При старте тестовая система открывает несколько сокетов и запускает кетчер, который слушает открытые сокеты. Когда в один из сокетов прибывает дейтаграмма, кетчер получает дейтаграмму и определяет ее исходный.
4. 5. 6.
6.6. Тестовые сценарии В ходе проекта были разработаны 15 тестовых сценариев. Приблизительно тестовые сценарии можно разделить на 4 группы: • Тесты на отправку пакетов. Тесты из данной группы проверяют, как целевая система передает пакеты верхнего уровня в сеть. Также производится проверка того, как реализация проводит нарезку больших пакетов на фрагменты. •
Тесты на получение пакетов. Тесты из данной группы проверяют, как целевая система обрабатывает различные входящие пакеты. Тестируются функция сборки фрагментов и доставка пакетов протоколам верхнего уровня. Значительное место занимает проверка того, как система обрабатывает поданные на вход некорректные пакеты.
•
Тесты для функции ICMPv6 Echo. Тесты из данной группы проверяют корректность реализации простого диагностического протокола Echo, встроенного в ICMPv6.
•
Тесты для Neighbor Discovery. Тесты из данной группы проверяют, что реализация Neighbor Discovery соответствует требованиям, изложенным в RFC 2461 [5].
Заметим, что представленное разделение нестрогое, и отдельные тестовые сценарии можно отнести сразу к нескольким группам. Тестовые сценарии для MSR IPv6 осуществляют два вида тестирования: • тестовые сценарии проверяют корректность работы целевой системы на корректных входах; •
тестовые сценарии проверяют устойчивость целевой системы по отношению к ошибкам во входных пакетах IPv6.
6.7. Процесс разработки тестового набора Процесс разработки тестового набора для MSR IPv6 можно разделить на несколько фаз: 1. Определение интерфейса. 137
Разработка спецификаций для отправки и получения пакетов без Neighbor Discovery. Разработка и прогон тестовых сценариев для отправки и получения пакетов без Neighbor Discovery. Пополнение спецификаций функцией Neighbor Discovery. Разработка и прогон тестовых сценариев для Neighbor Discovery. Прогон всего полученного тестового набора.
На фазе определения интерфейса был определен состав функций IPv6 для тестирования, и определены стимулы и реакции, относящиеся к выбранным функциям. Разработка спецификаций проводилась в два этапа. На первом этапе были разработаны спецификации, в которых не моделировалось поведение Neighbor Discovery. Для полученных спецификаций были разработаны и отлажены тестовые сценарии. Протоколы Neighbor Discovery предназначены для сбора и обновления информации о конфигурации сегмента локальной сети, к которой подключен узел IPv6. В спецификациях и тестовых сценариях, которые мы разработали на первом этапе, конфигурация сети предполагалась заданной и неизменной во времени. Это предположение позволило разработать и отладить довольно содержательные тестовые сценарии для функций отправки и получения пакетов и ICMPv6. На втором этапе мы добавили спецификации протоколов Neighbor Discovery. Для отладки полученных спецификаций мы воспользовались предположением, что сценарии, разработанные для спецификаций без ND, должны корректно работать и для спецификаций с ND. Избранная нами стратегия себя оправдала. При прогоне тестовых сценариев, разработанных на первом этапе, было выявлено и исправлено много недочетов в спецификациях Neighbor Discovery. После того, как спецификации Neighbor Discovery были отлажены, были разработаны тестовые сценарии специально для Neighbor Discovery.
7. Результаты Был разработан тестовый набор для реализации протокола IPv6. Тестовый набор был пропущен на Windows 2000, в качестве целевой системы выступала реализация IPv6 от Microsoft Research (MSR IPv6 version 1.4). Проект по разработке тестового набора для MSR IPv6 показал применимость UniTesK для тестирования сложного API с непроцедурными стимулами и отложенными реакциями. Также показана применимость UniTesK для тестирования внутренних подсистем ядра Windows 2000. 138
В ходе тестирования были обнаружены отклонения от стандартов IPv6 и ошибки программирования. Отклонения от стандартов заключаются в том, что в ряде случаев поведение MSR IPv6 отличается от требований, изложенных в стандартах на IPv6. При тестировании мы выявили также дефекты, которые можно охарактеризовать как ошибки, допущенные при программировании.
7.1. Выявленные дефекты При тестировании мы обнаружили, что в реализации алгоритма сборки фрагментов в MSR IPv6 присутствует ошибка. При получении последовательности фрагментов определенного вида в модуле MSR IPv6 возникает исключительная ситуация, которая приводит к краху ядра операционной системы и перезагрузке Windows 2000. В MSR IPv6 некорректно спроектирован интерфейс доступа к функции ICMPv6 Echo Request. Клиентский процесс, инициировавший запрос, блокируется до прибытия первого ответа (Echo Reply) или до истечения таймаута. Если на запрос поступили ответы, то первый ответ возвращается клиенту, а все остальные отбрасываются. Такое поведение не соответствует требованию передавать клиенту все поступившие ответы [4]. В одном частном случае реализация алгоритма сборки фрагментов в MSR IPv6 нарушает одно из требований, изложенное в RFC 2460 [2]. RFC требует, чтобы служебная информация, которая передается во фрагментах, не попадала в восстановленный пакет. Тестирование показало, что для фрагментов определенного вида MSR IPv6 оставляет служебную информацию в восстановленном пакете. Более подробное описание выявленных дефектов можно найти в [12].
7.2. Оценка покрытия кода целевой системы Для точного определения покрытия кода целевой системы необходимо пропустить тесты на отладочной версии ядра Windows 2000 с включенным профилировщиком ядра. Это сделано не было, поэтому оценка покрытия кода получена косвенным методом. Мы составили список всех процедур, которые есть в целевой системе, и для каждой процедуры оценили, будет ли она вызываться при прогоне тестов. Оказалось, что 20% процедур в целевой системе не будут вызываться при прогоне тестов; как правило, эти процедуры реализуют функции IPv6, исключенные из рассмотрения при разработке тестового набора. 60% процедур реализуют выбранные нами функции IPv6; эти процедуры должны вызываться при пропуске тестов. Про остальные 20% мы затрудняемся сказать что-либо определенное; как правило, это вспомогательные процедуры. Итого получается оценка покрытия исходных текстов 60-80%. 139
8. Заключение Проект по разработке тестового набора для MSR IPv6 продемонстрировал применимость UniTesK для тестирования сложного API на платформе Win32. UniTesK был использован для тестирования системы, расположенной в ядре Windows 2000. Интерфейс целевой системы содержит непроцедурные стимулы и отложенные реакции. Были выявлены ошибки в системе, которая уже несколько лет находилась в эксплуатации и проходила испытания другими тестовыми наборами. Литература 1. Information technology -- Open Systems Interconnection -- Basic Reference Model. ISO/IEC 7498, 1994 2. S. Deering, R. Hinden. Internet Protocol, Version 6 (IPv6) Specification. RFC 2460, December 1998 3. M. Crawford. Transmission of IPv6 Packets over Ethernet Networks. RFC 2464, December 1998 4. A. Conta, S. Deering. Internet Control Message Protocol (ICMPv6) for the Internet Protocol Version 6 (IPv6) Specification. RFC 2463, December 1998 5. T. Narten, E. Nordmark, W. Simpson. Neighbor Discovery for IP Version 6 (IPv6). RFC 2461, December 1998 6. http://research.microsoft.com/msripv6/ 7. R. P. Draves, A. Mankin, B. D. Zill. Implementing IPv6 for Windows NT. Proceedings of the 2nd USENIX Windows NT Symposium, Seattle, WA, August 3–4, 1998 8. I. Bourdonov, A. Kossatchev, V. Kuliamin, A. Petrenko. UniTesK Test Suite Architecture. Proceedings of FME 2002. LNCS 2391, pp. 77-88, Springer-Verlag, 2002. 9. I. Bourdonov, A. Kossatchev, A. Petrenko, D. Galter. KVEST: Automated Generation of Test Suites from Formal Specifications. FM’99: Formal Methods.LNCS, volume 1708, Springer-Verlag, 1999, pp. 608–621. 10. И. Б. Бурдонов, А. В. Демаков, А. С. Косачев, А. В. Максимов, А. К. Петренко. Формальные спецификации в технологиях обратной инженерии и верификации программ. Труды Института системного программирования, 1999 г., том 1, стр. 35-47 11. И.Б.Бурдонов, А.С.Косачев, В.В.Кулямин. Асинхронные автоматы: классификация и тестирование. В данном сборнике 12. I.Agamirzian, S.G.Groshev, A.V.Khoroshilov, G.N.Kluchnikov, A.S.Kossatchev, V.A.Omelchenko, N.V.Pakoulin, A.K.Petrenko, V.Z. Shnitman. MSR IPv6 verification project. Technical report, December 2001
140
Методы и технологии реинжиниринга ИС К.В. Ахтырченко, Т.П. Сорокваша Аннотация. Сегодня можно говорить, что эра, когда разработчики информационных систем приходили в организацию и начинали проекты информатизации «с нуля», прошла. Большинство организаций уже имеет некоторые информационные системы (ИС), которые со временем начинают требовать целенаправленной деятельности по их реинжинирингу. В настоящей статье исследуются существующие подходы, методы и технологии реинжиниринга ИС, предлагается подход к их классификации. На основании результатов исследований и вводимой классификации дается оценка текущего состояния в данной области. Ключевые слова: реинжиниринг ИС, методы и технологии реинжиниринга ИС, подход к классификации методов и технологий реинжиниринга, модернизация ИС, миграция ИС, эволюция ИС, реструктуризация ИС, унаследованные ИС.
1. Введение Результаты исследований состояния информатизации в различных организациях позволяют сделать вывод, что в настоящий момент большинство из них уже имеет некоторые информационные системы (ИС). Эти ИС в различной степени автоматизируют процессы, протекающие в организациях. Исследования проектов информатизации, и, в первую очередь, проектов разработки ИС так же показывают, что создание новой информационной системы в большинстве случаев предусматривает изменение состояния существующих ИС. Типичными стали проекты: по разработке новых ИС и их интеграции с существующими ИС; по разработке новых ИС с целью замены существующих ИС; по модернизации (наращиванию функциональности, развитию) существующих ИС. По сути, сегодня можно говорить, что эра, когда разработчики ИС приходили в организацию и начинали проекты информатизации «с нуля», прошла. Наступает время проектов по систематической трансформации существующих ИС или эра реинжиниринга ИС. Следствием сложившейся ситуации становится объективная потребность в исследовании, пересмотре и переосмыслении существующих подходов, методологий и технологий разработки ИС, что, в свою очередь, может потребовать их модернизации, а возможно, и разработки новых решений. 141
Ситуация осложняется тем, что в настоящий момент различными исследователями и практиками понятие реинжиниринга ИС трактуется по разному. Во многом это обусловлено необычайно широким спектром задач по реинжинирингу, с которыми приходится сталкиваться в реальных проектах. Сегодня в мире существует большое количество подходов, методов и технологических решений, напрямую или косвенно соотносимых с деятельностью по реинжинирингу ИС. Однако они не интегрированы на уровне методологий (процессов разработки). Как результат, можно наблюдать наличие огромного количества методологий, где основной акцент сделан на разработку ИС «с нуля», и практическое отсутствие «стройных» методологий, целью создания которых являлось бы комплексное, целостное решение задач реинжиниринга ИС. В настоящей статье исследуются существующие подходы, методы и технологии реинжиниринга ИС, предлагается подход к их классификации. На основании результатов исследований и вводимой классификации дается оценка текущего состояния в данной области. Заметим, что в процессе написания статьи не ставилась цель исследовать все решения в области реинжиниринга ИС, представить детальную информацию по каждому из них. В то же время авторами была предпринята попытка рассмотреть основные подходы, методы, технологии и инструментальные средства, которые характеризуют состояние дел в данной области. Детальную информацию об интересующих решениях можно найти в литературе, ссылки на которую представлены в конце статьи, а так же на следующих Web – сайтах: http://www.informatik.uni-stuttgart.de/ifi/ps/reengineering/ http://www.iam.unibe.ch/ http://www.stsc.hill.af.mil/reng/ http://www.sei.cmu.edu/reengineering/index.html http://www.tcse.org/revengr/
2. Понятие «реинжиниринга ИС», его содержание и место в ЖЦ ИС Существует ряд работ [1, 2, 5, 9, 10, 13, 15, 16, 20, 34-36], в которых в различной степени определяется соотносимая с реинжинирингом ИС деятельность, выявляется и исследуется место реинжиниринга в ЖЦ ИС.
2.1. Понятие «реинжиниринга ИС» Сразу следует признать, что в настоящий момент понятие «реинжиниринг ИС» не является повсеместно устоявшимся. Как следствие довольно часто возникает определенная терминологическая путаница. Авторами исследуются одни и те же проблемы, подходы, методы и технологии их решения, однако в качестве базовых понятий, наряду с «реинжинирингом ИС» [1, 9, 16, 20] употребляются 142
«эволюция ИС» [10, 13], «миграция ИС» [15], «модернизация ИС» [2], «реструктуризация ИС» [5]. Нельзя отрицать, что деятельность по миграции ИС имеет определенную специфику (окраску) по отношению к деятельности по модернизации ИС. Однако, принимая во внимание определение реинжиниринга ИС, приводимое в [1]: «Реинжиниринг представляет собой систематическую трансформацию существующей системы с целью улучшения ее характеристик качества, поддерживаемой ею функциональности, понижения стоимости ее сопровождения, вероятности возникновения значимых для заказчика рисков, уменьшения сроков работ по сопровождению системы», становится очевидным, что и миграция, и модернизация ИС являются частью деятельности по реинжинирингу ИС. Как результат, подходы, методы и технологии миграции, модернизации, эволюции ИС, следует считать частью методологического и инструментально-технологического обеспечения процесса реинжиниринга ИС. Такой взгляд на реинжиниринг ИС согласуется с таксономией, вводимой в ряде работ [34, 36, 38-40]. В этих работах авторами делается попытка выстроить систему понятий, соотносимых с данным видом деятельности. Так, в [38] реинжиниринг ИС определяется как «исследование (изучение, обследование) и перестройка исходной системы с целью ее воссоздания в новой форме с последующей реализацией этой новой формы»1. Далее, в контексте деятельности по реинжинирингу вводятся и определяются такие важные понятия, как: прямой инжиниринг (Forward engineering); редокументирование (Redocumentation); рефакторинг (Refactoring); реструктуризация (Restructuring); переориентация (Retargeting); обратный инжиниринг (обратное проектирование) (Reverse engineering); сопровождение программных продуктов (Software maintenance); трансляция исходного кода (Source Code Translation); и т.д. Перечисленные понятия раскрывают понятие «реинжиниринг ИС», а соотносимая с ними деятельность рассматривается либо как одна из форм реинжиниринга ИС, либо как подпроцесс процесса реинжиниринга. Определения этих и других понятий приводятся в приложении к данной статье в глоссарии понятий и терминов. При этом в тех случаях, когда проявлялись отличия в определении того или иного понятия, в глоссарий включались альтернативные варианты определения, а при необходимости, и поясняющие определение комментарии. 1
Далее в настоящей работе при исследовании существующих решений употребляется оригинальная терминология, предлагаемая авторами работ. При этом в качестве рабочего варианта используется определение реинжиниринга ИС, приводимое в [1].
143
2.2. Основное содержание реинжиниринга ИС и его место в ЖЦ ИС Следующим шагом на пути исследования подходов, методов и технологий реинжиниринга ИС следует считать определение основного содержания деятельности по реинжинирингу ИС, места реинжиниринга в ЖЦ ИС. Так, в [1] авторы придерживаются следующей позиции при определении границ деятельности по реинжинирингу, и, как следствие, места реинжиниринга в ЖЦ ИС. Утверждается, что реинжиниринг ИС занимает промежуточное местоположение по отношению к разработке и сопровождению ИС. При этом сопровождение ИС рассматривается как деятельность, предусматривающая выполнение изменений, направленных на коррекцию, усовершенствование и адаптацию ИС, а разработка ИС как деятельность, включающая реализацию новых возможностей, добавление новой функциональности, осуществление таких существенных улучшений, как переход на использование новых компьютеров, внедрение новых информационных технологий. Авторами правомерно утверждается, что реинжиниринг характеризуется деятельностью, как по сопровождению, так и по разработке ИС. При этом эти два вида деятельности в контексте реинжиниринга ИС могут существенно перекрываться. В отличие от [1], работа [2] посвящена вопросам модернизации унаследованных информационных систем. В ней делается обзор различных методик модернизации унаследованных систем, определяется роль модернизации систем в процессе управлениях их эволюцией. Утверждается, что коммерческий рынок предлагает разнообразные решения проблемы модернизации унаследованных систем, которая становится все более актуальной. В сложившейся ситуации понимание преимуществ и слабых мест каждой такой методики является чрезвычайно важным, поскольку обуславливает выбор правильного решения, и как следствие успех деятельности по модернизации системы. В контексте исследований, связанных с эволюцией ИС, авторами выделяются деятельности по сопровождению, модернизации и замещению ИС. Определяется, что сопровождение представляет собой инкрементальный итеративный процесс, в рамках которого выполняются малые изменения в системе, не затрагивающие структурной организации системы (архитектуры системы). В отличие от сопровождения, модернизация характеризуется как деятельность, которая предусматривает значительные изменения существующей системы (в том числе в ее структуре), но не ее утилизацию или замещение новой системой. И, наконец, замещение рассматривается как процесс, который заключается во внедрении новой системы, способной полностью заменить существующую ИС. Замещение обычно применяется к системам, которые недокументированны, 144
устарели или не расширяемы, расходятся с требованиями бизнеса и для которых модернизация невозможна или экономически не выгодна. Определяя место этих видов деятельности в контексте ЖЦ ИС, авторы рассматривают следующую последовательность их выполнения (см. Рис. 1).
Рис. 1. Жизненный цикл ИС. Первоначально, осуществляется разработка (построение) ИС. Далее выполняется деятельность по ее сопровождению. В процессе сопровождения возникает необходимость в реструктуризации системы и как следствие выполняется деятельность по ее модернизации. После этого снова осуществляется деятельность по сопровождению системы. В тот момент, когда ИС перестает удовлетворять заказчика, осуществляется ее замещение на новую систему и последовательность выполняемых видов деятельности повторяется. Безусловно, в реальной жизни может возникать и другая последовательность, когда, сразу, не прибегая к модернизации, осуществляется замещение одной ИС другой. Однако общий подход к последовательности выполнения сопровождения, модернизации и замещения останется неизменным. Приводимые в [2] виды деятельности основаны на таксономии, вводимой в [16]. В отличие от предыдущей работы, в [16] в качестве базового понятия используется именно «реинжиниринг», а вводимая таксономия рассматривается как множество видов деятельности, соотносимых с реинжинирингом ИС. Применительно к унаследованным ИС выделяются виды деятельности по оценке, сопровождению, трансформации, замещению ИС, а также используются смешанные стратегии, предусматривающие совместное выполнение перечисленных видов деятельности. 145
Обеспечивая концептуальное понимание процесса реинжиниринга ИС, в ряде работ [1, 9] определяются основные виды деятельности (фазы), соотносимые с этим процессом. Так, в [1] рассматриваются следующие основные фазы: оценки показателей проекта по реинжинирингу, в том числе характеристик унаследованной информационной системы (фаза оценки); анализа решений по реинжинирингу, в том числе принятие решения о необходимости проведения работ по реинжинирингу или сопровождению/разработке ИС; осуществления реинжиниринга (выполнения работ по реинжинирингу); внедрения системы, трансформированной в результате проведения реинжиниринга. Другой подход к определению деятельности по реинжинирингу базируется на так называемой модели «подковы» [9, 21]. В основу данной модели положены следующие процессы (виды деятельности), соотносимые с реинжинирингом ИС: анализ существующей системы, основанный на одном или более ее логических описаний; трансформация этих логических описаний в новое, улучшенное логическое описание системы. разработка новой системы, основанной на новых логических описаниях системы. Эти три основных процесса соединяются в модели в виде «подковы» (см. Рис. 2). Трансформация архитектуры
Образы проектирования и архитектурные стили Планы программ Стили кодирования
Унаследованные исходные коды
Исходные коды новой системы
Рис.2. Модель «подковы». Первый процесс (Architecture Recovery) предусматривает восстановление архитектуры существующей системы посредством извлечения на основании 146
исходного кода характеризующих ее артефактов. Полученная архитектура анализируется на предмет соответствия требованиям к изменяемости, надежности, защищенности и так далее. Второй процесс (Architecture Transformation) заключается в трансформации (реинжиниринге) восстановленной архитектуры к желаемой новой архитектуре. Полученная в результате трансформации новая архитектура оценивается с позиции ее качества с учетом накладываемых на нее организационных и экономических ограничений. И, наконец, третий процесс (Architecture-based Development) включает деятельность по разработке системы, соответствующей новой архитектуре. Здесь решаются вопросы декомпозиции элементов системы по пакетам, осуществляется выбор стратегий взаимодействия элементов/компонентов системы. В рамках данного процесса так же обеспечивается интеграция в новую систему артефактов унаследованной системы, например, посредством переписывания части унаследованного кода и/или применения технологии построения оболочек для компонентов унаследованной системы. С моделью «подкова» соотносится три уровня, на каждом из которых может осуществляться трансформация существующей системы. Представление на уровне структуры кода (Code-Structure Representation) включает программный код, а так же такие артефакты, как абстрактные синтаксические деревья и графы потоков (flow graphs), получаемые на основании выполнения различного рода аналитических операций (например, разбора кода). Текстуальный перевод, а так же перевод на основе синтаксических деревьев являются примерами трансформации системы на этом уровне. В отличие от предыдущего уровня, представление на уровне функциональности системы (Function-Level Representation) предусматривает определение связей между функциями программ (например, последовательности вызовов), данными (как частный случай, связей между сущностями данных, соотношений данных и функций) и файлами (к примеру, распределение функций и данных по файлам). Трансформация системы на данном уровне осуществляется на основании пересмотра функциональности системы и заключается, например, в переходе от функционального подхода к анализу и проектированию к объектному подходу, в переходе от реляционной БД к объектной БД. На архитектурном уровне артефакты предыдущих уровней, объединяются в подсистемы в терминах архитектурных компонентов архитектуры ИС. Трансформация системы на этом уровне предусматривает коренные изменения в структуре программы, в том числе в части применения основных образцов взаимодействия компонентов: типов программных компонентов, используемых соединителей (connectors), вариантов декомпозиции функциональности, образцов управления и обмена данными времени выполнения. 147
Согласно модели «подкова» трансформация системы, в зависимости от ситуации, может осуществляться на каждом из представленных уровней, при этом более низкий уровень поддерживает трансформацию на более высоком уровне. Следует признать, что модель «подкова» находит широкое применение в рамках деятельности, связанной с реинжинирингом ИС. Так, в [20] на ее основе определяются требования и основной каркас для интеграции инструментальных средств реинжиниринга на архитектурном уровне и уровне программного кода. С учетом соотносимых с ней процессов и уровней представления, осуществляется расширение модели CORUM (Common Object-based Reengineering Unified Model). Эта модель, в свою очередь, разрабатывалась: для представления требуемой для систем управления на основе программного кода (Code-based Management System) информации о программных средствах; для обеспечения интероперабельности между системами данного класса (в том числе между средствами реинжиниринга программ на уровне программного кода). В контексте вводимых расширений в этой же работе для модели «подкова» определяется семантическая модель, обеспечивающая на основании формулируемых унифицирующих свойств семантическую связь между архитектурным уровнем и уровнем программного кода. Подход, предложенный в [34-36], очень близок к подходу, основанному на модели «подкова». Характеризуя жизненный цикл реинжиниринга ИС, авторы определяют следующие шаги процесса реинжиниринга: анализ требований для выявления конкретных целей реинжиниринга унаследованной системы; восстановление модели, в том числе документирование и понимание структуры унаследованной системы; выявление проблем, связанных с унаследованной системой; анализ проблем, включающий выбор архитектуры, позволяющий устранить обнаруженные в унаследованной системе дефекты; реорганизация, включающая выбор и применение оптимального подхода трансформации унаследованной системы; распространение изменений. В отличие от предыдущих работ, в [10, 13] деятельность по реинжинирингу рассматривается в качестве одной из форм деятельности по эволюции унаследованных ИС, когда, требуется более сильнодействующее «лекарство» для «лечения» ИС, нежели серия локальных инкрементальных изменений [13]. Так, в [13] описывается каркас (enterprise framework), характеризующий: глобальную среду, в которой осуществляется эволюция системы; действия, процессы и рабочие продукты (артефакты), которые сопровождают деятельность по эволюции системы. 148
Авторами подчеркивается, что помимо технических вопросов, связанных с эволюцией унаследованных ИС, существует так же множество организационных вопросов. Например, «Как планировать эволюцию большой сложной системы, включая ее реинжиниринг?», «Какие существуют критичные факторы успеха эволюции системы?», «Как оценить, что люди, осуществляющие эволюцию системы, на правильном пути?». Кроме этого, важным является необходимость учета стратегических, организационных, и других аспектов бизнеса, влияющих на эволюцию унаследованной ИС. Поэтому основной целью создания каркаса (enterprise framework) следует считать необходимость оценки среды, в рамках которой осуществляется эволюция унаследованной ИС, необходимость обеспечения понимания широкого спектра вопросов, как технического, так и управленческого характера, которые соотносятся с эволюцией унаследованных ИС. Важнейшим здесь становится выявление факторов, определяющих успех деятельности по эволюции ИС, а так же разработка согласованного множества технических и управленческих инструкций (действий), требуемых для эффективного планирования, оценки и управления инициативами по эволюции систем. Отражая, применительно к эволюции системы, пространство проблем и пространство решений, предлагаемый в [13] каркас включает такие элементы, как организация, проект, унаследованная система, инженерия систем и программных средств, технологии, целевая система. Между этими элементами определяется связь. При этом для каждого из них приводится список вопросов (checklists), позволяющий охарактеризовать (исследовать и оценить) интересующий элемент. Следует признать, что положенная в основу каркаса концепция является расширением концепции разработки ИС с учетом деятельности по внедрению, повседневных операций и деятельности по сопровождению. Каркас может быть использован для выполнения следующих видов деятельности: исследование и анализ пространства проблем и пространства решений в контексте инициатив по эволюции системы; разработка руководств по составлению стратегических и тактических планов по реинжинирингу унаследованных систем; выявление технологических вопросов и потенциальных проблем на протяжении всего пути по эволюции систем; рецензирование планов, ранжирование (приоритезация) технических вопросов, разработка рекомендаций по улучшениям процессов эволюции систем и результатов их выполнения (рабочих продуктов). Общий подход к использованию каркаса представлен на Рис. 3.
149
Рис. 3. Общий подход к использованию каркаса. В рамках подхода выделяются две значительные составляющие: основная фаза и фаза эволюции. Основная фаза сфокусирована на таких элементах, как организация, проект и унаследованная система. Фаза эволюции концентрируется на целевой системе, инженерии систем и программных средств, технологиях, используемых для построения целевой системы. Другими словами, первая фаза сфокусирована на пространстве проблем, а вторая на пространстве решений. В [10] авторами предлагается комплексный, основанный на рассмотренном ранее каркасе, подход к эволюции систем, который определяется в контексте унаследованных систем и современных программных технологий. В основу подхода положены следующие положения (принципы): различие между эволюцией систем и сопровождением программных средств; использование описанного ранее каркаса (enterprise framework) при поддержке принятия решений в процессе эволюции системы; достижение технического понимания систем на высоком уровне абстракции; применение технологий распределенных объектов, технологии «wrapping» [10] для эволюции системы; применение «net-centric» [10] вычислений для эволюции системы. 150
Определяя различие между сопровождением программных средств и эволюцией систем в части реинжиниринга ИС, авторы рассматривают сопровождение как «мелкозернистую», «краткосрочную» деятельность, направленную на планирование и внесение локализованных изменений. При сопровождении структура (архитектура) системы остается относительно неизменной, а требуемая «порция» вносимых за определенный промежуток изменений, как правило, связана с изменением какого-либо одного требования к системе. Такие изменения, обычно, не сопровождаются существенным изменением значений характеристик и атрибутов качества программных средств. В отличие от сопровождения, эволюция систем рассматривается как «крупнозернистая», «высокоуровневая», форма изменений на уровне структуры (архитектуры) системы. Вносимые в процессе эволюции изменения, приводят к изменениям значений атрибутов качества, что, как правило, существенно упрощает сопровождение систем. Для этого при внесении изменений в структуру системы могут использоваться стратегии «снизу вверх» и «сверху вниз», применение которых основано на ревизии программного кода, восстановлении описания архитектуры унаследованной системы, проектировании новой структуры, новой формы документации и т.д. Авторами подчеркивается, что эволюция позволяет адаптировать систему сразу с учетом большого количества выдвигаемых к ней требований (включая приобретение новых возможностей), что в конечном итоге увеличивает стратегическую и экономическую значимость программных средств. При этом акцент смещается от понимания программ к пониманию систем, от сопровождения к эволюции и миграции, от стратегий «снизу вверх» к стратегиям «сверху вниз». В отличие от рассмотренных ранее работ, в [15] основное внимание уделяется исследованию и решению технических проблем, связанных с миграцией унаследованных систем. Характеризуя понятие «миграция ИС» в данной работе выделяются отдельно эволюция, сопровождение и миграция ИС. Основываясь на том факте, что объектом эволюции и сопровождения является унаследованная ИС, а объектом миграции как унаследованная, так и новая (целевая) системы, авторы разделяют миграцию и другие процессы ЖЦ ИС. При этом миграция рассматривается как деятельность, которая начинается с унаследованной ИС и заканчивается сопоставимой целевой ИС. В основу предлагаемого авторами подхода положена декомпозиция структуры системы на компоненты пользовательского интерфейса, компоненты – приложения и компоненты управления базами данных. При этом в качестве основных инкрементально выполняемых шагов миграции выступают: анализ унаследованной ИС; декомпозиция структуры унаследованной ИС; проектирование интерфейсов (пользовательских и системных) целевой системы; 151
проектирование приложений (функциональной логики) целевой системы; проектирование базы данных целевой системы; развертывание среды, требуемой для эксплуатации и сопровождения целевой системы; создание и развертывание необходимых шлюзов; миграция унаследованных данных; миграция унаследованных приложений (компонентов, реализующих функциональную логику); миграция унаследованных интерфейсов (пользовательских и системных); переход к использованию целевой системы.
3. Классификация подходов, методов и технологий. В настоящий момент существует значительное количество работ, посвященных проблемам, методам и технологиям реинжиниринга ИС. Эти работы охватывают данную проблематику с различных точек зрения, рассматривая и исследуя в различной степени как проблемы концептуального уровня (иногда даже философского характера), так и конкретные методы, и инструментальные средства, предназначенные для реинжиниринга ИС. Несмотря на наличие множества различных решений, их исследование и комплексное применение на практике бывает затруднено. Причинами возникающих трудностей следует считать: понятие «реинжиниринг ИС» различными исследователями до сих пор трактуется по разному, существует множество близких понятий, наличие которых приводит к появлению внешне отличающихся, но по сути схожих подходов, методов и технологий; предлагаемые решения не позиционируются в контексте других существующих решений; решения не интегрированы на уровне методологий и технологий, большое количество методов и инструментальных средств направлено на решение отдельных локальных задач, связанных с реинжинирингом ИС; наблюдается разрыв между решениями концептуального характера и решениями, направленными на решение конкретных прикладных задач. Следует признать, что на множестве существующих решений (подходов, методов и технологий) отсутствует их систематизация, обеспечивающая позиционирование и определяющая взаимосвязь решений на различных уровнях рассмотрения задач реинжиниринга, в том числе, уровнях методологии и инструментальных средств.
152
В сложившейся ситуации целесообразным видится определение классификации, определяющей структуризацию на множестве существующих подходов, методов и технологий реинжиниринга ИС. Так, классифицируя существующие подходы, методы и технологии, можно выделить следующие уровни рассмотрения и исследования аспектов, соотносимых с деятельностью по реинжинирингу ИС (см. Рис. 4). УРОВЕНЬ 6 Технология реинжиниринга ИС
УРОВЕНЬ 5 Методология реинжиниринга ИС
УРОВЕНЬ 1 Понятие «реинжиниринг ИС», место реинжиниринга в ЖЦ ИС УРОВЕНЬ 2 Процесс реинжиниринга ИС, связи между шагами процесса УРОВЕНЬ 3 Методы решения локальных задач, возникающих при реинжиниринге ИС КЛАСС 1 Методы, не зависящие от конкретной программной технологии КЛАСС 2 Методы, ориентированные на использование УРОВЕНЬ 4 Инструментальные программные средства
Рис. 4. Уровни рассмотрения и исследования аспектов, соотносимых с реинжинирингом ИС. Первый уровень включает исследования, направленные на достижение концептуального понимания деятельности по реинжинирингу ИС. Именно на этом уровне исследуются вопросы адекватного определения понятия «реинжиниринг ИС», определения места реинжиниринга в жизненном цикле (ЖЦ) ИС, в том числе выявление связей процесса реинжиниринга ИС в целом с другими процессами ЖЦ ИС. Следует считать, что большая часть рассмотренных ранее аспектов, относятся к этому уровню. В отличие от первого, второй уровень содержит исследования, основная цель которых заключается в выявлении основных шагов (действий), реализуемых в процессе реинжиниринга и в определении связей между основными шагами процесса. Здесь в сферу рассмотрения попадают потоки управления и потоки данных между основными шагами процесса, основные роли, соотносимые с исполнителями процесса, а так же правила распределения ролей среди команды 153
исполнителей. Исследования и разработки на этом уровне проводятся как без учета, так и с учетом вводимых ограничений (например, архитектурных решений, которым должны соответствовать подлежащие реинжинирингу ИС). Следует признать, что наиболее детально вопросы, связанные с данной проблематикой, исследуются в [1, 15, 33], в меньшей степени в [8, 13, 16, 20]. Так, в [1] выделяются основные фазы процесса реинжиниринга ИС, а для каждой фазы определяются действия (деятельности) и соотносимые с ними потоки управления. Процесс дается в самом общем виде и не зависит от какихлибо ограничений, например используемых программных технологий. В [15] авторами так же определяется выполняемый в рамках процесса реинжиниринга поток работ. Однако здесь основное внимание уделяется вопросам технического характера, а выполняемые при реинжиниринге шаги предусматривают декомпозицию структур, соответственно, унаследованной и целевой системы на компоненты пользовательского интерфейса, компоненты – приложения и компоненты управления базами данных. В отличие от предыдущих работ в [33] авторами основной акцент сделан на решение задач оценки унаследованных систем и поддержки принятия решений при реинжиниринге ИС. Авторами определяется процесс оценки, состоящий из следующих входящих в его состав процессов (подпроцессов): технической оценки (Reengineering Technical Assessment), экономической оценки (Reengineering Economic Assessment), принятия управленческих решений (Reengineering Management Decision). Для каждого из процессов описывается его область применения, поток входящих в него работ (шагов процесса), определяются связи с другими процессами оценки. Следует признать, что потенциально эти процессы могут быть интегрированы в любой процесс разработки. Однако стоит заметить, что оценка унаследованных систем является лишь одной из задач по реинжинирингу ИС. Еще одним примером процесса, направленного на решение локальной задачи, является итеративный процесс, определяющий следующую последовательность шагов, которые должны быть выполнены при планировании проектов реинжиниринга ИС [37]: Определение целей, направлений деятельности организации и информационной системы.
154
Формирование объединенной команды, которая осуществлять реинжиниринг унаследованной системы.
Определение среды разработки и сопровождения, базирующейся на применении CMM (Capability Maturity Model).
Выбор стандартного множества метрик для оценки программных средств.
будет
Анализ унаследованной системы.
Определение процесса реинжинирингу.
Разработка/Обновление валидации.
Анализ средств реинжиниринга.
Обучение.
реализации
стандартных
деятельности
средств
тестирования
по и
На третьем уровне рассматриваются (исследуются и разрабатываются) методы, каждый из которых направлен на решение некоторой локальной задачи, возникающей в процессе реинжиниринга ИС, например, выполнения определенного шага процесса. По сути, эти методы воплощают собой некоторые вполне конкретные решения, с которыми соотносится определенная область применения. Как правило, в проектах по реинжинирингу применятся некоторая комбинация таких методов, при этом каждый из них может стать частью методологии реинжиниринга ИС, но в отдельности таковой не является. Более того, объединение этих методов так же нельзя рассматривать в качестве методологии, поскольку между ними не определены связи, обеспечивающие их интегральную целостность. Другими словами отсутствуют системообразующие факторы, делающие набор методов целостным образованием – системой. С некоторой условностью все методы реинжиниринга ИС можно разделить на два класса. Методы, относящиеся к первому классу, определены на концептуальном уровне и, в целом, не зависят от какой-то одной программной технологии. Так, в [2] дается обзор методов модернизации и миграции унаследованных систем. Среди всего множества рассматриваемых методов к первому классу относятся метод репликации баз данных и основанный на объектно-ориентированном подходе метод построения оболочек для компонентов унаследованной системы (object – oriented wrapping), методы «белого» и «черного» ящика модернизации системы. Другими представителями данного класса являются: методы оценки вариантов реинжиниринга ИС [9, 11, 33], метод планирования миграции программных средств [8], методы извлечения знаний о существующей системе [3, 4, 17], методы трансформации (реконструкции) архитектуры ИС [3, 7, 19, 21], методы автоматизации реинжиниринга программ [6, 23] и т.д. В целом следует считать, что область применения таких методов, как правило, характеризуется некоторым классом программных технологий. А для применения в реальных проектах каждый из них адаптируется с учетом используемых в проекте технологий и инструментальных средств. Отдельным направлением исследований, относящимся к данному классу и получившим развитие в последние годы, является исследование и разработка образцов реинжиниринга ИС [26-30, 36]. Каждый из образцов реинжиниринга ИС нацелен на решение некоторой типовой задачи (проблемы), которая 155
сопровождает деятельность по реинжинирингу ИС. Не смотря на некоторые отличия, авторы в целом придерживаются единого подхода к описанию таких образцов. Так, в [26] определяется следующий шаблон описания. - Имя образца. - Цели применения. - Область приложения. - Мотивация к применению. - Структура системы до и после применения образца. - Процесс применения образца. - Обсуждение образца. - Особенности, зависящие от языка программирования. Стоит заметить, что хотя последний из разделов шаблона «привязывает» шаблон к определенной среде реализации, языкам программирования, все же каждый из образцов представляет некоторое концептуальное решение проблемы. Подробную информацию об образцах реинжиниринга можно найти в книге «Object-Oriented Reengineering Patterns» [27]. В отличие от первого класса, методы второго изначально ориентированы на использование определенных программных технологий. Ко второму классу относятся так же адаптации методов из первого класса. Здесь методы в наибольшей степени приспособлены к их непосредственному (прямому) применению в конкретных проектах. Примерами методов данного класса следует считать [2]: методы интеграции с использованием CGI, методы интеграции на основе технологии XML, метод построения оболочек для компонентов унаследованной системы с использованием технологии CORBA. И наконец, четвертый уровень включает исследование и разработку инструментальных программных средств, автоматизирующих применение подходов, методов и технологий, рассматриваемых на предыдущих уровнях. Следует признать, что в настоящий момент таких средств существует большое количество, среди которого выделяются следующие [3, 4, 6, 23, 31, 32, 35]: средства переноса приложений, написанных на устаревших языках, на современные языки и платформы (например, с языков PL/1, Кобол на языки C++, Java, Visual Basic); средства интеграции унаследованных приложений, к примеру, на основе метода построения оболочек для компонентов унаследованной системы; средства автоматизированного извлечения данных из унаследованных систем; средства автоматизированного извлечения знаний об унаследованных системах; средства оптимизации (реструктуризации) унаследованных систем при их переносе на современные языки и платформы (как на уровне программного кода, так и на уровне архитектуры ИС); 156
различные средства анализа программного кода.
Полезная классификация инструментальных средств дается в [31]. В рамках этой классификации выделяются такие типы средств, как: средства реинжиниринга бизнес процессов; средства преобразования имен данных; средства реинжиниринга данных (БД); средства прямого инжиниринга; средства преобразования форматов; средства реструктуризации; средства обратного проектирования; средства трансляции исходного кода; и др. В этой же работе авторами приводятся характеристики инструментальных средств реинжиниринга ИС. Для каждого из них специфицируется имя программного продукта; требования к аппаратной и программной платформе; координаты компаний-поставщиков; поддерживаемые языки программирования, СУБД, платформы; принадлежность к тому или иному типу средств. Осуществляя классификацию и исследование существующих подходов, методов и технологий реинжиниринга ИС, дополнительно к уже выделенным уровням, следует добавить еще два, являющихся по своей природе интегральными. Это уровень методологии и уровень технологии реинжиниринга ИС. Первый из них обеспечивает целостное рассмотрение и применение подходов и методов без учета среды их реализации, специфики конкретных проектов. Это соответствует интеграции первых трех уровней, причем на третьем уровне в сферу рассмотрения, в первую очередь, попадают методы первого класса. Уровень технологии обеспечивает адаптацию (конкретизацию) методологии реинжиниринга ИС с учетом среды реализации, специфики конкретных проектов посредством применения методов и инструментальных средств, соответствующих третьему и четвертому уровням. При этом в отличие от методологии, на третьем уровне, прежде всего, рассматриваются методы второго класса. Следует признать, в процессе проводимых авторами настоящей статьи исследований не было обнаружено целостных методологий и технологий реинжиниринга ИС, соответствующих уровню проработки и области охвата RUP [24, 25]. В наибольшей степени эту проблема исследуется в [1, 8, 15, 33]. В тоже время, в [1] предлагается лишь каркас, определяющий основной ход работ, в [8] даются рекомендации по выполнению основных видов деятельности по реинжинирингу. В [33] определяются лишь процессы оценки унаследованных систем, а в [15] основное внимание уделяется вопросам технического характера, при этом основной акцент сделан на решение проблем интеграции систем, в то 157
время как методы анализа унаследованной системы практически не рассматриваются. Представленный подход к классификации обеспечивает систематизацию на множестве существующих подходов, методов и технологий реинжиниринга ИС. В качестве его основных областей применения следует рассматривать: оценку состояния в области методологического и технологического обеспечения реинжиниринга ИС; адаптацию и разработку методологий и технологий реинжиниринга ИС. В завершении данного раздела стоит отметить, что возможны и другие полезные подходы к систематизации методов и технологий реинжиниринга ИС. Так, предлагаемые и исследуемые различными авторами процессы реинжиниринга, как правило, охватывают систему в целом, в то время как методы могут соотноситься с некоторыми ее составляющими, с отдельными шагами процесса. Последний факт обуславливает возможность классификация многих методов: по объектам применения (например, в зависимости от их типа (компонент пользовательского интерфейса, компонент данных, вычисляющий компонент (компонент бизнес - логики))); по видам деятельности процесса реинжиниринга (методы извлечения знаний о существующих ИС (методы обратного проектирования), методы оценки (анализа) существующих ИС и т.д.).
4. Заключение. На основании проведенных исследований и вводимой классификации подходов, методов и технологий реинжиниринга ИС, становится возможным охарактеризовать текущее состояние в области его методологического и технологического обеспечения. Так, несмотря на наличие большого количества работ, охватывающих данную проблематику с различных точек зрения, следует признать, что: понятие «реинжиниринг ИС» различными исследователями до сих пор трактуется по разному, существует множество близких понятий, наличие которых приводит к появлению внешне отличающихся, но по сути схожих подходов, методов и технологий; существующие методы и технологии не позиционируются в контексте других существующих решений, не интегрированы на уровне методологий и технологий; наблюдается разрыв между решениями концептуального характера и решениями, направленными на решение конкретных прикладных задач; отсутствует четкая взаимосвязь между методами/технологиями реинжиниринга и методологиями разработки ИС «с нуля». В сложившейся ситуации актуальной задачами становятся: 158
унификация, а возможно, и стандартизация понятия «реинжиниринг ИС», других связанных с ним понятий; разработка целостных методологий реинжиниринга ИС; разработка средств адаптации методологий реинжиниринга ИС в реальных проектах; создание инструментальных средств, обеспечивающих комплексное решение задач по реинжинирингу ИС; интеграция методологий разработки «с нуля» и методологий реинжиниринга, в том числе и на уровне поддерживающих их инструментальных средств.
Литература 1. John Bergey, William Hefley, Walter Lamia, Dennis Smith A Reengineering Process Framework, Software Engineering Institute, Carnegie Mellon University, Pittsburgh, 1995. 2. Santiago Comella-Dorda, Kurt Wallnau, Robert C. Seacord, John Robert A Survey of Legacy System Modernization Approaches, Software Engineering Institute (Technical Note CMU/SEI-200-TN-003, 00tn003.pdf), Pittsburgh, 2000. 3. Rick Kazman, S. Jeromy Carriere Playing Detective: Reconstructing Software Architecture from Available Evidence. Technical Report CMU/SEI-97-TR-010. Pittsburgh, 1997. 4. Rick Kazman, S. Jeromy Carriere View Extraction and View Fusion in Architectural Understanding, Proceedings of the Fifth International Conference on Software Reuse (ICSR), June, 1998, Victoria, BC. 5. Кротов А.А. и Лупян Е.А. Обзор методов реструктуризации и интеграции информационных систем, http://d902.iki.rssi.ru/students/alekro/Dissertation/Papers/Reengineering/my_review.html 6. "Автоматизированный реинжиниринг программ" Сборник статей под ред. А.Н.Терехова и А.А.Терехова Издательство С.-Петербургского университета, 2000. 7. Guo G. Y., Atlee J. M., Kazman R. A Software Architecture Reconstruction Method, Department of Computer Science, University of Waterloo, Software Engineering Institute, Carnegie Mellon University. 8. John Bergey, Dennis Smith, Nelson Weiderman DoD Legacy System Migration Guidelines, Software Engineering Institute, Carnegie Mellon University, Pittsburgh, September 1999. 9. John Bergey, Dennis Smith, Nelson Weiderman, Steven Woods Options Analysis for Reengineering (OAR): Issues and Conceptual Approach, Software Engineering Institute, Carnegie Mellon University, Pittsburgh, September 1999. 10. Weiderman N., Nelson H., Bergey John K., Smith Denis B., & Tilley Scott R. Approaches to Legacy System Evolution, Software Engineering Institute, Carnegie Mellon University, Pittsburgh, PA 15213, 1997 (CMU/SEI-97-TR-014) 11. Ransom J., Sommerville I., & Warren I. A Method for Assessing Legacy Systems for Evolution, Proceedings of the Second Euromicro Conference on Software Maintenance and Reengineering (CSMR98), 1998 12. Bisdal Jesus, Lawless Deirdre, Wu Bing, Grimson Jane, Wade Vincent, Richardson Ray, & O'Sullivan D. An Overview of Legacy Information System Migration, APSEC 97, ICSC 97, 1997
159
13. John K. Bergey, Linda M. Northrop, Dennis B. Smith Enterprise Framework for the Disciplined Evolution of Legacy Systems, SEI CMU October 1997. 14. Энн Мак-Крори Что такое унаследованные системы?, Computerworld, США, 1998. 15. Michael L. Brodie, Michael Stonebraker Migrating Legacy Systems. Gateways, Interfaces & The Incremental Approach, Morgan Kaufmann Publishers, Inc., 1995 16. Weiderman N., Northrop L., Smith D., Tilley S., Wallnau K. Implications of Distributed Object Technology for Reengineering, CMU/SEI-97-TR-005, SEI CMU June 1997. 17. Tilley S. A Reverse-Engineering Environment Framework, SEI CMU April 1998 18. Bergey J., Smith D., Tilley S., Weiderman N., Woods S. Why Reengineering Projects Fail, SEI CMU April 1999. 19. Kazman R., O’Brein L., Verhoef Ch. Architecture Reconstruction Cuidelines, SEI CMU August 2001. 20. Kazman R., Woods S., Carriere S. Requirements for Integrating Software Architecture and Reengineering Models: CORUM II, SEI CMU, October 1998. 21. Carriere S.J., Woods S. Kazman R. Software Architectural Transformation, Software Engineering Institute, Carnegie Mellon University, Pittsburgh, October 1999. 22. John Bergey, Dennis Smith, Nelson Weiderman DoD Software Migration Planning, Software Engineering Institute, Carnegie Mellon University, Pittsburgh, August 2001. 23. www.ispras.ru 24. Kruchten P. The Rational Unified Process: an introduction. Reading: Addison Wesley, 1999. 25. Rational Unified Process, version 2002.05.00.25, Rational Software Corporation. 26. Ducasse S., Richner Т, Nebbe R. Type-Check Elimination: Two Object-Oriented Reengineering Patterns, Proceedings WCRE, 1999. 27. Demeyer S., Ducasse S. , Nierstrasz O. Object-Oriented Reengineering Patterns, Morgan Kaufmann Publishers, Inc., 2002. 28. Ducasse S. , Demeyer S., Nierstrasz O. A Pattern Language for Reverse Engineering, Proceedings of EuroPLoP, 2000. 29. Pooley R., Stivens P. Software Reengineering Patterns, University of Edinburg, Department of computer science, http://www.reengineering.ed.ac.uk/. 30. Dewar R. Characteristics of Legacy System Reengineering, The University of Edinburgh, Division of Informatics, http://www.reengineering.ed.ac.uk/. 31. Olsem M. R., Sittenauer Ch. Reengineering, Software Technology Support Center, Technology Report, Volume 2, April 1995, http://www.stsc.hill.af.mil/reng/. 32. Ducasse S., Lanza M, Tichelaar S. The Moose Reengineering Environment, University of Berne, Software Composition Group, 2001. 33. Software Reengineering Assessment Handbook, Technical Report, Version 3.0, 1997, http://www.stsc.hill.af.mil/ 34. Sander T. Modeling Object-Oriented Software for Reverse Engineering and Refactoring, Thesis, University of Bern, 2001. 35. Ducasse S. R´etro-Conception d’Application `a Objets Reengineering Object-Oriented Applications, Universit´e Pierre et Marie Curie, 2001. 36. The FAMOOS Object-Oriented Reengineering Handbook, http://www.iam.unibe.ch/_famoos/handbook/. 37. Olsem M. R., Sittenauer Ch. Reengineering, Software Technology Support Center, Technology Report, Volume 1, April 1995, http://www.stsc.hill.af.mil/reng/. 38. IEEE Computer Society TCSE, 1990, http://tcse.org/. 39. Стандарт ANSI/IEEE Std. 729-1983.
160
40. Joint Logistic Commanders Computer Resources Management group (JLC/CRM), 1992, http://www.stsc.hill.af.mil/reng/.
Приложение А. Глоссарий понятий и терминов. Реинжиниринг бизнес-процессов (Business Process Reengineering) Фундаментальное переосмысление и радикальное перепроектирование бизнеспроцессов для достижения существенных улучшений в таких ключевых для современного бизнеса показателях результативности, как затраты, качество, уровень обслуживания и оперативность [40]. Рационализация имен данных (Data name rationalization (DNR)) Унификация именования данных, являющаяся специальным случаем реинжиниринга данных. Заключается во введении унифицирующих соглашений по именованию во всех программных системах [40]. Реинжиниринг данных (Data Reengineering) Выполнение всех функций реинжиниринга, соотносимых с исходным кодом, но применительно к файлам данных [40]. Восстановление результатов проектирования (Design recovery) Подмножество обратного инжиниринга, в котором знание проблемной области, внешняя информация, логические выводы или нечеткие суждения принимаются во внимание при обследовании исходной системы. Целью восстановления результатов проектирования является выявление значимых высокоуровневых абстракций, в дополнение к тем, которые были получены в процессе непосредственного исследования (изучения) системы [38]. Прямой инжиниринг (Forward engineering) Традиционный процесс перехода от высокоуровневых абстракций и логического, независящего от реализации проектирования к физической реализации системы [38]. Представляет собой переход от требований к высокоуровневому проектированию, и далее к низкоуровневому проектированию и реализации [36]. Представляет собой множество видов деятельности по инжинирингу системы, на вход которым для производства новой целевой системы поступают продукты и артефакты, производные от унаследованных программных средств, и новые требования [40]. Комментарий Основное отличие прямого инжиниринга от реинжиниринга заключается в том, что в случае реинжиниринга «стартуют» от существующей реализации (существующей системы). Основное отличие прямого инжиниринга от инжиниринга в целом заключается в том, что на вход прямого инжиниринга поступают результаты реинжиниринга [40]. Редокументирование (Redocumentation) Форма реструктуризации, где результирующее семантически эквивалентное представление системы является альтернативным взглядом, предназначенным для его восприятия человеком [38]. Процесс анализа системы с целью создания различного рода сопровождающей ее документации. Включает в себя как создание руководств пользователя, так и переформатирование листинга исходного кода [40]. Реинжиниринг (Reengineering) 161
Исследование (изучение, обследование) и перестройка исходной системы с целью ее воссоздания в новой форме с последующей реализацией этой новой формы [38]. Комментарий Процесс реинжиниринга включает в себя такие подпроцессы, как обратный инжиниринг, реструктуризация, редокументирование, прямой инжиниринг и переориентация [40]. Как правило, предполагает модернизацию системы в целях обеспечения ее соответствия возникающим новым требования [36]. Рефакторинг (Refactoring) Специальный вид реструктуризации, а именно реструктуризации на уровне программного кода, имеющей объектно-ориентированный контекст. Является процессом изменения программной системы, направленным на улучшение внутренней структуры программного кода, но не изменяющим внешнего поведения программы [34, 36]. Реструктуризация (Restructuring) Трансформация системы из одной формы представления в другую на одном и том же уровне абстракции. Новое представление сохраняет семантику и внешнее поведение (функциональность) оригинала [38, 40]. Переориентация (Retargeting) Процесс трансформации и перевода (переноса) существующей системы в новую конфигурацию [40]. Комментарий Например, перенос на новую аппаратную платформу, под новую операционную систему, под новое CASE - средство. Обратный инжиниринг (обратное проектирование) (Reverse engineering) Процесс анализа исходной системы, преследующий 2 цели – выявить компоненты системы и отношения между ними, и создать представление системы в другой форме или на более высоком уровне абстракции [38]. Процесс достижения понимания системы, ее анализа и абстрагирования по направлению к новой форме представления, соответствующей более высокому уровню абстракции [40]. Процесс извлечения информации из существующей программной системы [36]. В общем случае обратное проектирование применяют для извлечения информации на высоком уровне абстракции, например, извлечение информации уровня проектирования из программного кода. Сопровождение программных продуктов (Software maintenance) Модификация программного продукта после его поставки в целях исправления ошибок, улучшения производительности и других атрибутов качества, или адаптации продукта к изменениям окружения (внешней среды) [39]. Трансляция исходного кода (Source Code Translation) Трансляция исходного кода с одного языка программирования на другой или с одной версии в другую на том же самом языке программирования [40]. Инжиниринг систем (Systems Engineering) Высокоуровневый процесс инжинирии систем, направленный на достижение соответствия системы всем выдвигаемым к ней требованиям [40].
162
неэффективной затратой средств, не дающей видимого вклада в повышение качества продукта, и в то же время откладывающей выход продукта на рынок. Другие считают, что новые методы разработки ПО и управления проектами требуют новых методов тестирования, что в новых условиях возникают новые риски и новые виды ошибок в ПО, и значение тщательного тестирования возрастает, что эффективность новейших методов обеспечения качества часто переоценивается, и указывают при этом на отмеченное пользователями общее снижение надежности коммерческого ПО в последние годы. Данная работа представляет собой попытку исследования понятия качества ПО и того места, которое занимает тестирование среди методов обеспечения и контроля качества.
Место тестирования среди методов оценки качества ПО В. В. Кулямин, О. Л. Петренко
1. Введение В последнее десятилетие произошли революционные технологические изменения практически во всех видах деятельности, связанных с разработкой и распространением программного обеспечения. Стали активно и широко использоваться такие подходы, как:
итеративные процессы разработки ПО; методы обеспечения и контроля качества ПО на всех этапах разработки, нацеленные на повышение степени удовлетворения клиентов; объектно-ориентированные методы анализа, проектирования и разработки ПО; проектирование и разработка ПО с использованием формализованных графических языков моделирования, таких как UML; использование инструментов CASE, поддерживающих автоматизированные преобразования из графических языков в языки программирования и обратно.
В связи с такими масштабными изменениями во взглядах архитекторов, программистов и руководителей проектов требуется пересмотр традиционных представлений о месте в процессах разработки ПО различных видов деятельности, которые и составляют эти процессы. Такой пересмотр происходит, но зачастую, в отсутствии четких критериев рассмотрения сложных понятий, приводит к радикализму, неоправданному завышению или занижению роли той или иной деятельности. Предметом данной статьи является современная оценка места тестирования в процессе производства ПО. Можно встретить совершенно противоположные мнения о значении тестирования в новых процессах разработки, и его важности для системы обеспечения качества в целом. Одни говорят, что в современных условиях тестирование является по большей части анахронизмом, что новые методы проектирования и разработки ПО в сочетании с методами обеспечения качества на ранних этапах разработки, сами по себе гарантируют получение качественного продукта, что традиционное тестирование является 163
2. Эволюция понятия качества ПО Что такое качественное программное обеспечение? Если спросить об этом достаточно широкую группу людей, имеющих дело с разработкой, продажей и использованием ПО, можно получить следующие ответы:
легко использовать хорошая производительность нет ошибок; не портит пользовательские данные при сбоях; можно использовать на разных платформах; может работать 24 часа в сутки и 7 дней в неделю; легко добавлять новые возможности; удовлетворяет потребности пользователей; хорошо документировано.
Все эти ответы выделяют характеристики, важные для конкретного пользователя, разработчика ПО или группы таких лиц. Однако, для повышения степени удовлетворения всех пользователей ПО, для достижения им прочного положения на рынке и повышения потенциала развития важен учет всей совокупности его характеристик, важных для всех заинтересованных сторон. Приведенные ответы показывают, что качество ПО может быть описано большим количеством разнородных характеристик. Значит, понятие качества программы — многоплановое и может быть выражено адекватно только некоторой структурированной системой характеристик или атрибутов. Такая система характеристик называется моделью качества.
2.1. Качество ПО по МакКолу Первой широко известной моделью качества ПО стала предложенная в 1977 МакКолом и др. [1] модель. 164
В ней характеристики качества разделены на три группы
Факторы (factors), описывающие ПО с позиций пользователя и задаваемые требованиями.
Критерии (criteria), описывающие ПО с позиций разработчика и задаваемые как цели.
Метрики (metrics), используемые для количественного описания и измерения качества.
Факторы качества, которых было выделено 11, группируются в три группы по различным способам работы людей с ПО. Полученная структура изображается в виде треугольника МакКола.
Сопровождаемость Оцениваемость Гибкость
Переносимость Переиспользуемость Способность к взаимодействию
Внедрение
Ревизии
удобство проверки на соответствие стандартам (auditability); точность управления и вычислений (accuracy); степень стандартности интерфейсов (communication commonality); функциональная полнота (completeness); однородность используемых правил проектирования и документации (consistency); степень стандартности форматов данных (data commonality); устойчивость к ошибкам (error tolerance); эффективность работы (execution efficiency); расширяемость (expandability); широта области потенциального использования (generality); независимость от аппаратной платформы (hardware independence); полнота протоколирования ошибок и других событий (instrumentation); модульность (modularity); удобство работы (operability); защищенность (security); самодокументированность (selfdocumentation); простота работы (simplicity); независимость от программной платформы (software system independence); возможность соотнесения проекта с требованиями (traceability); удобство обучения (training).
Каждая метрика влияет на оценку нескольких факторов качества. Числовое выражение фактора представляет собой линейную комбинацию значений влияющих на него метрик. Коэффициенты этого выражения определяются поразному для разных организаций, команд разработки, видов ПО, используемых процессов и т.п.
Функционирование Корректность Надежность Эффективность Целостность Практичность
2.2. Качество ПО по Боему
Рис. 1. Треугольник МакКола. Критерии качества — это числовые уровни факторов, поставленные в качестве целей при разработке. Объективно оценить или измерить факторы качества непосредственно довольно трудно. Поэтому, МакКол ввел метрики качества, которые с его точки зрения легче измерять и оценивать. Оценки в его шкале принимают значения от 0 до 10. Вот эти метрики качества: 165
В 1978 Боем [2,3] предложил свою модель, по существу представляющую собой расширение модели МакКола. Атрибуты качества подразделяются по способу использования ПО (primary use). Определено 19 промежуточных атрибутов (intermidiate construct), включающих все 11 факторов качества по МакКолу. Промежуточные атрибуты разделяются на примитивные (primitive construct), которые, в свою очередь, могут быть оценены на основе метрик. В дополнение к факторам МакКола атрибуты качества по Боему включают следующие: ясность (clarity), удобство внесения изменений (modifiability), документированность (documentation), способность к восстановлению функций (resilience), понятность (understandability), адекватность (validity), функциональность (functionality), универсальность (generality), экономическая эффективность (economy). 166
Временные характеристики (time behaviour), Использование ресурсов (resource utilisation), Соответствие стандартам эффективности (efficiency compliance,
2.3. Модель качества ПО ISO 9126 В 1991 году в качестве стандартной была принята модель качества ПО ISO 9126 [4,5]. Эта модель не является прямым расширением ранее предложенных. В ней оценка качества ПО основана на трехуровневом рассмотрении. 1. Цели (goals) — то, что мы хотим видеть в ПО. 2. Атрибуты (attributes) —свойства ПО, показывающие приближение к целям. 3. Метрики (metrics) — количественные характеристики степени наличия атрибутов. Выделено 6 целей: функциональность (functionality), надежность (reliability), практичность или удобство использования (usability), эффективность (efficiency), сопровождаемость (maintainability), переносимость или мобильность (portability). Цели подразделяются на 21 атрибут качества. В 2001 году этот стандарт был пересмотрен и расширен [6]. В него было добавлено 6 дополнительных атрибутов качества: привлекательность как атрибут практичности и степень соответствия стандартам для каждой из целей, кроме функциональности. Ниже приведен полный список атрибутов качества ПО по стандарту ISO 9126. ♦ Функциональность: Пригодность к определенной работе(suitability), Точность, правильность (accuracy), Способность к взаимодействию (interoperability), Соответствие стандартам и правилам (compliance), Защищенность (security). ♦ Надежность: Зрелость, завершенность (обратна к частоте отказов) (maturity), Устойчивость к отказам (fault tolerance), Способность к восстановлению работоспособности при отказах (recoverability), Соответствие стандартам надежности (reliability compliance, добавлен в 2001). ♦ Практичность, удобство использования: Понятность (understandability), Удобство обучения (learnability), Работоспособность (operability), Привлекательность (attractiveness, добавлен в 2001), Соответствие стандартам практичности (usability compliance, добавлен в 2001). ♦ Эффективность: 167
добавлен в 2001). ♦ Сопровождаемость: Анализируемость (analyzability), Изменяемость, удобство внесения изменений (changeability), Риск возникновения неожиданных эффектов при внесении изменений (stability), Контролируемость, удобство проверки (testability), Соответствие стандартам сопровождаемости (maintainability compliance, добавлен в 2001). ♦ Переносимость, мобильность: Адаптируемость (adaptability), Устанавливаемость, удобство установки (installability), Способность к сосуществованию с другим ПО (coexistence), Удобство замены другого ПО данным (replaceability), Соответствие стандартам переносимости (portability compliance, добавлен в 2001). Принятые в 2001 году части 2 и 3 стандарта ISO 9126 [7,8] определяют набор метрик качества ПО. В качестве примера таких метрик приведем следующие. 1. 2. 3. 4. 5.
Полнота реализации функций. Используется для измерения пригодности. Корректность реализации функций. Используется для измерения пригодности. Отношение числа обнаруженных дефектов к прогнозируемому. Используется для определения зрелости. Отношение числа проведенных тестов к общему их числу. Используется для определения зрелости. Отношение числа доступных проектных документов к указанному в их списке. Используется для измерения анализируемости.
Заметим, что третья и четвертая метрики из приведенных показывают, что качество ПО зависит не только от самого ПО как объекта материального мира, но и от его восприятия заинтересованными лицами: разработчиками, пользователями, заказчиками и др. Действительно, не изменяя самого ПО, можно повысить его качество только за счет проведения некоторых еще не проведенных тестов, поскольку значение четвертой метрики при этом увеличится. Сравнение моделей МакКола, Боема и ISO 9126 можно найти в [9]. Далее в этой работе мы будем использовать модель качества ПО по стандарту ISO 9126. Для полноты обзора упомянем еще две модели качества ПО. 168
Модель качества FURPS [10], предложенная в 1987 году.
Эта модель по структуре похожа на модели МакКола и Боема, но в ней не уделяется достаточное внимание переносимости ПО. Модель Дроми [11], предложенная в 1996 году. Эта модель отличается от принятого в 1991 году стандарта ISO более четким выделением связей между целями, атрибутами и метриками качества. В рамках этой модели впервые указывается на необходимость рассмотрения характеристик процесса разработки ПО для оценки качества полученного продукта.
3. Тестирование и другие методы оценки качества ПО Посмотрим теперь, как соотносятся понятия тестирования и качества ПО. В 1990 году стандартом ISO принято следующее определение тестирования. Тестирование — это наблюдение за функционированием ПО в специфических условиях с целью определения степени соответствия ПО требованиям к нему. Это определение показывает, что:
Тестирование само по себе не изменяет ПО, а значит, не способно влиять на те метрики качества, которые зависят только от самого ПО, Тестирование может служить методом контроля качества ПО, а именно тех его характеристик, которые проявляются при функционировании ПО.
Несмотря на истинность первого утверждения, тестирование способно изменить качество ПО в той его части, которая относится к восприятию ПО заинтересованными лицами. Некоторые метрики качества (см. примеры выше) отражают такое восприятие, и на их значение тестирование способно влиять. Сопоставим теперь тестирование с другими методами оценки качества ПО. Для этого воспользуемся отчетами по проекту SCOPE [12,13], нацеленному на выделение средств и методов оценки различных характеристик качества. В следующем списке содержатся упоминаемые в них методы и несколько методов, по каким-то причинам не использованных в этом проекте. ♦ Тестирование: Функциональное тестирование (functional tetsing), Структурное тестирование, нацеленное на покрытие кода (glass box testing), Лабораторное тестирование удобства использования ПО (laboratory testing), Тестирование производительности (performance testing), Нагрузочное тестирование (load testing, добавлено), стрессовое тестирование (stress testing, добавлено). ♦ Изучение документов с целью поиска проблемных мест и проверки соответствия стандартам, стилям, принятым правилам и соглашениям: 169
Целенаправленное изучение кода (code inspection), Целенаправленное изучение документации (documents inspection).
♦ Формальный анализ: Формальное доказательство свойств ПО (formal verification), Анализ алгоритмической сложности (complexity analysis). ♦ Анализ: Проверка статической семантики языков программирования, Автоматический анализ кода (static analysis), Анализ свойств ПО, выполняемый человеком, Анализ архитектуры и проекта (architecture review, design review), Анализ процессов разработки (process analysis, добавлен). ♦ Измерения: Определение метрик ПО, проекта, документации, Измерения производительности (benchmarks), Профилирование (profiling, добавлено). ♦ Моделирование, использование моделей для оценки свойств ПО: Модели использования (usability model), Модели надежности (reliability model), Модели функционирования: проверка на модели (model checking, добавлено), прототипирование (добавлено). В отчетах SCOPE не упоминаются также применяемые иногда методы оценки качества ПО, основанные на субъективном его восприятии и интуиции экспертов. Проанализируем перечисленные методы оценки качества, сопоставив их с атрибутами качества по стандарту ISO 9126 и с объектами применения, в качестве которых выступают различные документы, представляющие ПО. Будем рассматривать следующие виды таких документов.
170
Исполнимый код. Исходный код на языке программирования высокого уровня. Формальные модели ПО различного рода. Проектная документация на естественных языках. Пользовательская документация.
Атрибуты качества Пригодность
Исполнимый код Функциональное тестирование Точность Функциональное тестирование Способность к Тестирование на взаимодейст- соответствие вию Соответствие Тестирование на стандартам и соответствие правилам Защищенность Тестирование защищенности
Исходный Модели Проектная Пользовательская код документация документация Проверка Проверка на Изучение Изучение кода модели документов документов Анализ кода Формальный Анализ анализ документов Анализ кода Изучение Изучение документов документов Проверка кода
Анализ кода Проверка на модели, формальный анализ Зрелость Нагрузочное Проверка на тестирование модели Устойчивость к Стрессовое Анализ кода Проверка на отказам тестирование модели, формальный анализ Способность к Стрессовое Анализ кода Проверка на восстановтестирование модели, лению формальный анализ Соответствие Тестирование на Анализ кода стандартам соответствие надежности Понятность Тестирование Прототипирование Удобство Тестирование Прототиобучения пирование РаботоспоТестирование Прототисобность пирование Привлекате- Тестирование Прототильность пирование Соответствие Тестирование на стандартам соответствие практичности
Изучение документов
Изучение документов
Анализ документов
Анализ документов Анализ документов Анализ документов Анализ документов Анализ документов Анализ документов Анализ документов Изучение документов
Изучение документов Изучение документов Изучение документов Изучение документов Изучение документов
Временные Тестирование и характеристики измерения производительности Использование Тестирование ресурсов производительности, профилирование Соответствие Тестирование и стандартам измерения эффективности производительности Анализируемость Изменяемость
Анализ кода Формальный Анализ анализ документов
Стабильность
Анализ кода
Контролируемость Соответствие стандартам сопровождаемости Адаптируемость Устанавливаемость Способность к сосущество ванию Удобство замены Соответствие стандартам переносимости
Анализ кода
Анализ кода, Формальный Анализ профилианализ документов рование Анализ документов
Анализ кода Анализ кода
Проверка кода
Тестирование
Анализ кода
Тестирование
Анализ кода
Тестирование
Проверка кода
Тестирование
Анализ кода
Тестирование на Проверка соответствие кода
Анализ документов Анализ документов Анализ документов Анализ документов Анализ документов
Анализ документов Анализ документов Анализ документов
Изучение документов Изучение документов Изучение документов
Анализ документов Анализ документов
Изучение документов Изучение документов
Таб. 1. Методы оценки атрибутов качества. Таб. 1 дает сопоставление известных авторам методов оценки качества ПО с атрибутами качества и различными видами документов. Мы не претендуем на полноту представленной в ней информации, пустые клетки в таблице означают, 171
172
что нам не удалось вспомнить или найти в литературе и Интернете соответствующие методы. Эта таблица показывает, что тестирование является практически единственным способом проверки качества ПО, применимым к исполнимому коду — конечному продукту процессов разработки ПО. Только для оценки характеристик производительности кроме тестирования можно использовать другие методы. Для подавляющей массы коммерческого ПО его исполнимый код и пользовательская документация являются единственными документами, доступными конечным пользователям. Поскольку соответствие между действительными свойствами программ и их описанием в пользовательской документации часто само по себе требует проверки, тестирование оказывается единственным надежным средством оценки качества ПО с точки зрения конечных пользователей. Оно не может быть заменено ни одним из других указанных методов контроля качества, ни каким-либо их сочетанием. Приведенная аргументация в пользу незаменимости тестирования может быть оспорена сторонниками подхода «корректность по построению» (correctness by design). Этот подход подразумевает применение таких методов проектирования и разработки, которые автоматически гарантировали бы корректность полученного в результате ПО. К нему тесно примыкают активно распространяющиеся сейчас методы обеспечения качества ПО на ранних этапах разработки. Ни в коем случае не отвергая необходимости развития подобных методов и полезности их применения на практике, заметим, что все подобные подходы подразумевают, что результат будет качественным только при правильном применении соответствующих методов. Исключить людей из процессов разработки ПО в ближайшем будущем возможным не представляется, а людям свойственно делать ошибки даже при выполнении достаточно простой работы. Разработка же ПО является одним из самых сложных процессов, включающем в себя разнородные виды деятельности и, в частности, перевод неформальных требований к ПО в формальные модели и код, написанный на формальных языках. Последнее обстоятельство порождает множество неопределенностей в разработке ПО, способствующих появлению многочисленных и трудноопределимых ошибок. Даже в том случае, если нужный уровень качества достигнут и в пользовательской, и в проектной документации, и в исходном коде, и подтвержден моделированием – трансляция исходного кода в исполнимый и развертывание результирующего ПО на целевой платформе, в окружении других программ, способны внести множество непредусмотренных дефектов и значительно понизить качество ПО в его восприятии конечными пользователями.
173
4. Заключение Данная работа показывает, что тестирование является одним из важнейших методов контроля качества ПО, и практически единственным их них, доступным конечным пользователям. Приведенная выше таблица показывает, что ни один из других известных методов, ни какая-либо их комбинация не способны полностью заменить тестирование, поскольку только тестирование позволяет получить оценки качества по исполнимому коду. Этот вывод ни в коем случае не умаляет важности других методов, зачастую способных давать необходимую информацию о качестве ПО на более ранних этапах разработки, когда тестирование не применимо. Несмотря на активное развитие и внедрение в практику перспективных методов обеспечения качества на ранних этапах разработки ПО, в ближайшем будущем они также вряд ли будут способны сделать тестирование ненужным. Тем не менее, мы считаем, что такие методы имеют большой потенциал и их развитие и практическое использование может дать значительные результаты. Кроме того, в силу наличия в составе понятия качества ПО характеристик, связанных с восприятием ПО различными заинтересованными лицами, само по себе проведение тестирования способно повысить качество ПО. Можно также отметить наличие пустых клеток в Таб. 1. Такие клетки могут означать как отсутствие связи между соответствующими атрибутом качества и видом документов, так и отсутствие на данный момент методов, позволяющих оценивать этот атрибут качества по данному виду документов. Так, например, по мнению авторов, отсутствие на данный момент методов оценки сопровождаемости на основе исполнимого кода ПО не означает невозможности проведения подобных оценок. Более того, такие методы могли бы существенно помочь при сопровождении и перепроектировании унаследованного программного обеспечения, для которого зачастую не сохраняется других документов и даже исходного кода, либо имеющиеся документы не актуальны, не соответствуют той версии ПО, которая находится в работе. Литература 1. J. McCall, P. Richards, G. Walters. Factors in Software Quality. three volumes, NTIS ADA049-014, AD-A049-015, AD-A049-055, November 1977. 2. B. W. Boehm, J. R. Brown, H. Kaspar, M. Lipow, G. MacLeod, and M. J. Merritt. Characteristics of Software Quality. North Holland, 1978. 3. B. Boehm. Software Risk Management. IEEE Computer Society Press, CA, 1989. 4. International Standard ISO/IEC 9126. Information technology – Software product evaluation – Quality characteristics and guidelines for their use. International Organization for Standardization, International Electrotechnical Commission, Geneva, 1991. 5. В. В. Липаев. Обеспечение качества программных средств. Методы и стандарты. Синтег, Москва, 2001.
174
6. ISO/IEC 9126-1. 2001. Software engineering – Software product quality – Part 1: Quality model. Geneva, Switzerland: International Organization for Standardization. 7. ISO/IEC DTR 9126-2. 2001. Software engineering – Software product quality – Part 2: External metrics. Geneva, Switzerland: International Organization for Standardization. 8. ISO/IEC DTR 9126-3. 2000. Software engineering – Software product quality – Part 3: Internal metric. Geneva, Switzerland: International Organization for Standardization. 9. L. Hyatt and L. Rosenberg. A Software Quality Model and Metrics for Identifying Project Risks and Assessing Software Quality. ESA 1996 Product Assurance Symposium and Software Product Assurance Workshop. European Space Agency, ESTEC, Noordwijk, The Netherlands, pp. 209-212. 10. R. Grady and D. Caswell. Software Metrics: Establishing a Company.Wide Program, Prentice Hall, 1987. 11. G. Dromey. Cornering the Chimera. IEEE Software, January, 1996, pp. 33-43. 12. R. Bache and G. Bazzana. Software metrics for product assessment. McGraw Hill, International Software Quality Assurance Series, 1993. 13. A. K. Rae, H. L. Hausen, and P. Robert (Editors). Software Evaluation for Certification: Principles, Practice and Legal Liability. McGraw Hill, International Software Quality Assurance Series, 1995.
175
176
Вопросы организации распределенного хранения данных в системах обработки изображений Д.Н. Волков
1. Введение Фотограмметрические системы (ФГС) предназначены для построения цифровых моделей местности или поверхности объекта по его изображениям. В настоящее время в большинстве используемых систем этого типа работа осуществляется операторами на рабочих станциях с использованием различных средств автоматизации этого процесса, кроме того на некоторых стадиях обработки могут использоваться полностью автоматические методы. Однако основную долю времени составляет ручная обработка данных, поэтому при проектировании таких систем большое внимание уделяется проблемам организации одновременной обработки различных порций данных разными операторами. Обработка информации в цифровых фотограмметрических системах (ЦФГС) имеет ряд особенностей, связанных как со значительными объемами обрабатываемых данных, так и с особенностями технологического процесса и его отдельных этапов. Кроме того, к таким системам могут предъявляться особые требования по надежности, используемой аппаратной базе и необходимым вспомогательным функциям. Использование для хранения данных в ЦФГС файловых систем общего назначения напрямую представляется нецелесообразным, так как при этом: • невозможно эффективно организовать работу нескольких программных модулей с данными, хранящимися в одном файле (с учетом семантики данных); •
затруднительно обеспечить безопасный доступ к данным по сети;
•
отсутствуют средства организации размещения данных с учетом частоты обращений к ним по сети
•
повышается трудоемкость администрирования системы и снижается эффективность использования пространства на дисках рабочих станций, а также повышаются затраты на передачу данных по сети. 177
В связи с этим оптимальным решением является отказ от непосредственного использования файловых систем общего назначения, взамен чего встает задача разработать собственные методики организации хранения данных. При этом становится возможным учесть особенности работы системы и предъявляемые к ней требования, тем самым повысив эффективность хранения и доступа к данным.
2. Требования, предъявляемые к системе На основе опыта разработки и эксплуатации предыдущих версий фотограмметрической системы, а также с учетом пожеланий пользователей, были выдвинуты следующие требования к модулю распределенного хранения данных (МРХ): 1. Организовать возможность хранения обрабатываемых данных на накопителях различных машин локальной сети. 2. Предусмотреть возможность доступа к данным на работающих компьютерах в то время, когда другие компьютеры могут быть недоступны. 3. Осуществлять доступ к данным на машине после ее включения без дополнительного административного вмешательства. 4. Иметь возможность получения информации о местоположении данных, хранящихся на недоступной в данный момент машине. 5. Организовать защиту данных от их модификации (в том числе по сети) средствами, отличными от системных. 6. Хранить данные так, чтобы затраты на передачу их по сети при обращениях были минимальными. 7. Создать средства автоматизированного управления расположением данных для обеспечения выполнения требований предыдущего пункта. 8. Ввести ряд средств управления системой, в том числе: контроль свободного пространства в сети, выполнение операций резервного копирования и восстановления, переноса данных внутри сети или операции импорта/экспорта с другими системами. Требование 1 вызвано тем, что обрабатываемые данные могут иметь значительный размер (до десятков и сотен гигабайт), а их обработка должна вестись на различных рабочих станциях. Централизованное хранение подобных данных потребует использование накопителей сверхбольшой емкости (ограничение на аппаратную платформу) и резко увеличит нагрузку на сеть, снизив скорость доступа к данным. Требования 2 – 5 связаны с обеспечением надежности работы в условиях локальной сети предприятия и сформулированы на основании опыта работы пользователей и по их требованиям. В частности, пункт 5 означает, что следует ограничить доступ к данным по сети через стандартные средства ОС (Windows Explorer, различные навигационные оболочки). 178
Требование 6 очевидным образом следует из стремления повысить скорость работы на имеющейся аппаратной базе. Требования 7 – 8 соответствуют запросам системных администраторов по контролю и обслуживанию системы.
3. Некоторые сведения о существующих системах В ЦФГС «AeroSys» и «VirtuoZo» совместная работа с проектом реализована на уровне разделения проекта на независимые фрагменты, работа с которыми проводится раздельно. При этом, в заключительной части работ происходит объединение результатов индивидуальной работы с каждой частью проекта. Недостатками такого подхода является, в первую очередь, невозможность предварительной оценки итогового результата и большие трудозатраты при необходимости коррекции конечного продукта после сборки данных. В системе «ZIimaging ImageStation» совместная работа организована через общий доступ к файлам по сети. При этом каждый модуль устанавливает ловушки на событие «запись в файл», и по срабатыванию этой ловушки происходит чтение данных, записанных другими модулями. При этом возникают существенные системные расходы времени и ресурсов на организацию вышеупомянутых ловушек, а также снижается надежность системы, поскольку каждый модуль самостоятельно контролирует изменения в общем файле данных, которые ему необходимо внести. Возникают дополнительные накладные расходы на создание и хранение в файле синхроинформации, чтобы каждый модуль мог определить, какие изменения были внесены другими модулями. Ряд операций, которые требуют возможности отката (носят транзакционный характер) при таком подходе труднореализуемы или вообще невозможны. Все вышеперечисленные системы используют для хранения данных сервис, предоставляемый файловыми системами базовых ОС, расширенные средствами сетевого доступа к файлам ОС. Существующие в настоящее время сетевые файловые системы (ФС) общего назначения организованы по клиентсерверной архитектуре, при которой машина, хранящая на своих накопителях данные (сервер) предоставляет машине, желающей получить доступ к этим данным (клиенту) определенный интерфейс, через который происходит передача команд-запросов и данных. Одной из основных задач при сетевом доступе к данным является унификация интерфейса прикладных программ (API) работы с удаленными файлами. Большинство современных ОС решают ее путем включения каталогов поставляемой сервером части сетевой файловой системы в локальную файловую систему, как часть последней. При этом возникает так называемая «точка привязки» (mount point) для экспортируемой ФС – это каталог локальной ФС, который является корневым каталогом экспортируемой. Как следует из определения, точка привязки своя для каждого клиента, импортирующего одну и ту же удаленную ФС. Для прикладной программы каталоги и файлы удаленной ФС будут подкаталогами точки 179
привязки и файлами в них. Каждый компьютер может быть и клиентом и сервером, экспортируя элементы своей ФС и импортируя удаленные. Для передачи данных по сети ФС используют существующие протоколы транспортного уровня (TCP, IPX), а операционная система предоставляет набор функций (API) для открытия и закрытия доступа по сети к каталогам локальной файловой системы, а также для подключения и отключения ресурсов, открытых для доступа с удаленных компьютеров. Используя эти средства ОС можно организовать доступ модулей ФГС к данным, расположенных на других машинах в сети. Однако этот подход (использовавшийся в некоторых предыдущих версиях системы) имеет ряд недостатков: • данные становятся доступными для любого приложения, не только системы; • различные средства разграничения доступа к сетевым ресурсам доступны не во всех версиях ОС и усложняют настройку системы; • работоспособность системы может быть нарушена, если пользователь изменит настройки доступа или самостоятельно, в обход средств системы, изменит хранящиеся данные (удалит или отредактирует файлы). Другим подходом может быть использование готового средства распределенного доступа к данным, например распределенной СУБД. Этот способ был отвергнут по следующим причинам: • для обеспечения функционирования системы на базе СУБД, в соответствии с всеми предъявляемыми требованиями, понадобится разработать надстройку, по объему порядка целого модуля хранения данных; • затраты на администрирование СУБД существенно повысят трудоемкость (снизят надежность) обслуживания системы; • за счет использования СУБД повысятся требования к аппаратуре, возрастет стоимость аппаратно-программного комплекса; • использование дополнительных продуктов может оказаться неприемлемым по лицензионным соображениям или требованиям безопасности.
4. Общая структура модуля распределенного хранения данных МРХ структурно состоит из следующих служб: Служба каталогов – осуществляет хранение информации о расположении данных, позволяя получить некоторую справочную информацию о данных без непосредственного обращения к самим данным. В силу того, что подобная справочная информация имеет относительно малый размер по сравнению с размером данных, ее представляется возможным хранить на каждом 180
компьютере системы (кэшировать), благодаря чему запрос этой информации будет происходить без сетевых запросов, что повысит скорость выполнения этих запросов. Кроме этого реализуется требование по возможности получения справочной информации о данных, недоступных в текущий момент (выключенный компьютер). Для того, чтобы кэшированная информация поддерживалась в актуальном состоянии, предусмотрены механизмы ее синхронизации. Служба сетевого доступа к данным – позволяет получить доступ к данным, хранящимся на других компьютерах, через собственный сетевой протокол. При этом используется сервис, предоставляемый модулем сетевого доступа, являющимся независимой частью ЦФГС. Последний модуль служит для организации сетевых соединений между модулями ЦФГС, запущенными на различных рабочих станциях, он использует протокол транспортного уровня (TCP) операционной системы, делая все остальные модули независимыми от реализации сетевого протокола на конкретной платформе. Служба хранилищ – организует хранение данных в обособленных объектах – хранилищах. Каждое хранилище имеет собственную структуру каталогов, в котором располагаются файлы с данными, и может быть перенесено на другую машину без изменения конфигурации всей сетевой системы. Каждое хранилище имеет собственный каталог с информацией о хранящихся в нем данных, который используется службой каталогов. Далее будет подробно разобрана работа каждой из этих служб.
5. Организация службы каталогов Для доступа к данным необходимо ввести механизмы их идентификации. При этом они, во-первых должны быть удобными для написания программ с их использованием, а во-вторых не приводить к существенным накладным расходам на их работу. С учетом этого была введена следующая логическая организация данных: • структурной единицей хранения данных является ресурс (аналогичен файлу в ФС) – неинтерпретируемая последовательность байтов; • каждый ресурс имеет идентификатор – строку, уникальную в пределах всей системы; • вводится однозначное соответствие элементов множества ресурсов и элементов множества идентификаторов: каждому ресурсу соответствует идентификатор и наоборот; • пространство идентификаторов ресурсов образует дерево (по соображениям иерархической упорядоченности хранимых данных) – Рис. 1.
181
projects projects.id_22856
id_22856 id_54128
images id_13452
id_45701
projects.id_54128 images.id_13452 images.id_45701
scheme1
projects.id_22856.scheme1
models
id_34980 id_11653 projects.id_22856.models.id_34980
projects.id_22856.models.id_11653
Рис. 1. Дерево ресурсов. Для упорядочивания физического хранения данных вводится понятие хранилища. Хранилище – это объект, содержащий данные ресурсов и информацию для обеспечения доступа к этим данным. Каждое хранилище также имеет свой уникальный строковый идентификатор. Собственно данные ресурсов хранятся в виде файлов локальной ФС. Это, правда, не исключает возможности хранения данных на удаленном компьютере с использованием средств сетевой ФС (Рис. 2). Однако при этом теряется ряд преимуществ доступа к данным через сетевые средства МРХ (в первую очередь, связанные с безопасностью), поэтому так следует поступать только при отсутствии других возможностей (на удаленном компьютере не установлены модули ФГС. Для уменьшения вероятности случайного повреждения пользователем структуры данных все файлы данных хранилища целесообразно поместить в отдельный каталог в корневом каталоге диска, который сделать скрытым (путем установки атрибута или другим образом, в зависимости от ФС). Использование более сильных способов защиты данных, например, путем создания раздела на жестком диске собственного формата, неприемлемо из-за снижения универсальности (более низкий уровень доступа к аппаратным ресурсам потребует разработки значительного объема дополнительных средств, драйверов и т.п.) и надежности (повышается трудоемкость восстановления данных при отказах аппаратуры или ошибках ПО).
182
Исходя из требования по возможности иметь доступ к информации о ресурсах, хранящихся на компьютерах, к которым нет доступа в настоящий момент, служба каталогов должна хранить последнее состояние каждого хранилища до момента перехода его в недоступное состояние. Это реализуется путем хранения на каждой машине кэша каталога хранилища копии каталога, полученного при последнем запросе. При невозможности доступа к хранилищу используются данные из кэша, при этом ресурсы данного хранилища помечаются, как недоступные, а также можно узнать, на какой машине это хранилище было доступным последний раз (какую машину нужно включить для обеспечения доступа к ресурсам). Такой подход позволяет обеспечить простоту перемещения ресурсов из хранилища в хранилище, и хранилищ с машины на машину, причем эти изменения не отразятся на модулях верхнего уровня, идентификаторы ресурсов не изменятся, и доступ будет осуществляться единообразно, независимо от изменений в расположении данных. Это дает возможность оптимизировать расположение данных по доступу к ним, не испытывая дополнительных накладных расходов по изменению конфигурации модулей верхнего уровня.
Владелец Модуль доступа к данным
Программа-клиент
Создание, удаление
ь апис ие, з Чтен
Хранилище Внешний сервер
6. Выполнение операций доступа к ресурсам
Рис. 2. Доступ при отсутствии на компьютере модулей ФГС. В разрабатываемой версии МРХ каждому ресурсу соответствует один отдельный файл. Это позволяет осуществлять доступ к локальным (для приложения) ресурсам напрямую через стандартные функции ОС, без промежуточных обработок данных, максимально повысив производительность. При необходимости разделения некоторого блока данных (например, большого изображения) на несколько ресурсов для хранения их на разных компьютерах, это производится модулями, непосредственно использующими данные, с учетом специфики каждого типа данных. Для доступа к данным ресурса по его идентификатору необходимо осуществить преобразование идентификатора ресурса в пару «идентификатор хранилища – имя файла». Это преобразование является одной из основных операций в МРХ, ее выполняет служба каталогов МРХ. Каждое хранилище имеет каталог – таблицу, содержащую всю информацию о хранящихся ресурсах (идентификатор, имя файла с данными, синхронизационные метки, описание для пользователя и др.). Каталог рассылается всем машинам сети, таким образом служба каталогов на каждой машине формирует свое дерево ресурсов, посредством которого осуществляется преобразование идентификатора ресурса для доступа к данным. 183
В системе введено понятие «владелец хранилища». Им становится компьютер, который имеет доступ на запись для данного хранилища (локальный или через системные средства сетевого доступа к файлам) и первым произвел операцию захвата хранилища. В первую очередь происходит захват локальных хранилищ (доступных на локальной ФС), затем список захваченных хранилищ рассылается всем остальным машинам, чтобы они имели информацию о расположении того или иного хранилища. В процессе работы владелец хранилища может изменяться, если произошло выключение или сбой в работе предыдущего владельца. Таблица соответствия идентификатора хранилища и машины, ответственной за него, динамически изменяется с учетом информации, приходящей по сети. Владелец осуществляет полный контроль над каталогом хранилища (все операции чтения или модификации каталога производятся только через него), создание новых ресурсов, рассылку каталога хранилища другим компьютерам и вспомогательные операции. Так достигается синхронизация всех операций с каталогом хранилища, а также осуществляется доступ к данным по сети. Хранилище может быть доступно через средства ОС сетевого доступа к файлам. В таком случае удаленные машины могут обращаться к ресурсам хранилища через эти средства, открывая соответствующие файлы на чтение и/или запись (Рис. 3).
184
Владелец сь запи , е и Чтен
Хранилище
Модуль доступа к данным
зд Со
, ие н а
а уд
Программа-клиент
е ни е л
Рис. 3. Доступ через средства сетевой ФС. Возможна ситуация, когда хранилище располагается на диске сервера, на котором не установлена ФГС. Тогда это хранилище делается доступным по сети средствами ОС, один или несколько компьютеров имеют к нему доступ через эти средства. Один из них при старте системы становится владельцем хранилища, управляя каталогом хранилища, а все они обращаются к файлам хранилища через сетевую ФС (Рис. 2).
7. Методика уникальности имен. Создание и удаление ресурсов Для организации иерархической структуры ресурсов идентификатор ресурса имеет следующий формат: сегмент_1.сегмент_2. … .сегмент_n, где сегмент_i – последовательность алфавитно-цифровых символов. При этом все множество идентификаторов ресурсов системы естественным образом образует дерево. Введя понятие узла дерева ресурсов, необходимо заметить, что не каждому узлу соответствует ресурс. Этим данная система именования отличается от традиционной системы каталогов ФС – в нашем случае каталоги отсутствуют, а каждый ресурс именуется своим полным идентификатором без привязки к какому-либо другому ресурсу (Рис. 1 – возле узлов дерева, которым соответствуют ресурсы, указаны их полные идентификаторы). Такая организация используется для группировки ресурсов по функциональному назначению (например, ресурсы, содержащие данные для одного проекта, имеют общий корень, при этом физически могут располагаться на разных машинах), а также для некоторых операций управления ресурсами. Поскольку для пользователя было бы неудобно ссылаться на ресурсы по идентификатору, который определяется модулем хранения данных и не может 185
быть произвольно редактируемым, были введены описания ресурсов – произвольные текстовые строки, хранящиеся в каталоге ресурсов хранилища вместе с идентификаторами. Пользователь видит описание при выборе ресурса в диалогах, а также имеет возможность ввести описание для вновь создаваемого ресурса. Ресурсы можно разделить на две группы по следующему признаку: часть из них должна иметь фиксированный идентификатор (в рамках всей системы или в какой-либо логической группе, например, в поддереве проекта), тогда как другие могут иметь произвольный идентификатор в заданном поддереве. Ресурсы первого типа, как правило, содержат данные, определяемые в единственном экземпляре на проект (например, каталог изображений), а второго – данные, возникающие при обработке в нескольких вариантах (к примеру, разные варианты построения модели рельефа, из которых впоследствии будет выбрана одна). Для создания ресурсов первого типа модулю хранения данных передается заданный фиксированный идентификатор, при создании ресурса второго типа – специальный идентификатор, в котором один из сегментов (обычно последний) задается символом “*”. При создании ресурса модуль автоматически заменит звездочку строкой, формируемой по специальным правилам, так, чтобы в результате получился уникальный идентификатор. Этот идентификатор возвращается в код, запросивший создание ресурса, и используется при последующем доступе к нему. Полученный идентификатор можно использовать для создания ресурсов более низких уровней, добавляя в конец строки идентификатора дополнительные сегменты. Учитывая возможность хранилищ находиться в недоступном состоянии произвольным образом, возникает следующая трудность при организации доступа к ресурсам с фиксированным идентификатором: при поступлении запроса на создание такого ресурса необходимо достоверно знать, существует он (возможно, в хранилище, на данный момент недоступном), или еще не был создан и должен быть создан при обработке текущего запроса. Одним из вариантов метода решения данной задачи можно предложить, например, ведение отдельной таблицы всех ресурсов с фиксированными идентификаторами. Этот вариант неудобен тем, что требует наличия выделенной, всегда включенной, машины и по другим причинам. В рассматриваемой системе был использован другой подход, названный «методом ответственных». По сути, этот метод реализует вышеупомянутую таблицу уникальных ресурсов, только в распределенном варианте. На каждый узел дерева может быть навешен специальный атрибут «ответственный», имеющий значением идентификатор (имя) компьютера, который является ответственным за создание ресурсов с фиксированными идентификаторами в этом и всех нижележащих узлах дерева. Атрибут на нижележащем узле перекрывает более 186
верхний. Таким образом, все дерево идентификаторов ресурсов оказывается поделенным на зоны ответственности между компьютерами сети (Рис. 4).
projects id_22856 scheme1
id_54128
images id_13452
id_45701
models
id_34980 id_11653 Рис. 4. Зоны ответственности в дереве ресурсов. Рассмотрим алгоритмы создания ресурса и назначения узлу ответственного, поскольку они тесно связаны друг с другом. При запросе на создание ресурса с фиксированным идентификатором, определяется компьютер, ответственный за данную область дерева идентификаторов. Если такой компьютер найден и доступен в данный момент (включен), у него получается разрешение на создание ресурса. В ответ может быть получено разрешение, либо сообщено, что указанный ресурс уже существует и выдан идентификатор хранилища с этим ресурсом (при этом хранилище может быть сейчас недоступно – используется кэш хранилища, находящийся на ответственном компьютере). Если ресурс пока не был создан, он создается в выбранном хранилище, причем операция считается завершенной только после того, как ответственный синхронизирует это хранилище и сохранит его кэш на локальном диске. Такой алгоритм гарантирует, что ресурс с фиксированным идентификатором будет создан в системе в единственном экземпляре. При создании ресурса с уникальным идентификатором соответствующий ему узел получает атрибут «ответственный» с указанием создающего компьютера или компьютера, который владеет хранилищем ресурса. Это не обязательно, можно использовать и существующую в точке создания ресурса область ответственности, однако такой подход делает дерево идентификаторов разделенным на большее число областей ответственности с их локализацией (ответственным за ресурсы делается компьютер, владеющий хранилищем с этими ресурсами), а следовательно уменьшает среднее число отказов на создание ресурсов по причине отсутствия доступа к какому-либо компьютеру. 187
Как видно из рисунка, некоторые узлы верхнего уровня не лежат в зоне ответственности никакого компьютера. Это означает, что ресурсы с фиксированными идентификаторами не могут быть созданы в данных узлах. Однако это и не требуется в рамках общей концепции ресурсов рассматриваемой СОИ, а при создании ресурса с уникальным идентификатором автоматически, как следует из только что рассмотренного алгоритма, будет создана новая зона ответственности. Также видно, что все ресурсы верхнего уровня создавались с уникальными идентификаторами. При удалении ресурса также встает проблема синхронизации (в случае ресурсов с фиксированными идентификаторами). Однако требование – для удаления ресурса, к файлу которого есть физический доступ, необходимо дополнительно иметь доступ к третьему компьютеру (ответственному) – кажется излишне жестким. Поэтому удаление ресурса производится в два этапа: на первом удаляется файл ресурса из хранилища, на втором происходит удаление записей из каталога хранилища, которым не соответствуют файлы в хранилище. Первый этап не требует участия владельца хранилища, что ускоряет данную операцию, особенно при групповом удалении. Рассмотрим подробнее второй этап. Он выполняется владельцем хранилища по запросу (после удаления ресурсов), при начальном запуске и периодически. Для каждого ресурса в хранилище, файл которого отсутствует, определяется ответственный, удаляется запись из каталога, после чего ответственному направляется команда на синхронизацию данного хранилища. Операция удаления алгоритмически проще операции создания и содержит меньшее число проверок. Это объясняется тем, что при сбоях синхронизации на этапе удаления, до восстановления синхронности каталога хранилища с локальными кэшами, будет невозможно (отказ) создание ресурсов с фиксированными идентификаторами, а при подобных сбоях в процессе создания – образование двух ресурсов с одинаковыми идентификаторами, сохранение в них различных данных и необходимость вмешательства администратора для объединения этих ресурсов в один. Последнее, кстати, не всегда возможно, связано с большими затратами времени и может привести к потере данных. Все это указывает на значительно большую важность синхронизации при создании и необходимости выполнения этой операции более тщательно.
8. Синхронизация Как уже неоднократно упоминалось, синхронизация, в основном синхронизация каталогов хранилищ, является одной из основных служебных операций в модуле распределенного хранения данных. При синхрооперациях объект хранилища, расположенный на машине-владельце (первичный), взаимодействует с аналогичными объектами (вторичными) на удаленных машинах (Рис. 5). Объекты, соответствующие одному хранилищу, связываются между собой через сетевые службы системы по протоколу TCP. Данные 188
первичного объекта всегда имеют статус авторизованных, тогда как данные вторичных объектов используются для ускорения справочных запросов и должны быть изменены при приходе данных от первичного объекта.
Владелец
Хранилище Каталог
Объект хранилища
Кэш
Объект хранилища
Рис. 5. Взаимодействие объектов хранилища. Основными данным здесь является таблица каталога хранилища. В первичном объекте хранилища она всегда (с точностью до задержек записи на диск) согласована с таблицей каталога хранилища, хранящейся в виде файла в том же каталоге, что и хранилище. При изменениях этой таблицы первичный объект направляет все доступным вторичным объектам сообщение о необходимости пересинхронизировать таблицу ресурсов. Вторичные объекты самостоятельно решают, когда выполнить эту операцию, в зависимости от загрузки системы и необходимости доступа к ресурсам из данного хранилища. Однако в любом случае объект отмечает, что его данные устарели, установкой соответствующего флага. Для уменьшения объема запросов, передаваемых по сети, вводится понятие временной метки (timestamp) для каталога хранилища. Эти метка представляет собой число, которое каждый раз увеличивается на единицу при соответствующей модификации хранилища. Таких меток две: для последней модификации (создания, удаления, изменения атрибутов ресурса) и для последнего удаления. Эта пара меток существует для каталога хранилища на диске, в памяти, для кэша каталога. Кроме того, для каждого ресурса существует временная метка его последнего изменения его атрибутов (не содержимого!). При модификации хранилища его метка последней модификации увеличивается, после чего полученное значение присваивается метке ресурса, который вызвал изменения в хранилище. В случае удаления какого-либо ресурса из каталога хранилища, временная метка удаления получает значение обновленной метки изменения. 189
Если метка изменения у каталога на диске или кэша меньше, чем у таблицы в памяти, производится запись на диск (может быть отложена для уменьшения числа дисковых операций). При синхронизации по сети вторичный объект передает в запросе метки модификации и удаления своей таблицы. При этом: • если метка модификации вторичного объекта совпадает с меткой модификации первичного, хранилища синхронны (возвращается пустая таблица изменений); • если метка модификации вторичного объекта меньше метки модификации первичного, а метки удаления совпадают, то возвращается таблица изменений, содержащая записи каталога, с метками изменения большими, чем метка изменения вторичного объекта; • если метка удаления вторичного объекта меньше, чем у первичного, возвращается вся таблица каталога хранилища. Программно таблица каталога хранилища отдельно в памяти не хранится. Вместо этого каждый модуль распределенного хранения имеет в памяти общее дерево ресурсов, упорядоченных в соответствии с их идентификаторами, в котором каждый узел, в том случае, если ему соответствует ресурс, имеет указатель на объект (в терминах С++) хранилища, содержащего этот ресурс. Полный обход по дереву позволяет получить полную таблицу ресурсов для заданного хранилища. Эта операция, однако, относительно редка, по сравнению с операциями поиска заданного ресурса (как операция создания нового ресурса редка по сравнению с открытием существующего). При каждой синхронизации хранилища происходит проход по дереву ресурсов и его модификация в соответствии с полученной таблицей изменений от первичного объекта хранилища. Используемые средства синхронизации позволяют не блокировать дерево на исключительный доступ в процессе этой операции, что дает возможность одновременно получать справочную информацию о ресурсах, необходимую для доступа к ним.
9. Заключение В данной работе рассматривались особенности хранения данных в цифровых фотограмметрических системах, недостатки использования для решения данной задачи файловых систем общего назначения. В результате был определен набор требований к модулю хранения данных, определена функциональная структура данного модуля и выполнена его реализация, которая в настоящее время проходит тестирование в опытной эксплуатации. Следующим этапом работы по организации хранения данных будет разработка методики оптимизации размещения данных и создания средств для управления размещением данных в соответствии с этой методикой.
190
Свойства схем данных XML∗ Л.Г. Новак, С.Д. Кузнецов
1. Введение Расширяемый Язык Разметки (XML) [1] становится в последнее время доминирующим стандартом представления и обмена данными в Интернете. Подобно языку HTML, XML является поднабором языка SGML. Однако существует набор фундаментальных отличий XML от других языков разметки, одно из которых заключается в том, что разметка документа является семантической. Перечислим основные свойства языка XML [2]: - Независимый формат данных. При использовании XML как формата выходных и входных данных приложения, данные становятся независимы от самого приложения, что повышает способность взаимодействия. - Одни данные, несколько представлений. В силу того, что формат не зависит от приложения, очевидно, что одни и те же данные можно отображать разными способами и разными приложениями. - Улучшенные возможности поиска данных. Поскольку XML определяет семантическую структуру документа, это способствует созданию дополнительных возможностей для поиска информации. Например, индексирующие и поисковые средства могут работать не только с самими данными, но и с разметкой (метаданными) - Облегчение доступа к данным. В мире в настоящее время существует большое количество информации, доступ к которой затруднен из-за того, что она хранится в разнородных и несовместимых форматах. Перевод в формат XML откроет доступ к таким данным. - Более простая разработка приложений. XML делает необязательной реализацию поддержки большого количества бинарных форматов, вследствие чего разработка приложений становится значительно проще. - Использование готовых решений. При управлении данными, как правило возникает необходимость решения «шаблонных» задач, таких, как верификация данных, лексический и синтаксический разбор, и т.д.
∗
Работа частично поддержана грантом РФФИ 02-01-01088-а 191
Переход к формату XML способен убрать необходимость создания своих собственных реализаций для решения подобных задач. - XML файл может быть прочитан человеком. - XML поддерживается большим количеством стандартов. Эти стандарты предназначены для того, чтобы гарантировать совместимость приложений пользователя и готовых решений. В их число входят стандарты API для лексического и синтаксического анализа (SAX), стандарт для управления объектной моделью документа (DOM) и другие стандарты, которые будут рассмотрены ниже. Как видно из перечисленных свойств, в XML заложен потенциал для революционных изменений в области хранения и обработки данных. Из множества задач программирования, решаемых с помощью XML, можно выделить подкласс, включающий такие задачи, как обмен сообщениями между приложениями, управление данными некоторой предметной области, хранение полуструктурированных данных и т.д. [2,3]. Для каждой отдельно взятой задачи необходимо сужение допустимого множества XML-документов. Поэтому зачастую необходима спецификация множества возможных XMLдокументов, которые будут обрабатываться. Для этого используются словари XML-документов, по сути являющиеся схемами данных, представленных в формате XML. Здесь необходимо заметить, что логическая модель данных XML довольно близка к модели полуструктурированных данных [4]. Схемы XML (как и схемы данных, представленных в терминах любой другой модели данных) предназначены для описаний структурных и семантических ограничений, которые должны выполняться в любом экземпляре данных, соответствующем этой модели. Про множество данных, на которых выполняются ограничение схемы, говорят, что оно удовлетворяет данной схеме. Характерным примером структурного ограничения для XMLдокументов является спецификация содержания элементов (например, элемент с именем А может содержать только элементы с именем В), а примером семантического ограничения – спецификации ключей (атрибут a, содержащийся в элементе A, должен обладать уникальным значением среди множества значений атрибутов a). В текущее время существует около дюжины языков спецификаций схем данных, поддерживаемых различными организациями (W3C, OASIS и т.д.). Наиболее популярными языками являются DTD [1], XML Schema [5], RelaxNG [6], XDR [7]. Как отмечалось выше, все они предназначены для спецификации структурного и семантического содержания XML документов. Несмотря на то, что языки спецификации схем достаточно сильно различаются по выразительной силе, многие принципы построения ограничений схожи. В большей степени это касается структурных ограничений. Поэтому многие свойства структурных ограничений в терминах одного языка имеют свои аналоги для другого языка спецификации. Язык DTD является одним из 192
наиболее простых языков спецификации схем. Выразительная мощность этого языка существенно ниже, чем в других [17], однако этот язык имеет определенные преимущества. Во-первых, DTD является де-факто стандартом спецификации схем (по крайней мере, пока стандарт XML Schema не будет окончательно утвержден). В большом количестве алгоритмов и программных средств, предназначенных для управления XML-данными, для определения используется именно DTD. Во-вторых, схемы DTD можно однозначно отобразить на другие XML-схемы. Стоит заметить, что решения многих задач управления данными XML инвариантны по отношению к выбору языка спецификаций, что облегчает переход от одной схемы к другой. Основной целью данной работы является изучение свойств XML-схем и методов преобразования схем данных над моделью XML, которые могут быть использованы в качестве вспомогательного инструмента для создания и реализации некоторых задач, связанных с управлением данными и метаданными XML. Основная идея нашего подхода заключается в разработке методики, позволяющей существенно упростить реализацию этих алгоритмов, за счет выделения подклассов из всего многообразия XML-схем. Выделенный подкласс должен обладать следующим свойством: реализация алгоритма для схем, принадлежащих данному подклассу, существенно упрощается по сравнению с алгоритмом, работающим на всем многообразии схем XML. Схемы, принадлежащие определенному подклассу, называются схемами, представленными в нормальной форме. Статья организована следующим образом. В начале мы приводим формальное определение структурных частей (сигнатур) схем XML, основанное на регулярных грамматиках деревьев. Преимущество такого представления структурных ограничений заключается в том, что любую схему, выраженную на языке регулярных грамматиках деревьев, можно отобразить на существующие языки спецификаций схем XML и наоборот, структурные ограничения, выраженные на наиболее распространенных языках спецификаций схем выразимы с помощью регулярных грамматик деревьев. В следующем разделе, мы приводим классификацию типов регулярных грамматик и их соответствие языкам спецификаций схем XML. Далее мы вводим преобразования схем XML, приводящие их к эквивалентному виду (с точностью до отношения эквивалентности). В четвертом разделе мы определяем нормальные формы схем и приводим теоремы существования нормальных форм для любой схемы. Затем, мы обсуждаем методы использования алгоритмов нормализации для решения практических задач, связанных с управлением XML-данными, в частности для построения отображения моделей данных. Наконец, в последнем разделе, мы описываем логические языки, предназначенные для формулирования ограничений целостности XML.
193
2. Структурные ограничения XML В этом разделе мы приводим формальное определение схем, состоящих из структурных ограничений, и формулируем термин «валидируемость». Также мы приводим определения эквивалентности схем и отношения порядка на схемах, которые будут использоваться в дальнейшем. Раздел начинается с определения регулярных выражений хорошо известных из литературы по грамматикам и языкам программирования. Определение 1 (Регулярные выражения над множеством символов E). Множество регулярные выражения над множеством E (reg(E))определяются следующим образом: 1) ε - регулярное выражение, где ε обозначает «пустой список». 2) ∀e ∈ E: e- регулярное выражение. 3) Если е1 – регулярное выражение, то (е1), е1*, е1?, е1+ - тоже регулярные выражения. 4) Если е1 и е2– регулярные выражения, то е1,е2 и е1|е2 - тоже регулярные выражения Определение 2(Порождаемые последовательности). Пусть r- регулярное выражение над множеством E. Тогда конечная (м.б. пустая) последовательность s=[e0,..,en] символов, где ei∈E, порождается выражением r (s|=r), тогда и только тогда, когда выполняется одно из следующих соотношений: 1) Если r≡ε и s≡[] – пустая последовательность; 2) ∃ e∈ E: r≡e и s≡[e]; 3) r≡(r1) и s|=r ; 4) r≡r1* и s ∈ S, где S≡{[],[s1,..,sn] }, где ∀i : si |=r1; 5) r≡r1+ и s ∈ S, где S≡{[s1,..,sn] }, где ∀i : si |=r1; 6) r≡r1? и s ∈ S, где S≡{[],[s1] }, где s1 |=r1; 7) r≡r1,r2 и s≡[e0,…,ek, f0,..,fn], где [e0,…,ek] |=r1 и [f0,..,fn] |=r2 ; 8) r≡r1|r2 и s |=r1 или s |=r. Множество всех порождаемых последовательностей регулярного выражения r над множеством Е называется регулярным множеством и обозначается так: ℜE(r). Пример 1. Пусть E={0,1}. Множество последовательностей, порождаемых регулярным выражением (0|1)(0|1) состоит из множества последовательностей длины 2, содержащих элементы 0 и 1: [0,0];[0,1];[1,0];[1,1].
194
Регулярное выражение (0|1)* порождает множество последовательностей произвольной длины, состоящих из 0 и 1, то есть полное множество всех последовательностей над множеством E. Определение 3 (Эквивалентность регулярных выражений). Пусть r1,r2∈ reg(E). Тогда r1≅r2, если ∀ s =[e0,..,en] : s|= r1 ⇔ s|= r2 Определение 3’ (Эквивалентность регулярных выражений). Пусть r1,r2∈ reg(E). Тогда r1≅r2, если ℜE(r1)⇔ ℜE(r2) Пример 2. Регулярные выражения r*,r и r+ эквивалентны, где r – произвольное регулярное выражение над множеством r. Покажем это. Пусть s|= r+ . Тогда по определению 2 s≡[s1,..,sn], где ∀i : si |=r. Тогда s1|=r и [s2,..,sn]|=r* и, значит, s|= r*,r . В обратную сторону утверждение доказывается аналогично. Teoрема 1 (Замена выражений). Пусть f1 и f2 – есть идентичные регулярные выражения над множеством {E,r1} и {E,r2}, соответственно ,где r1 и r2 – обозначения регулярных выражений над множеством E (f1 получается из f2 путем замены символа r2 на r1 и наоборот). Пусть f’’1 и f’’2 - это два регулярных выражения над множеством E, получаемые, соответственно, из f1 и f2, с помощью замены символов r1 и r2 на регулярные выражения над множеством E. Тогда r2 ≅ r1 ⇒ f’’1 ≅ f.’’ Например, из этой теоремы следует, что выражение a|a+ ≅ a|(a*,a), так как a+ ≅ (a*,a). Определение 4 (Структурные схемы XML документов). [12] Структурная схема XML документов есть совокупность (T,E,A,p,a,r), где: • T – множество, состоящее из всевозможных доменов. • Е - множество типов элементов; тип элемента состоит из имени и условного обозначения, являющегося уникальным идентификатором типа. • A – множество типов атрибутов. Каждый тип включает в себя: o имя атрибута, o домен принимаемых значений o идентификатор обязательности (должен ли атрибут быть заполнен) o уникальный идентификатор типа атрибута. • p есть функция из множества E в reg({E,T}). p:E→ reg({id(E),T}), где id(E)- множество уникальных идентификаторов типа элемента. • a есть функция из множества E в множество всех подмножеств множества A – pows(A). a: E→pows(A), причем для любого типа 195
элементов e типы атрибутов из множества a(e) должны обладать уникальным именем. • r ∈ E и называется типом корневого элемента. Для Множества E должно быть соблюдено следующее условие: ∀e0∈ E, e ≠r ∃ (e0,e1,..,en): ∀i Данной схеме DTD соответствует структурная схема (T,E,A,p,a,r), где: T≅{#PCDATA} E≅{{Product, product}, {Name, name}, {Developer, developer}, {Summary, summary} ,{Description, description },{Para, para },{List, list}, {Item, item}, {Link, link}} (здесь и далее тип элемента представляется как пара – {имя, Идентификатор}) A≅{(URL, CDATA, Required,url)} p: p(product)= (name, developer?, summary?, description?) p(name)= p(Developer)=p(Summary)= #PCDATA p(description)= (para | list)+ p(para)=p(Item) = (#PCDATA | link)* p(list)= Item+ p(link)= ε a: 196
a(link)={URL} a(product)=a(name)=...=a(list) ≅{} r=product Таким образом, можно установить, что при отображении в структурную схему каждому имени элемента в DTD соответствует уникальный тип элемента. Множество T состоит из типа #PCDATA (Термин PCDATA обозначает произвольный набор символов, интерпретируемый синтаксическим анализатором как текстовый узел). Каждому атрибуту соответствует свой тип атрибута, значения которого устанавливаются согласно свойствам типа атрибута в DTD. Наконец, отображение p задается исходя из регулярных выражений, определяющих структуру элемента DTD. Однако, стоит отметить, что ограничения целостности, которые могут присутствовать в DTD (атрибуты типа ID или IDREF) никоим образом не отображаются на структурную схему. Ограничения целостности мы обсудим в последнем разделе работы. Заметим, что в зависимости от регулярного выражения, соответствующего элементам их типы можно классифицировать следующим образом: элементы пустого содержания : p(e) ∈ {ε}, элементы, содержащие данные : p(e) ∈ reg(T)/{ε}, элементы элементного содержания: p(e) ∈ reg(id(E))/ {ε}, элементы смешанного содержания : p(e) ∈ reg({id(E),T})/{ reg(E)∪ reg(T)} В нашем примере, link – это элемент пустого содержания, name, developer, summary – элементы содержащие данные, product, description и list – элементного содержания, и наконец para и item – смешанного. Стоит заметить, что структурным схемам вида (T,E,A,p,a,r) однозначно соответствуют регулярные грамматики деревьев [13], если положить следующее: множество F и id(Е) являются нетерминальными символами грамматики, где F – множество типов текстовых узлов, id(E) – множество уникальных идентификаторов типов элементов; T и name(E) – терминалы грамматики, где name(E) – множество имен элементов; Отображение p(e) заменяется правилом продукции одного из следующих двух видов: x → a r, где x∈ id(E), a∈ name(E), r∈ reg({E,F}) или x → a ε,где x∈ F, a∈T. В следующем разделе мы опишем классы регулярных грамматик и их соответствие языкам спецификаций схем. Следующие определения описывают понятие валидируемости XML документа. Здесь и далее XML документ рассматривается в рамках модели XML, представленной в первой главе. 197
Определение 5 (Интерпретация). Интерпретация I XML документа D в терминах структурной схемы S=(T,E,A,p,a,r) – это набор отображений I=(φ,ϕ,σ), где: φ – это отображение ED, -множества элементов документа, на множество E; ϕ - это отображение AD, -множества атрибутов документа на множество A; σ - это отображение TD, - множества текстовых узлов документа на множество T. Также должны выполняться следующие условия: (согласование имен элементов) Пусть name – функция, ставящая в соответствие узлу документа его имя. Тогда ∀e∈ ED: name(e)= name (φ(e)); (согласование имен и значений атрибутов) Пусть value– функция, ставящая в соответствие узлу документа его значение. Тогда ∀a∈ AD: name(a)= name (ϕ (a)) , value(a) ∈dom(ϕ (a)), где dom(x) – это домен принимаемых значений типа атрибута; (согласование текстовых узлов) ∀t∈ TD: value(t) ∈σ (t) (согласование атрибутов с элементами) Пусть Ae={ai} i=[0,..,ne] – множество атрибутов элемента е. Тогда ∀e∈ ED: ∀i ∈ [0,.., ne] ϕ (ai) ∈a(φ(e)); (согласование обязательных атрибутов) φ-1(es) – множество элементов документа D, которые отображаются в тип элемента es. Также пусть R(es) – это подмножество a(es), в которое входят те и только те типы атрибутов, у которых проставлен идентификатор обязательности. Тогда ∀es∈E ∀as∈ R(es) ∀e∈φ1 (es) ∃a∈ Ae : ϕ(a)= as; (согласование корневого элемента) Для rD – корневого элемента документа D : φ( rD)=r; (согласование содержания элемента) Пусть Ce = [e0,..,en] – есть упорядоченная последовательность элементов и текстовых узлов, вложенных в e. Тогда ∀e∈ ED: I(e0),.., I(en) |= p(φ(e)), где I(ei) – это одно из двух отображений {φ,σ} (в зависимости от типа узла). Определение 6 (Валидность). Документ D является валидным документом для структурной схемы S (удовлетворяет схеме S), если существует интерпретация I в терминах S (Обозначается D|=S). Данное определение является ключевым для всего дальнейшего рассмотрения. Введем следующее обозначение: DB(S) – множество всех документов XML, удовлетворяющих данной схеме. Утверждение 1 (Корректность валидности). Пусть D – схема, выраженная на языке спецификации DTD и S – соответствующая ей структурная схема. 198
Тогда DB(D)⊆DB(S). Если схема D не содержит ограничений целостности, тогда DB(D)=DB(S). Для доказательства утверждения достаточно использовать свойства отображения схем DTD в структурные схемы (они очевидно следуют из примера 3). Аналогичные утверждения можно сформулировать и доказать для других языков спецификации схем. Заметим, что далеко не всегда существует единственная интерпретация одного и того же документа. Нижеследующий пример демонстрирует случай множественной интерпретации одного и того же документа. Пример 4. На Рис. 1 представлена структурная схема и документ XML.
Рис. 1. а) структурная схема; б) документ Документ XML содержит три элемента: A, B и C. Исходя из определения интерпретации, отображение I должно ставить в соответствие каждому элементу тип элемента из множества Е с таким же именем, как и у элемента. Поэтому в любой интерпретации элементу A соответствует тип a, элементу С тип с. А вот для элемента B существует два разных типа в которые он мог бы отображаться b1 и b Достаточно легко убедиться, что в обоих случаях будут выполняться условия интерпретации. Определение 7 (Тривиальные схемы). Структурная схема называется тривиальной, если существует и притом единственный XML документ, валидный для данной схемы. Утверждение 2 (Существование тривиальной схемы). Для любого XML документа существует тривиальная структурная схема, для которой данный документ валиден. Для доказательства утверждения достаточно воспользоваться индукцией по глубине документа XML – максимальному расстоянию от корня дерева XML до листа. База индукции при n= В этом случае документ XML должен иметь следующий вид (представление в терминах модели XML [1]) – Рис. 2.
199
Рис 2. XML документ глубины 1 Как видно из рисунка, все узлы дерева помимо корня являются листами. Для формирования структурной схемы, необходимо выполнить следующие действия: 1) Множество E формируется следующим образом: для каждого узла типа «элемент», мы создаем отдельный тип элемента. 2) Множество A формируется следующим образом: для каждого узла типа «атрибут», мы создаем отдельный тип атрибута. Доменный тип состоит из одного значения – значения данного узла в документе. 3) Множество T формируется следующим образом: для каждого текстового узла в документе мы создаем отдельный домен, состоящий только из одного значения. 4) Отображение a задается по следующим правилам: для любого типа элемента e – множество a(e) состоит из типов атрибутов, соответствующих атрибутам того элемента XML, который задавал e. 5) Отображение e задается по следующим правилам: для любого типа элемента e – p(e) – это выражение вида (e0,..,en) где ei это либо тип элемента, либо домен, задаваемый i-м дочерним узлом того элемента XML, который задавал e. 6) Тип элемента r (корневой тип) задается корневым элементом дерева XML. Легко убедиться, что исходный документ удовлетворяет данной схеме. Также любой XML документ, удовлетворяющий данной схеме, совпадает с исходным документом. То есть схема является тривиальной. Индуктивный переход осуществляется следующим образом. Пусть утверждение доказано для документа, максимальная глубина которого равна n. Пусть у нас есть документ XML глубины n+1. В терминах XML модели, его можно представить в виде дерева глубины n+1. Рассмотрим множество поддеревьев, с корнями в дочерних узлах корневого документа исходного дерева. Их максимальная глубина не превышает n. По предположению индукции им ставятся в соответствие тривиальные схемы. Общая схема формируется путем объединения множеств E,T,A каждой из этих тривиальных 200
схем и продлением отображений a и p . Затем мы формируем еще один тип элемента r, соответствующий корню исходного XML документа, и продляем отображения a и p на него. Отображение a(r) возвращает множество атрибутов корневого элемента, а p(r)=(r0,..,rn), где ri – корневой тип элемента тривиальной схемы, порожденный i-м узлом. Способ создания тривиальной схемы, использованный в утверждении 2, задает инъективное отображение множества документов XML на множество схем. Этот результат используется в работе [15] для реализации алгоритмов трансляции выражений алгебры управления структурными схемами в выражения языка запроса к данным XML. Легко показать, что все домены из множества T – доменных типов тривиальной схемы содержат в точности одно значение. Лемма 1 (Достаточное условие тривиальности). Любая схема S=(T,E,A,p,a,r) такая, что для любого типа элементов e, регулярное выражение p(e) имеет вид r1,..,rn, где ri есть символы базового алфавита, является тривиальной или пустой схемы.
3. Классы регулярных грамматик В этом разделе мы приводим классификацию структурных схем. Данный метод заимствован из работы [13], где он используется для классификации грамматик деревьев. Определение 8 (Локальные структурные схемы). Структурная схема называется локальной, если не существует двух типов элементов с одинаковым именем. Структурная схема из примера 3 является локальной, в то время как схема из примера 4 не является таковой. Следующее утверждение выполняется для локальных схем. Утверждение 3 (Единственность интерпретации). Пусть S=(T,E,A,p,a,r) локальная структурная схема и XML документ D валиден для S. Пусть также любые два домена из множества Т не пересекаются и для любого типа элемента e, мультимножество имен типов атрибутов из множества a(e) содержит только уникальные значения. Тогда существует, и, притом единственная интерпретация документа D в терминах S. Существование интерпретации следует из самой формулировки утверждения. Для доказательства единственности воспользуемся формулировкой интерпретации. Из правила согласования имён элементов, и локальности схемы следует, что в любой интерпретации каждый элемент документа XML должен отображаться на один и тот же тип элемента, так как имена всех типов уникальны. Из того, что любые два домена не пересекаются и из свойства согласования текстовых узлов следует, что в любой интерпретации каждый узел документа XML должен отображаться на один и тот же домен. Таким 201
образом, достаточно проверить, что отображение атрибутов сохраняется в любой интерпретации. Это следует из свойств согласования атрибутов с элементами, согласования имен и значений атрибутов и из того, что для любого типа элемента e, мультимножество имен типов атрибутов из множества a(e) содержит только уникальные значения. Прежде чем описать следующий класс структурных схем, приведем следующее определение, относящееся к регулярным выражениям: Определение 9 (Допустимые символы). Пусть r- регулярное выражение над множеством M. Тогда ΔM(r) – это множество, содержащее все элементы из M, которые присутствуют в записи регулярного выражения. Например, если E={0,1,2}, то ΔM((0*,1*))= {0,1} Теорема 2 (Критерий допустимости). Пусть r- регулярное выражение над E. Тогда
∀e∈E: e∈ΔM(r) ⇔ ∃ s=[e0,..,ei-1,e,ei+1,..,en]: s|=r Определение 10 (Однотипные структурные схемы). Структурная схема S=(T,E,A,p,a,r) называется однотипной, если для любого типа элемента e, все типы элемента из множества ΔE(p(e)) обладают разными именами. Определение 11 (Ограничено-однотипные структурные схемы). Структурная схема S=(T,E,A,p,a,r) называется ограниченно-однотипной, если для любого типа элемента e, выполняется следующее условие: ∀s1=(e0,..,en), ∀ s2=( e’0,..,e’m), где s1|=p(e) и s2|=p(e), и ∀ i: ∀j
выраженным на языке DTD принадлежит классу локальных структурных схем. Множество структурных схем, соответствующих схемам, выраженным на языке DTD принадлежит классу однотипных структурных схем. И наконец, множество структурных схем, соответствующих схемам, выраженным на языке Relax NG, является полным множеством структурных схем.
4. Преобразования структурных схем В этом разделе мы обсудим различные методы преобразования структурных схем. Эти преобразования можно разделить на три вида: - Эквивалентные преобразования – приводящие к схеме эквивалентной исходной. - Слабо-эквивалентные – приводящие к схеме, множество валидируемых документов, которой совпадает с множеством валидируемых документов исходной схемы с точностью до перестановки порядка элементов в документе. - Упрощающие – приводящие к схеме не эквивалентной исходной. Однако для любого документа, валидируемого исходной схемой должен существовать документ валидируемый получаемой схемой, отличающийся только порядком следования элементов. Определение 12 (Эквивалентность структурных схем). Схемы D и D’ эквивалентны, если множества валидируемых XML документов каждой из этих схем совпадают. Теорема 3 (Достаточное условие эквивалентности). Две схемы S=(T,E,A,p,a,r) и S’=( T’,E’,A’,p’,a’,r’) эквивалентны если существует взаимно однозначное отображение M=(φ,ϕ,σ), где φ:E→ E’ ; ϕ: E→ E’; σ: T→ T’ обладающее следующими свойствами (отображение M-1 обладает аналогичными свойствами): 1) σ(t)≡t 2) name(e)= name(φ( e)) 3) φ(r) ≡r 4) a≡ϕ (a) (сохраняются все свойства типов атрибута) 5) ∀ e ∀ a∈a(e): ϕ(a)∈a’(φ(e)) и R(φ(e))⊆ ϕ(a(e)) 6) ∀s=[s0,..,sn] s|=p(e)⇒s’=[M(e0),..,M(en)]|=p’(φ(e)) Для доказательства достаточно проверить, что каждый XML документ, удовлетворяющий схеме S должен удовлетворять схеме S’ . Проверка того, что каждый XML документ, удовлетворяющий схеме S’ удовлетворяет схеме S, производится аналогично. Итак, пусть D|=S , где D – XML документ. В силу определения 6 должна существовать интерпретация I=(φ’,ϕ’,σ’) документа D в терминах S. Рассмотрим отображение I’=M•I =(φ•φ’, ϕ•ϕ’, σ•σ’). Докажем, что это интерпретация документа D в терминах S’. 203
∀e∈ ED: name(e)= name (φ’(e))=name(φ•φ’(e)) (согласование имени элементов). 2) ∀a∈ AD: name(e)= name (ϕ’(a))=name(ϕ•ϕ’ (a)) value(a) ∈dom(ϕ’(a)) = dom(ϕ•ϕ’(a)) (согласование имен и значений атрибутов). 3) ∀t∈ TD: value(t) ∈σ’ (t) ≡ σ•σ’ (t) (согласование текстовых узлов) 4) ∀ ae ∈ Ae : ϕ ‘( ae) ∈a(φ’(e)) ⇒ϕ•ϕ’ ( ae) ∈ a(φ•φ’ (e)) (согласование атрибутов с элементами). 5) ∀e∈ ED: I(e0),.., I(en) |= p(φ’(e)) ⇒ I(e0),.., I(en) |= p(φ•φ’ (e)) (согласование содержания элемента). Остальные свойства интерпретации проверяются аналогично. 1)
В случае, когда E≡E’ шестое условие принимает следующий вид p≅p’. Следствие 1 (Критерий эквивалентности схем, отличающихся только структурами). Пусть S=(T,E,A,p,a,r) и S’=( T,E,A,p’,a,r) две структурные схемы, у которых множество валидируемых XML документов непустое, и отличающиеся только регулярными выражениями, задающими структурное вложение. Тогда схемы S и S’ эквивалентны тогда и только тогда, когда ∀e∈ E p(e) ≅ p’(e). Достаточное условие является следствием теоремы 3, а необходимое условие проверяется на множестве экземпляров XML документов, удовлетворяющих схемам.
4.1. Эквивалентные преобразования Утверждение 7 (Эквивалентные регулярные выражения). регулярные выражения являются эквивалентными:
Следующие
(r) ≅r (3.1.1) r?≅r|ε (3.1.2) r+≅r*,r (3.1.3) r**≅r* (3.1.4) r1| r2 ≅ r2|r1 (3.1.5) (r1| r2),r3≅ ( r1, r3)|( r1, r2) (3.1.6) ε*≅ε (3.1.7) (r1| r2)* ≅ ( r1*, r2*)* (3.1.8) r*≅ r+|ε (3.1.9) r, ε≅r (3.1.10) r1*, r1*≅ r1* (3.1.11) r1*, r1+≅ r1+ (3.1.12) r1*, r1?≅ r1* (3.1.13) r?*≅r* (3.1.14) r+*≅r* (3.1.15) r++≅r+ (3.1.16) (r1|r2)+ ≅ ( r1+,r2+)+|( r2+, r1+)+| r1+| r2+|( r1+, r2+)+,r1+|( r2+, r1+),r2+ (3.1.17) Доказательство этого утверждения хорошо известно из теории регулярных грамматик. Заметим, что перечисленные пары регулярных выражений далеко не исчерпывают полный список эквивалентных регулярных выражений. Утверждение 8 (Эквивалентные преобразования структурных схем). Пусть S=( T,E,A,p,a,r) – структурная схема. Тогда любая схема, получаемая из 204
данной путем замены регулярного выражения на эквивалентное приводит к схеме S’=( T,E,A,p’,a,r) эквивалентной исходной схеме.
4.2. Слабо-эквивалентные преобразования Определение 13 (Слабо-эквивалентные регулярные выражения). Два выражения r1 и r2 являются слабо-эквивалентными (r1 ≈ r2) , если для любой последовательности s=[s0..sn], такой что s|= r1 существует последовательность s’=[sk(0)..sk(n)] , где k есть подстановка на множестве {0,..,n} , такая что s’|= r2 и наоборот, для любой последовательности s=[s0..sn], такой что s|= r2 существует последовательность s’=[sk(0)..sk(n) ] , где k есть подстановка на множестве {0,..,n}, такая что s’|= r1 . Утверждение 9 (Слабо-эквивалентные регулярные выражения). Следующие регулярные выражения являются слабо-эквивалентными: r1,r2≈ r2, r1 (3.2.1) (r1*, r2)*≈ ε| r1*, r2+ (3.2.2) Докажем сначала первое утверждение. Пусть s=[s0..sn] |= r1,r2. Тогда из определения 2 следует, что s≡[e0,…,ek, f0,..,fn], где [e0,…,ek] |=r1 и [f0,..,fn] |=r2 . Значит s’≡[ f0,..,fn ,e0,…,ek] |= r2, r1. Докажем второе утверждение. Пусть s|=(r1*, r2)* Рассмотрим два случая: sпустая или непустая последовательность. Если s=[], то s|=ε. Пусть s непустая последовательность символов. Тогда s можно представить в следующем виде
[s10 ,.., s1k (1) , s1 ,.., s n0 ,.., s nk ( n ) , s n ] , где s ij |= r1 , 1
1
n
n
1
s i |= r
.
Тогда последова-
n
тельность s’= [s 0 ,.., s k (1) ,.., s 0 ,.., s k ( n ) , s ,.., s ] |= r1*, r2+. Что и требовалось доказать. В обратную сторону утверждение доказывается аналогично. Определение 14 (Ослабленная интерпретация). Ослабленной интерпретацией I XML документа D в терминах структурной схемы S=(T,E,A,p,a,r) называется набор отображений I=(φ,ϕ,σ), удовлетворяющий всем свойствам интерпретации, кроме согласования содержания элемента. Условие согласования содержания элемента заменяется следующим: (согласование содержания элемента) Пусть Ce = [e0,..,en] – есть упорядоченная последовательность элементов и текстовых узлов, вложенных в e. Тогда ∀e∈ ED: I(e k(0)),.., I(e k(n)) |= p(φ(e)), где k(i)- есть подстановка на множестве {0,..,n}. Определение 15 (Ослабленная Валидность). Документ D является ослабленновалидным документом для структурной схемы S (слабо удовлетворяет схеме S), если существует ослабленная интерпретация I в терминах S (Обозначается D|≈S). 205
Определение 16 (Слабая эквивалентность структурных схем). Схемы D и D’ слабо эквивалентны, если множества слабо валидируемых XML документов каждой из этих схем совпадают. Следующие утверждения являются очевидными и приводятся без доказательства. Утверждение 10 (Слабая эквивалентность эквивалентных регулярных выражений). Если регулярные выражения являются эквивалентными, то они являются слабо-эквивалентными. Следствие 2 (Достаточное условие слабой эквивалентности). Если схема S и S’ являются эквивалентными, то они являются слабо-эквивалентными. Teoрема 4 (Критерий слабой эквивалентности схем, отличающихся только структурами). Пусть S=(T,E,A,p,a,r) и S’=( T,E,A,p’,a,r) две структурные схемы, у которых множество валидируемых XML документов непустое, и отличающиеся только регулярными выражениями, задающими структурное вложение. Тогда схемы S и S’ эквивалентны тогда и только тогда, когда ∀e∈ E p(e) ≈ p’(e). Как будет показано в дальнейшем, в силу того, что при слабо-эквивалентных преобразованиях (замене регулярного выражения на слабо-эквивалентное) теряется только семантика порядка следования элементов, то их удобно использовать для трансляции из XML модели в модели, не использующие порядок в структурном описании. Также, преобразование 3.2.2 ведет к «выравниванию» схемы (в английской литературе используется термин “flattening”), тем самым, приводя её к более простому виду - без вложенных операторов Клини (*). Отдельно стоит заметить, что преобразование (r1, r2)*→ r1*, r2* , часто встречающееся в алгоритмах трансляции XML модели в реляционную, не является слабо-эквивалентным.
4.3. Упрощающие преобразования Все преобразования, которые будут представлены ниже, ведут к потере определенной, достаточно большой части информации о структуре документа. Однако они достаточно часто используются на практике. Обусловлено это тем, что упрощение структурных ограничений приводит к существенному уменьшению сложности решения многих задач, встречающихся на практике. Определение 17 (Упрощение регулярного выражения). Регулярное выражение r2 над E является упрощением р.в. r1 над E (r1 〈 r2) , если множество символов E, формирующих r2 , совпадает с множеством символов, формирующих r1, и выполняется следующее условие. Для любой последовательности s=[s0..sn] такой, что s|= r1 существует последовательность s’=[sk(0)..sk(n)] , где k есть подстановка на множестве [0,n] и s’|= r. 206
Утверждение 3. Для регулярных выражений r1 и r2 r1 〈 r2 , r2 〈 r1⇔ r1 ≈ r2, r1 ≅ r2⇒ r1 〈 r2 , r2 〈 r1 Для доказательства первого предложения в прямую сторону (r1 〈 r2 , r2 〈 r1⇒ r1 ≈ r2) достаточно воспользоваться определением упрощения. Чтобы доказать
утверждение в обратную сторону, необходимо воспользоваться критерием допустимости символов из множества E (теорема 2). Вторая часть утверждения вытекает из первой и из утверждения 10. Из этого утверждения непосредственно вытекает, что слабо-эквивалентные и эквивалентные преобразования являются упрощающими. Утверждение 4. (Упрощающие преобразования) Следующие преобразования регулярных выражений являются упрощающими:
но при этом семантика множественности сохранена (например, элемент с может быть максимум один у элемента а). Определение 18 (Упрощение схемы). Схема D’ является упрощением схемы D, если множество валидируемых документов первой схемы принадлежит множеству слабо-валидируемых элементов второй. Критерий и достаточное условие того, что схема S является упрощением схемы S’, формулируются и доказываются таким же образом, как и для слабоэквивалентных схем. В следующем разделе, мы определим нормальные формы схем XML документов и докажем теоремы существования нормальных форм произвольных структурных схем.
5. Нормальные формы структурных схем
(r1, r2)* 〈 r1*, r2*
(3.3.1)
(r1, r2)+ 〈 r1+, r2+
(3.3.2)
В этом разделе мы опишем нормальные формы структурных схем: представлений структурных ограничений, записанных определенным образом. Также мы сформулируем и докажем теоремы существования нормальных форм для любой структурной схемы.
(r1, r2)? 〈 r1?, r2?
(3.3.3)
5.1. Первая нормальная форма
(r1|r2) 〈 r1?, r2?
(3.3.4)
r1?, r1? 〈 r1*
(3.3.5)
r1+, r1+〈 r1+
(3.3.6)
Доказательство этого утверждения напрямую следует из определения порождаемых последовательностей. Заметим, что мы перечислили не все упрощающие преобразования. Пример 5. Дано следующее описание элемента : ((b|c|e|)?,(e?|(f?,(b,b)*))*) 〈 (b|c|e|)?,(e?|(f?,b*,b*))* 〈 (b|c|e|)?,(e?|(f?,b*))* 〈 (3.3.1) (3.1.11) (3.3.4) (b|c|e|)?,(e??,(f?,b*)?)* 〈 (b|c|e|)?,(e??,f??,b*?)* 〈 b?,c?,e?,(e??,f??,b*?)* 〈 (3.3.3) (3.3.4) (3.3.1) b?,c?,e?,e??*,f??*,b*?* 〈 b?,c?,e?,e*,f*,b* 〈 b*,c?,e*,f* (3.1.4),(3.1.14) (3.1),(3.1.13) Как видно из примера исходная схема приобретает весьма простой вид. Следует учесть, что информация об относительном порядке элементов утеряна, 207
Определение 19 (Конъюнктивно-множественные регулярные выражения). Конъюнктивно-множественные (к.-м.) регулярные выражения над множеством E (regKM(E))определяются следующим образом: 1) ε - к.-м. регулярное выражение, где ε обозначает «пустой список». 2) ∀e ∈ E: e- к.-м. регулярное выражение. 3) Если r1 – к.-м. регулярное выражение, то (r1), r1*- к.-м. регулярные выражения. 4) Если r1 и r2– к.-м. регулярные выражения, то r1, r2 - к.-м. регулярные выражения. Определение 20 (Первая нормальная форма). Схема S=(T,E,A,p,a,r) представлена в первой нормальной форме (эквивалентная форма), если : ∀e ∈ E p(e)=r0|..|rn , где ∀i ri ∈ regKM({id(E),T}) Teoрема 5 (Существование первой нормальной формы). Для любой схемы S=(T,E,A,p,a,r) существует схема эквивалентная ей, которая представлена в первой нормальной форме. Для доказательства этой теоремы следует воспользоваться следствием 1 из теоремы 3. Пусть e – некий элемент схемы S=(T,E,A,p,a,r). Соответственно p(e) – регулярное выражение. Используя эквивалентные преобразования регулярных выражений r?≅r|ε (3.1.2) и r+≅r*,r (3.1.3) мы приходим к регулярному выражению, соответствующему исходному, но не содержащему операций ? и +. После чего следует воспользоваться преобразованиями (r1| r2),r3≅ ( r1, r3)|( r1, r2) (3.1.6) и (r1| r2)* ≅ ( r1*, r2*)* (3.1.8), после которых 208
операция конкатенации (“|”) «поднимается». Таким образом, для любого типа элемента e, p(e) преобразуется в выражение p’(e) вида r0|..|rn, где ∀i ri ∈ regKM({id(E),T}). В силу следствия 1 новая схема S’=(T,E,A,p’,a,r), представленная в первой нормальной форме, эквивалентна схеме S. Следует заметить, что для регулярных выражений с использованием операции позитивного замыкания (“+”) вместо операции Клини (“*”)теорема о существовании нормальной формы также верна. Определение 19’ (Конъюнктивно-множественные регулярные выражения). Конъюнктивно-множественные (к.-м.) регулярные выражения над множеством E (regKM(E))определяются следующим образом: 1) ε - к.-м. регулярное выражение, где ε обозначает «пустой список»; 2) ∀e ∈ E: e- к.-м. регулярное выражение; 3) Если r1 – к.-м. регулярное выражение, то (r1), r1+- к.-м. регулярные выражения. Если r1 и r2 – к.-м. регулярные выражения, то r1, r2 – к.-м. регулярные выражения. Принимая альтернативное определение конъюнктивно-множественных регулярных выражений, доказательство теоремы 5 частично меняется. Так, вместо преобразования r+≅r*,r используется r*≅r+|ε (3.1.9). А вместо преобразования (r1| r2)* ≅ ( r1*, r2*)* для поднятия конкатенации применяется (r1|r2)+ ≅ ( r1+,r2+)+|( r2+, r1+)+| r1+| r2+|( r1+, r2+)+,r1+|( r2+, r1+),r2+ (3.1.17) Пример 6. Приведем к первой форме регулярное выражение: преобразования:
r0|..|rn , где ∀i ri ∈ regKM({id(E),T}) следующее ((b|c)?,(f?,b*)*), используя эквивалентные
(b|c)?,(f?,b*)*≅(b|c|ε),((f|ε),b*)*≅(b|c|ε),((f,b*)|(b*))*≅(b|c|ε),((f,b*)*,(b**))*≅ (b|c|ε),((f,b*)*,b*)*≅(b|c|ε),((f,b*)*)*≅(b|c|ε),(f,b*)*≅b,(f,b*)*| c,(f,b*)*| (f,b*)*.
5.2. Вторая нормальная форма Определение 21 (Конъюнктивные регулярные выражения). Конъюнктивные (к.) регулярные выражения над множеством E (regK(E))определяются следующим образом: 1) ε - регулярное выражение, где ε обозначает «пустой список»; 2) ∀e ∈ E: e- к. регулярное выражение; 3) Если r1 – к. регулярное выражение, то (r1)-к. регулярные выражения; 4) Если r1 и r2– к. регулярные выражения, то r1, r2 - тоже к. регулярное выражение; 5) Если r =(e0,..,en) , где ∀i : ei∈ E, то r* и r+ - к. регулярные выражения. Определение 22 (Вторая нормальная форма). Схема S=(T,E,A,p,a,r) представлена во второй нормальной форме (слабо-эквивалентная нормальная форма), если: 209
∀e ∈ E p(e)=r0|..|rn , где ∀i ri ∈ regK(E) Teoрема 6 (Существование второй нормальной формы). Для любой схемы S=(T,E,A,p,a,r) существует схема слабо-эквивалентная ей, представленная во второй нормальной форме. Для доказательства этой теоремы, необходимо воспользоваться результатами Теоремы 5. Для исходной схемы S существует эквивалентная схема S’, структурные ограничения которой имеют вид r0|..|rn , где ∀i ri ∈ regKM(E). Далее, для каждого ri мы воспользуемся преобразованием (r1*, r2)*≈ ε| r1*, r2+ (3.2.2) для уменьшения вложенных операторов * и +. После чего, если выражение r2 содержит операцию *, то воспользуемся преобразованием (3.1.3) для замены оператора r2+ на r2*,r Таким образом, используя индукцию по длине регулярного выражения и по глубине «вложенности» операций * и +, приходим к доказательству теоремы. Используя преобразования (3.2.1) и (3.1.11)-(3.1.16) можно добиться существенного упрощения выходной формы. Пример 7. Приведем регулярное выражение из предыдущего примера ко второй нормальной форме. (b|c)?,(f?,b*)*≅b,(f,b*)*| c,(f,b*)*| (f,b*)*≈(b|c|ε)(b*f+|ε)≈b+f+|b|cb*f+|c|b*f+|ε≈ b|cb*f+|c|b*f+|ε (в последнем переходе использовалось эквивалентное преобразование r*|r+≅r*).
5.3. Третья нормальная форма Определение 23 (Простые регулярные выражения). Простые (п.) регулярные выражения над множеством E (regS(E))определяются следующим образом: 1) ε -п. регулярное выражение, где ε обозначает «пустой список»; 2) ∀e ∈ E: e- п. регулярное выражение; 3) Если r1 и r2– п. регулярные выражения, то r1, r2 - тоже п. регулярное выражение; 4) Если r =e , где e∈ E, то r* ,r? r+ - п. регулярные выражения. Определение 24 (Третья нормальная форма). Схема S=(T,E,A,p,a,r) представлена во третьей нормальной форме (простая нормальная форма), если: ∀e ∈ E p(e)=r , где r ∈ regS(E) Teoрема 7 (Существование третьей нормальной формы). Для любой схемы S=(T,E,A,p,a,r) существует схема, являющаяся ее упрощением, и представленная в третьей нормальной форме. Для доказательства этой теоремы следует воспользоваться упрощающими преобразованиями для построения новой структурной схемы, являющейся упрощением исходной схемы и представленной в третьей нормальной форме. Для доказательства того, что такая схема существует необходимо воспользоваться индукцией по длине регулярного выражения. 210
Пример 8. Рассмотрим регулярное выражение из примера 7. (b|c)?,(f?,b*)*→(b?,c?)?,f?*,b**→b??,c??,f?*,b**→b?,c?,f*,b*→b*,c?,f* В отличие от первой и второй нормальных форм, для третьей нормальной формы можно сформулировать и доказать теорему единственности. Пусть на множестве E введено отношение порядка. Тогда, определим простые упорядоченные регулярные выражения следующим образом. Определение 25 (Простые упорядоченные регулярные выражения). Простые упорядоченные (п. у.) регулярные выражения над множеством E (regSO(E))определяются следующим образом: 1) ε -п. у. регулярное выражение, где ε обозначает «пустой список»; 2) ∀e ∈ E: e- п. у. регулярное выражение; 3) Если r =e , где e∈ E, то r* ,r? r+ - п. у. регулярные выражения; 4) Если r1 и r2– п. регулярные выражения, и ∀a1,a2 ∈E, таких, что ∃s1= [e0,..,ei-1,a1,ei+1,..,en], s2= [e’0,..,e’i-1,a2,e’i+1,..,e’n] s1|=r1, и s2|=r2 верно, что e1<e2, то r1, r2 - тоже п. у. регулярное выражение. Определение 24’ (Третья нормальная форма). Схема S=(T,E,A,p,a,r) с заданным отношением порядка на множестве E представлена в третьей нормальной форме (простая нормальная форма), если: ∀e ∈ E p(e)=r , где r ∈ regSO(E) Если не существует двух типов элементов с одинаковым именем, то отношение порядка на множестве E может соответствовать лексикографическому порядку на множестве имен элементов. Teoрема 8 (Существование и единственность третьей нормальной формы). Для любой схемы S=(T,E,A,p,a,r), такой, что на множестве Е задано отношение порядка, существует и единственная схема S’=(T,E,A,p’,a,r) , представленная в третьей нормальной форме, являющаяся ее упрощением.
6. Применение Нормальных форм В этом разделе мы приводим краткий обзор способов применения нормальных форм при решении типичных задач управления данными. Валидация XML документов. Валидация XML документов является одним из наиболее распространенных средств управления XML документами. Валидация документов используется при создании XML-СУБД, обмене сообщениями, трансформации XML документов. Одна из основных проблем при валидации документа заключается в том, что до сих пор не существует единого стандарта для XML схем: схемы могут быть выражены на языках DTD, XML Schema, Relax NG, и т.д. Однако на сегодняшний день существует ряд исследований, ориентированных на создание универсального валидатора. В этих работах схемы представляются в виде регулярных грамматик деревьев, аналогичных структурным схемам. Основная часть алгоритмов валидации – разбор списка потомков – заключается в следующем: определить 211
удовлетворяет ли упорядоченный список потомков данного элемента его модели содержания (структурному ограничению). Преобразование схем к первой нормальной форме, как впрочем, и применение эквивалентных преобразований имеют следующее значение для алгоритмов валидации: 1) После преобразования к 1НФ операции ? и + устраняются, что позволяет воспользоваться алгоритмами валидации «классических» регулярных выражений, определяемых как замыкание операций “*”, ”|”, ”,” над базовым алфавитом. 2) Все операции конкатенации (“|”) становятся внешними, что сильно структурирует модель содержания. Это приводит к упрощению алгоритма разбора списка потомков. Сопоставление схем. Задача сопоставления схем заключается в поиске эквивалентных частей в разных схемах. Решение этой проблемы применяется для интеграции данных. В текущее время ведутся исследования по автоматическому поиску зависимостей [16]. Методы автоматического сопоставления схем можно классифицировать следующим образом [16]: - Поиск в схемах/поиск в данных. Алгоритмы сопоставления схем могут исследовать зависимости только в схемах или зависимости по удовлетворяющим XML-документам. - Элементный/структурный поиск. Поиск зависимостей может применяться либо к отдельным элементам, либо к структурам (фактически, учитываются или нет структурные ограничения). - Лингвистический/логический поиск. Поиск зависимостей осуществляется по лингвистическому принципу (например, по именам элементов) или по семантическим ограничениям (например, по типам данным). В первую очередь, приведение схем к нормальным формам оказывает влияние на элементный лингвистический поиск. Приведение схем к 3НФ с заданным отношением порядка существенно упрощает поиск зависимостей и фактически сводит задачу к поиску изоморфных поддеревьев в деревьях с именованными узлами и с ребрами, размеченными «*», «+» и «?». Подробнее способы сопоставления схем будут описаны в следующей главе. Трансляция моделей. Одна из основных задач, встречающихся при создании систем хранения, управления и интеграции данных, заключается в трансляции моделей, в терминах которых экземпляры данных предоставляются, в термины «единой» модели данных. Так, несмотря на то, что XML и языки запросов к XML-данным завоёвывают в последнее время всё большую популярность, потребность хранения XML данных в «традиционных» СУБД и, соответственно, необходимость трансляции до сих пор остаётся. Обосновано это тем, что многолетний опыт, накопленный при изучении и реализациях реляционных и объектно-ориентированных СУБД невозможно игнорировать. 212
Рассмотрим основные виды трансляции данных, определенных в терминах модели XML.
6.1. XML->Relational Одним из основных направлений исследования методов трансляции моделей является трансляция XML-модели данных в реляционную [9,10]. Отличительными особенностями реляционной модели данных являются: - отсутствие упорядоченности кортежей и атрибутов, - трехуровневая модель (отношение-кортеж- атрибут), в отличие от произвольной глубины XML схем, - отсутствие атрибутов, имеющих своим значением множество, - отсутствие рекурсии. Существует различные методы автоматического представления XML документов в реляционных СУБД: - Хранение XML- данных в BLOB. - Модельно-ориентированная трансляция. Данный вид трансляции не зависит от структурных ограничений, определенных в схеме схемы, а целиком опирается на свойства модели данных XML [20]. - Трансляция, ориентированная на данные. Данные алгоритмы трансляции оперируют с XML-данными, не представленными никакой схемой [19]. На начальном этапе трансляции производится вывод схемы, представляющей XML-данные. - Трансляция с оценкой эффективности. Алгоритм трансляции, представленный в работе [18], анализирует способ трансляции XMLданных таким образом, чтобы запросы, предопределенные приложением, выполнялись наиболее эффективно. - Структурно-ориентированная трансляция. Эта трансляция опирается на информацию, полученную из XML-схемы. В алгоритмах этого типа [9,10] используются структурные ограничения, явно присутствующие в схеме, а также выводятся неявные ограничения, исследуемые в процессе анализа схемы. Проведенные исследования [9,10], касающиеся проблемы структурноориентированной трансляции из XML в реляционную модель выявили ряд возникающих трудностей и показали методы решения: 1) Наличие оператора конкатенации в модели содержания. Например, пусть у нас есть определение модели содержания элемента . Переводя в реляционную модель, наиболее близким отображением будет таблица r с двумя полями: a и b. Однако эта схема не будет отражать тот факт, что в элементе r может встретиться либо a либо b. Поэтому необходимо добавить семантическое ограничение: «если значение в поле a непустое, то значение в поле b должно быть пустым и наоборот». Если есть вложенные конкатенации (то есть конкатенации не на самом верхнем 213
уровне регулярного выражения), мы должны использовать 1НФ для вынесения конкатенаций на самый верхний уровень. 2) Наличие оператора Клини (*). Если в модели содержания какого-то узла встречается другой элемент с оператором * (), то в этом случае для элемента придется создавать отдельное отношение. Если же структура содержит вложенные операторы * (
6.2. XML->Semistructured Другим направлением трансляции XML является трансляция в полуструктурированные и объектно-ориентированные модели. Существенное отличие этих моделей от реляционной заключается в том что, данные представляются в виде ориентированного графа с именованными узлами. Последнее свойство, как правило, снимает необходимость использования 2НФ и 3НФ. Поэтому, в общем случае транслируется схема, приведенная к 1НФ или непосредственно исходная схема. Например, для полуструктурированной модели данных YAT [14] мы использовали представление структурных схем в 1НФ, в силу особенностей данной модели (отсутствие операторов + и ? и наличие оператора | с ограниченными свойствами)[15].
6.3. Relational -> XML В работе [21] перечислены основные методы автоматизации представления реляционных данных в терминах модели данных XML: - Плоская трансляция. Данный подход является наиболее тривиальным способом отображения схемы реляционной базы данных в XML-схему. Трансляция задается следующим образом: 1. Имя отношения переходит в элемент с таким же именем. Содержимое корневого элемента состоит из произвольного набора элементов, имена которых соответствуют именам отношения в базе данных. 2. Каждому отношению базы данных ставится в соответствие тип элемента, имя которого совпадает с именем отношения. Множество типов атрибутов, относящихся к данному типу элемента, соответствуют 214
паре {тип домена, имя атрибута} из заголовка отношения. - Вложенная трансляция (Nesting-Based Translation). Основной недостаток плоской трансляции заключается в том, что при создании XML-схемы не используются такая структурная возможность для моделирования XML, как наличие повторяющихся подэлементов. Вложенная трансляция устраняет этот недостаток. В работе [22] показано, каким образом достигается вложенная трансляция для отношений, представленных в 3НФ. - Трансляция с использованием «зависимостей по включению». Термин «зависимость по включению» используется в теории баз данных [21] как обобщение внешних ключей. Использование трансляции такого типа [21] позволяет вкладывать элементы, построенные из разных отношений друг в друга, исходя из информации о внешних ключах отношений и прочих зависимостей по включению. Если у отношения существует внешний ключ «на себя», получаемая схема XML будет рекурсивной. Дополнительную информацию об этих и прочих видах трансляции из модели XML в другие модели и наоборот, можно получить в работе [21].
7. Ограничения целостности XML В последнем разделе главы мы опишем различные виды ограничений целостности для XML-данных. Эти исследования, направленные на систематизацию логических способов задания ограничений целостности, были проведены в работах [8,12]. Итак, пусть S=(T,E,A,p,a,r) – Структурная схема, D- произвольный XMLдокумент, валидируемый S. Рассмотрим следующие логические выражения, являющиеся определениями ограничений целостности над схемой S. Определение 26 (Ограничение ключа). Ограничением ключа λ над схемой S=(T,E,A,p,a,r) называется логическое выражение вида K(e)→e, где e∈E, K(e)⊆a(e). Определение 27 (Документ удовлетворяет ограничению ключа). XMLдокумент D, валидируемый схемой S=(T,E,A,p,a,r) удовлетворяет ограничению ключа λ=K(e)→e, если для любой интерпретации I=(φ,ϕ,σ) выполняется следующее условие: ∀x,y∈φ-1(e):
I (x.l = y.l) →x≡y
l∈K(e)
где x.l – это прообраз типа атрибута l, являющийся атрибутом элемента x. Под равенством атрибутов в документе, здесь и далее, подразумевается равенство значений. 215
Пример 9.
Рис. 3. Пример документа XML. На Рис. 3 представлена документ XML, удовлетворяющий следующей структурной схеме: T≅{a} E≅{{a, A}, {b, B}} A≅{(C,c, CDATA, Required), (D,d, CDATA, Required)} p:p(a)= (b*) p(b)= ε a:a(b)={C,D} a(a)={} r=a. Из утверждения 3 следует, что существует единственная интерпретация документа в терминах этой схемы. Рассмотрим следующее ограничение ключа λ= {C}→B. Существует два элемента c именем b, у которых значения атрибута c совпадают. Следовательно, документ не удовлетворяет данному ограничению ключа. Однако тот же самый документ удовлетворяет другому ограничению ключа: {С,D}→B. Определение 28 (Ограничение включения). Ограничением включения λ над схемой S=(T,E,A,p,a,r) называется логическое выражение вида L1(e1)→ L2(e2) , где e1,e2∈E, L1и L2 упорядоченные множества, такие что L1⊆a(e1), L2⊆a(e2), | L1|=| L2|. Определение 29 ( документ удовлетворяет ограничению включения). XMLдокумент D, валидируемый схемой S=(T,E,A,p,a,r) удовлетворяет ограничению включения λ= L1(e1)→ L2(e2), если для любой интерпретации I=(φ,ϕ,σ) выполняется следующее условие: ∀x∈φ-1(e1) ∃ y∈φ-1(e2):
I (x.i = y.i)
i =[1,|L1 | ]
где x.i и y.i – это прообразы i-х по порядку типов атрибута из упорядоченных множеств L1(e1) и L2(e2) , являющихся атрибутами элементов x и y соответственно. Пример 10. Рассмотрим структурную схему и XML-документ из предыдущего примера. Приведенный XML-документ удовлетворяет следующему ограничению включения: λ={C}B →{D}B. 216
Определение 30 (Ограничение внешнего ключа). Ограничением включения λ над схемой S=(T,E,A,p,a,r) называется комбинация ограничения включения L1(e1)→ L2(e2) и ограничения ключа L2(e2) → e. Определение 31 (Документ удовлетворяет ограничению внешнего ключа). XML-документ D, валидируемый схемой S=(T,E,A,p,a,r) удовлетворяет ограничению внешнего ключа λ= L1(e1)→ L2(e2); L2(e2) → e2, если он удовлетворяет обоим ограничениям целостности, составляющим ограничение внешнего ключа для любой интерпретации. После того, как мы определили логические выражения, предназначенные для формулирования ограничений целостности, мы можем сформулировать определения, соответствующие формальным определениям из раздела 1.6 (определение 1.4-1.7). Определение 32 (Схема данных XML). Схема данных XML – это пара (S,E), где S – это структурная схема, а E- множество ограничений целостности над S, сформулированных в виде логических выражений следующего вида – ограничение ключа, ограничение включения, ограничение внешнего ключа. Определение 33 (Валидируемость документа XML). XML-документ D валидируется схемой (S,E), если D|=S и D удовлетворяет всем ограничениям целостности из E.
8. Заключение Основной целью данной работы является изучение свойств схем данных XMLдокументов. В работе представлено формальное определение структурных схем и изучены методы преобразования схем-экземпляров, обладающих свойством сохранения той или иной семантики. Также в работе представлены нормальные формы структурных ограничений и доказаны теоремы существования нормальных форм для произвольной структурной схемы. Как уже было показано выше, в большинстве исследований, касающихся проблем управления данными и моделями XML тем или иным образом можно установить класс семантических правил, которыми можно пренебречь для эффективности реализации. Нормальные формы схем как раз и являются способом приведения схемы к более простому виду с потерей части семантики. В заключительной части работы мы описываем способы поддержки ограничений целостности. В данный момент нами разработаны алгоритмы преобразования схем DTD и Relax NG в структурные схемы с последующим приведением к нормальным формам. На следующем этапе мы планируем расширить список поддерживаемых языков спецификаций схем (XDR, XML Schema). Затем мы планируем перейти к более детальному изучению способов применения нормальных форм схем на практике.
217
Литература 1. Extensible Markup Language (XML) 0 (Second Edition) W3C Recommendation 6 October 2000. http://www.w3.org/TR/2000/REC-xml-20001006 2. Бумфрей Ф. , Диренцо О. И др. XML:Новые перспективы WWW. М.:ДМК 2000 3. Bourret R. XML and Databases, http://www.rpbourret.com/xml/XMLAndDatabases.htm 4. Suciu, D. Semistructured Data and XML. In Proc. of the Int. Conf. on Foundations of Data Organization. 1998. 5. H. S. Thompson, D. Beech, M. Maloney, and N.Mendelsohn (Eds). XML Schema Part 1: Structures, W3C Recommendation, May 200http://www.w3.org/TR/xmlschema-1/. 6. J. Clark and M. Murata (Eds). “RELAX NG Tutorial”.OASIS Working Draft, Jun. 200 http://www.oasisopen.org/committees/relax-ng/tutorial.html. 7. Microsoft. XML Schema Developer’s guide Internet document, May 2000 http://msdn.microsoft.com/xml/XMLGuide/schema-overwiew.asp 8. W. Fan and L. Libkin. On XML integrity constraints in the presence of dtds. In Proc. ACM PODS, 200 9. J. Shanmugasundaram, K. Tufte, G. He, C. Zhang, D. DeWitt, and J. Naughton. “Relational Databases for Querying XML Documents: Limitations and Opportunities”. In VLDB, Edinburgh, Scotland, Sep. 1999. 10. Murali Mani, Dongwon Lee, XML to Relational Conversion using Theory of Regular Tree Grammars , Proceedings of the 28th VLDB Conference,Hong Kong, China, 2002 11. D.Florescu, D. Kossmann, Storing and Querying XML Data Using RDBMS , IEEE Data Eng. Bulletin, 22(3):27-34, Sep 1999 12. W. Fan and J. Simeon. "Integrity Constraints for XML". In ACM PODS, Dallas, TX, May 2000. 13. M. Murata, D. Lee, and M. Mani. Taxonomy of XML Schema Languages using Formal Language Theory. In Extreme Markup Languages, Montreal, Canada, 2001 14. S. Cluet et al. "Your mediator needs data conversion!." In Proc. of the ACM SIGMOD Conf. on Management of Data, Washington, USA, pp. 177--188, 1997. 15. L. Novak Mediation system implementation based on specification of XML schema integration: generic approach. To be appeared 16. E. Rahm, and P.A. Bernstein. A Survey of Approaches to Automatic Schema Matching. VLDB Journal 10(4):334-350. Dec. 200 17. Dongwon Lee, Wesley W. Chu.Comparative Analysisof Six XML Schema Languages. SIGMOD Record 29(3): 76-87 (2000). 18. P. Bohannon, J. Freire, P. Roy, and J. Simeon. “From XML Schema to Relations: A Cost-Based Approach to XML Storage”. In IEEE ICDE, San Jose, CA, Feb. 200 19. A. Deutsch, M. F. Fernandez, and D. Suciu. “Storing Semistructured Data with STORED”. In ACM SIGMOD, Philadephia, PA, Jun.1998. 20. T. Shimura, M. Yoshikawa, and S. Uemura. “Storage and Retrieval of XML Documents using Object-Relational Databases”. In Int’l Conf. on Database and Expert Systems Applications (DEXA), pp. 206–217,Florence, Italy, Aug. 1999. 21. Dongwon Lee, Murali Mani, Frank Chiu, Wesley W. Chu, “NeT and CoT: Translating Relational Schemas to XML Schemas using Semantic Constraints “,CIKM, 2002 22. D. Lee, M. Mani, F. Chiu, and W. W. Chu., “Nesting-based Relational-to-XML Schema Translation”. In Int’l Workshop on the Web and Databases (WebDB), Santa Barbara, CA, May 2001.
218
Автоматическая генерация графических пользовательских интерфейсов доступа к интегрированным данным на основе диаграмм классов UML∗ Д.Р. Ширяев
1. Введение Система BizQuery [1], разрабатываемая группой MODIS ИСП РАН, позволяет интегрировать разнородные источники данных. В системе применяется подход виртуальный интеграции. При виртуальной интеграции данные из различных источников приводятся к одной схеме, и пользователь “видит” данные в терминах этой схемы. При этом внутри интеграционной системы данные не хранятся. Для выполнения запроса система выделяет из исходного запроса подзапросы к источникам, и после выполнения этих частичных запросов в интеграционной системе происходит соединение полученных результатов. Запросы к системе можно формулировать на одном из двух языках запросов XQuery [2]и UQL [3]. Запросы на XQuery формулируются в терминах XML [4], а запросы на UQL – в терминах UML-модели [5]. Для удобной работы с интегрированными данными требуется обеспечить высокоуровневый доступ к ним в терминах предметной области. Для представления предметной области хорошо подходят и широко используются диаграммы классов UML – простое, мощное и выразительное средство для представления сущностей предметной области и связей между ними. Как было установлено при выполнении проекта BizQuery, информации, содержащейся в диаграмме классов UML, оказывается достаточно для построения высокоуровневого интерфейса доступа к интегрированным данным. Очевидно, что строить интерфейс вручную каждый раз для новой предметной области проблематично. В проекте BizQuery был предложен подход, при котором графические пользовательские интерфейсы (Graphic User Interfaces GUI) автоматически строятся по диаграмме классов UML-модели. Затем работа пользователя с данными производится в терминах предметной области,
∗
Работа частично поддерживалась грантом РФФИ 02-07-90300-в 219
понятных пользователю. При этом на каждом шаге навигации по модели интерфейс динамически перестраивается. В системе BizQuery за обеспечение взаимодействий с пользователями отвечает компонент Frontend. Этот компонент Frontend позволяет строить три различных вида интерфейсов: Form Generator (Forms, FG), Catalog Generator (Catalogs, CG) и GraphicMap (GM). Forms и Graphic Map являются декларативными интерфейсами, а Catalogs – навигационным. Используя декларативный интерфейс, пользователь формирует запрос путем композиции ограничений на значения атрибутов классов модели, и получает результат в виде экземпляров классов модели, удовлетворяющих наложенным ограничениям. С другой стороны, используя навигационный интерфейс, пользователь может получать все экземпляры заданного класса модели с последующей возможностью перехода по связям от данного класса к другим классам. Связи между классами определяются в диаграмме классов UML-модели. В графическом интерфейсе Forms пользователь выбирает класс, экземпляры которого он хочет получить (целевой класс), и формирует ограничения на значения атрибутов этого класса, а возможно, и на значения атрибутов классов, которые с ним связаны. В результате пользователь получает все экземпляры целевого класса, удовлетворяющие установленным ограничениям. В графическом интерфейсе Catalogs пользователь также выбирает класс, экземпляры которого он хочет получить (целевой класс). При этом пользователь получает все экземпляры данного класса. После этого можно получить все экземпляры одного из классов, связанных с данным. Таким образом, используя связи между классами, определенными в диаграмме классов UML-модели, пользователь может осуществлять “навигацию” по интегрированным данным. Важной особенностью интерфейсов Forms и Catalogs возможность их настройки в соответствии с потребностями пользователей. Пользователь может сам решить, как должен выглядеть его интерфейс, и написать соответствующий XSL-стиль. При использовании графического интерфейса Graphic Map пользователь видит всю диаграмму классов предметной области, может выбрать целевой класс и определить условия, которым должны удовлетворять интересующие его объекты целевого класса и объекты классов, связанных с целевым.
2. Генерация интерфейсов Первый этап. Подготовка UML-модели, соответствующей данной предметной области. 1. После обсуждения всех аспектов предметной области в среде Rational Rose [8] строится диаграмма класcов UML-модели (Рис. 1), соответствующая данной предметной области. 2. Диаграмма класcов UML-модели преобразуется в XMI-представление [9]. (Чтобы обеспечить возможность данного преобразования, было установлено 220
дополнение к Rational Rose «UnisysRoseXMLTools»). XMI-представления UMLмоделей, соответствующие различным предметным областям, сохраняются в репозитории BizQuery. mail mail_from : String mail_to : Str ing mail_date : String r ef_item : String
+catgraph
category name : String id_category : Integer
To Users Custom Styles
it em +mailbox 1..*
+refitem 1..* +items 1..*
+itemCategories
id : Integer featured : String location : String quantity : Float name : String pay_type : String shipping : String ref_region : String
Web Server
XSL Translator
1..* +itemref
Authorizer
1..* +categorie s
auction +persons
quantity : Integer type : String
1..*
person id_person : Integer name : String emailaddress : String phone : String street : String city : String province : String zipcode : Integer country : String homepage : String creditcard : String education : String income : Integer gender : String business : String age : Integer
Rubricator Catalog Generator
closed_auction
+seller
price : Float date : String
+watc hes
+personref
bid date : String time : String incr eas e : String id : Integer
Graphic Map
open_auction
+buyer +theperson
Form Generator
GML
initial : String res erve : Strin g cur rent : String priv acy : String start : String end : String id : String
FormsDTD
+bidder
GML Generator Dispatcher
1..*
Request Manager
Рис. 1. Диаграмма классов UML-модели.
Поток данных
Второй этап. Динамическая генерация интерфейсов по заранее построенным XMI-представлениям диаграмм классов. Процесс динамической генерации и использования интерфейсов показан на Рис. 2.
Поток команд
XMI
BQNet Client (SOAP) BQNet Interface
To Kernel Рис. 2. Динамическая генерация и работа графических интерфейсов компонента Frontend системы BizQuery.
221
222
2.1. Основные модули компонента Frontend системы BizQuery WebServer– поддерживает взаимодействия компонента Frontend системы BizQuery с пользователями. При реализации компонента Frontend использовался веб-сервер Jakarta Tomcat 3.3.1 Authorizer – модуль для авторизации пользователя. В форме авторизации вводится регистрационное имя пользователя и его пароль. Rubricator –обращается к ядру и получает дерево UML-моделей, доступных пользователю в соответствии с авторизацией. Пользователь выбирает UMLмодель, соответствующую интересующей его предметной области. Dispatcher – модуль, в котором загружается форма со списком классов выбранной метамодели. Из этого списка пользователь выбирает целевой класс. Также пользователь выбирает один из трёх интерфейсов (Forms, Catalogs и GraphicMap), в котором он будет работать. BQNet Client SOAP [11] – SOAP клиент для связи с ядром системы BizQuery. Catalog Generator – основной компонент интерфейса Catalogs. Form Generator – основной компонент интерфейса Forms. Graphic Map – основной компонент интерфейса GM. Request Manager – принимает UQL-запрос и через BQNet Client передаёт его ядру, получает результат запроса и передаёт его XSLT процессору для отображения. XSLT Translator [6] – используется для различных XSL преобразований в компоненте Frontend системы BizQuery, в том числе: • преобразует DOM (Document Object Model) [7] представление формы в HTML для отображения через Web Server; • преобразует XML файл результатов запроса в HTML для отображения через Web Server.
3. Сценарии динамической генерации и работы графических интерфейсов компонента Frontend системы BizQuery 1.
Пользователь через Web Server загружает Authorizer, вводит логин и пароль.
2.
Загружается Rubricator, через BQNet Client обращается к ядру и получает дерево UML-моделей, доступных пользователю в соответствии с авторизацией.
3.
Пользователь выбирает UML-модель, соответствующую интересующей его предметной области, эта модель загружается с сервера в виде заранее построенного XMI [9] представления диаграммы классов UML и переводится в специальное внутреннее представление на основе хэштаблиц. 223
4.
Загружается Dispatcher. Из списка классов выбранной UML-модели пользователь выбирает целевой класс. Кроме того, пользователь выбирает один из трёх интерфейсов (Forms, Catalogs, GraphicMap), который собирается использовать. Если выбран интерфейс Forms: 5f. По внутреннему представлению в соответствии с Forms DTD (см. приложение 1) строится DOM-представление выбранной метамодели. 6f. По DOM с учетом одного из стилей Custom Styles с помощью XSLT строится форма, соответствующая текущему классу, т.е. классу, информация о котором отображается в форме в данный момент (рис. 3). Первым текущим классом является целевой класс. 7f. Заполняется форма, соответствующая текущему классу. При переходе по связи сохраняется информация о заполненных значениях атрибутов текущего класса, имя связи, по которой происходит переход на другой класс, меняется текущий класс и осуществляется перестройка формы. В строку UQL-запроса добавляется запись. 8f. При нажатии кнопки Submit строится запрос и передаётся модулю Request Manager. 9f. Request Manager через BQNet Client передаёт запрос ядру и получает от него результат запроса. В соответствии с одним из стилей Custom Styles с помощью XSLT результат преобразуется в HTML и передаётся пользователю. Если выбран интерфейс Catalogs: 5c. Catalog Generator формирует запрос на выдачу всех экземпляров текущего класса и отдаёт его модулю Request Manager. Первым текущим классом является выбранный в Dispatcher целевой класс. 6с. Request Manager через BQNet Client передаёт запрос ядру, получает результат запроса, и отдаёт его модулю Catalog Generator. 7с. Catalog Generator, с помощью XSLT в соответствии со специальным стилем преобразует результат в XML документ, соответствующий Catalog DTD (см. приложение 2.) Это делается для того, чтобы пользователям было более удобно писать свои стили для преобразования результата в HTML. 8c. Далее с помощью XSLT в соответствии с одним из Custom Styles результат преобразуется в HTML и передаётся пользователю. Если количество выдаваемых экземпляров текущего класса велико, то они выдаются порциями. Для получения следующей порции достаточно нажать Next Portion. 7с. При каждом переходе по связи меняется текущий класс, строится запрос, производится обращение к модулю Request Manager, и всё повторяется, начиная с пункта 6с. Если выбран интерфейс Graphic Map:
224
5g. Из Dispatcher загружается апплет интерфейса GM, строящийся на основе специального внутреннего представления выбранной UML-модели и заранее сгенерированного gml-файла (см. приложение 3). 6g. Пользователь, осуществляя навигацию по метамодели, генерирует запрос, и далее, также как и в интерфейсе Forms, получает результат запроса.
Внизу формы расположены 3 кнопки: • `submit` – строит UQL запрос, и получает результат запроса, • `back` – возвращает к предыдущему классу, стирает последний критерий из запроса, • `reset` – стирает введённые значения атрибутов.
4. Полученные в результате генерации графические пользовательские интерфейсы
4.2. Интерфейс Catalogs
4.1. Интерфейс Forms Интерфейс Forms является наиболее привычным для пользователей. Пользователь заполняет формы в терминах предметной области и получает интересующую его информацию опять же в терминах предметной области. Внешний вид этого интерфейса зависит от используемого XSL стиля. Приведем пример формы, построенной с использованием стиля по умолчанию. В правой части формы (Рис. 3) находится информация о текущем классе (current business class) и список атрибутов текущего класса. Ограничения на текущий класс накладываются путём заполнения полей атрибутов.
Внешний вид этого интерфейса также зависит от используемого XSL стиля. Приведем пример интерфейса, построенного с использованием стиля по умолчанию (Рис. 4). В окне интерфейса Catalogs пользователь получает все экземпляры текущего класса. Если экземпляров много, то они выдаются порциями. Для получения следующей порции экземпляров необходимо нажать “Next Portion”. Каждый экземпляр класса представлен в виде отдельной таблицы. В левой части таблицы изображены атрибуты классов, а в правой части ссылки на связанные классы. Ссылка содержит имя роли и имя целевого класса. Экземпляры можно фильтровать по имени класса или по значению атрибутов. В процессе навигации по каталогам строится запрос, отправляется на сервер, и результаты запроса отображаются в том же окне.
Рис.3. Интерфейс Forms. В левой части формы располагается список классов, с которыми есть связи у текущего класса. В этом списке два столбца: имя роли связи и имя класса, к которому идет данная связь в соответствии с метамоделью. По одной из связей можно перейти к соответствующему классу. Рис. 4. Интерфейс Catalogs 225
226
4.3. Интерфейс Graphic Map Graphic Map – оригинальный графический интерфейс, в котором предметная область представляется в виде, схожем с диаграммой классов UML модели, но более удобном, компактном и понятном для конечных пользователей.
4.3.1. Представление GM Классы UML-модели распределены по боксам. Бокс – это графический объект карты, представляющий собой прямоугольник с закладками. Каждой закладке в боксе соответствует один класс UML-модели. При этом классы, объединенные в одно дерево наследования, размещаются в одном общем боксе. В каждый момент времени один из классов бокса является активным. При выборе определенной закладки бокса соответствующий класс становится активным. Между боксами карты могут иметься связи разных типов (кроме наследования), соответствующие связям диаграммы классов UML между соответствующими классами, содержащимися в боксах. Таким образом, каждое дерево наследования помещается в отдельный бокс, куда попадает главный родитель этого дерева вместе со всеми наследниками. В частном случае, если класс не принадлежит никакому дереву наследования, то он попадает в отдельный бокс один. С каждым классом модели может быть связан рисунок.
4.3.2. Расположение GM Окно браузера делится на 4 фрейма (Рис. 5). Центральный фрейм содержит графическое представление UML-модели. В правом фрейме находятся атрибуты текущего класса с текстовыми полями для ввода значений атрибутов. В левом нижнем фрейме собираются критерии для поиска. В правом нижнем фрейме находится дерево наследования текущего бокса. Вверху фрейма расположены инструменты для формулировки запроса.
5. Заключение В данной статье рассмотрены основные аспекты автоматической генерации GUI на основе диаграммы классов UML модели. Все идеи, описанные в этой статье, были реализованы в рамках компонента Frontend системы BizQuery, над которой работает наша группа MODIS [1]. Тестирование и использование системы показало удобство и эффективность разработанного подхода. Рассмотренной в данной статье темой также занимаются исследователи группы различных университетов мира, что подчёркивает ее актуальность. Появляются также первые коммерческие продукты, например Polen Ecompanion Software[10]. Литература 1. Система BizQuery http://www.ispras.ru/groups/modis/bizquery.html 2. XQuery 1.0: An XML Query Language http://www.w3.org/TR/xquery/ 3. UQL: A Query Language on Integrated Data in Terms of UML (in Russian, English) Maxim Grinev, Sergey Kuznetsov Programming and Computer Software, Vol. 28, No. 4, 2002, pp. 189-196. 4. Extensible Markup Language (XML) 1.0 (Second Edition) http://www.w3.org/TR/RECxml 5. Unified Modeling Language (UML), version 1.4 http://www.omg.org/technology/documents/formal/uml.htm 6. XSL Transformations (XSLT) Version 1.0 http://www.w3.org/TR/xslt 7. Document Object Model (DOM) http://www.w3.org/DOM/ 8. Rational Rose documentaion http://www.rational.com/ 9. XML Metadata Interchange (XMI), version 1.2 http://www.omg.org/technology/documents/formal/xmi.htm 10. Pollen UML-GUI Designer http://www.e-companionsoftware.com 11. Simple Object Access Protocol (SOAP) 1.1 http://www.w3.org/TR/SOAP/
Приложение 1. Описание Forms DTD. Forms.DTD
Рис. 5. Интерфейс Graphic Map. 227
228
model (class+)> class (attribute*, link*)> attribute EMPTY> link (multiplicity*)> multiplicity EMPTY> class name ID #REQUIRED selected (yes |no) #REQUIRED attribute type (integer | double | string | date) name CDATA #REQUIRED label CDATA #REQUIRED> link
#REQUIRED
roleName CDATA #IMPLIED name CDATA #REQUIRED type (association | aggregation | composition | inheritance) #REQUIRED targetClass IDREF #REQUIRED> Элемент model является тэгом верхнего уровня XML документа, соответствующего Forms DTD. Он содержит внутри себя информацию о метамодели, определяемой данным документом. Элементы class, attribute и link соответствуют понятиям класс, атрибут и связь в диаграмме классов UML модели. Элемент class содержит следующие атрибуты: • name – имя класса, • selected – атрибут для определения текущего класса. Для текущего класса значение атрибута ”yes”, иначе - “no”. Элемент attribute содержит следующие атрибуты: • type – тип атрибута. Значение должно быть одним из нижеследующих: integer, double, string или date, • name– имя атрибута. Имя атрибута должно иметь следующий формат: ИмяКласса.ИмяАтрибута, • label – имя атрибута, которое отображается в форме. Элемент link содержит следующие атрибуты: • roleName – имя роли связи, • name – имя связи. Тэг link содержит элемент multiplicity. Элемент multiplicity описывает, сколько сущностей класса, к которому идёт связь, могут соответствовать элементу текущего класса. Содержание тэгов lower и upper описывает соответственно максимальное и минимальное возможные значения возможного количества классов.
Приложение 2. Описание Catalog DTD.
Верхним элементом документа является элемент result. В этом элементе содержатся экземпляры классов UML модели, полученные в результате запроса. Описание экземпляра класса содержится в элементе classinstanse. Этот элемент содержит следующие атрибуты: cname - имя класса, ID- идентификатор экземпляра. Также элемент classinstanse содержит элементы attribute и reference. Элемент attribute имеет атрибут ‘aname’ – имя атрибута. Элемент reference содержит следующие атрибуты: Type – тип связи. Значение должно быть одним из нижеследующих: association, aggregation, composition, inheritance, rolename – имя роли связи. Элемент reference содержит элемент class. Элемент class содержит атрибут cname – имя класса, на который ссылается связь.
Приложение 3. Описание GML <element map (box*, link*)> <element box (tab+)> <element tab (reference*)>
Catalog DTD определяет структуру XML документа, представляющего результат запроса, вместе с информацией, извлекаемой из UML-модели. Catalog DTD: 229
230
active (yes|no) #REQUIRED> <element reference empty> <element link (turn*)> <element turn empty> Элемент map содержит информацию о всей графической карте. Элемент box описывает box. Элемент link описывает линию на карте, представляющую определенную связь между классами. Элемент reference описывает ссылку от данного класса на другой класс (важно направление) и также ссылается на тэг link по id, который описывает отображение данной связи на карте. Элемент turn определяет координаты точки перегиба линии на карте. Определения графической карты (GML) ссылаются на объекты XMI по идентификаторам: • Элемент tab содержит атрибут-ссылку по id на соответствующий класс UML модели в файле XMI. • Элемент reference содержит атрибут-ссылку по id на соответствующую ссылку UML модели в файле XMI.
231
232