ОЦЕНКА СЛОЖНОСТИ ГРАФА ФУНКЦИОНАЛЬНОЙ
ПРОГРАММЫ
А.В. Лаздин, О.Ф. Немолочнов
Рассматриваются сравнительные характеристики схемы алгоритма функциональной программы и графа, представляющего ее. Доказывается, что сложность графовой формы представления функциональной программы сопоставима со сложностью нормализованной схемы ее алгоритма.
В соответствии с определением жизненного цикла программного обеспечения [1] программа как описание алгоритма решения некоторой задачи последовательно представляется такими формами, как спецификация, схема алгоритма, исходные тексты на различных языках программирования, исполняемый код. Под исполняемым кодом в данной работе понимается программа, предназначенная для выполнения на процессоре определенного типа и под управлением конкретной операционной системы. В идеале программа должна быть инвариантна всем этим формам представления, однако на практике, в ходе трансляции одной формы представления в другую, возможно внесение ошибок и, как результат, появление ненадежных программ. Для контроля корректности преобразований широко применяется метод верификации - доказательство соответствия описания алгоритма на разных уровнях абстракции [2].
Необходимо отметить, что главной целью создания программного продукта является получение исполняемого кода (ИК). Ненадежность ИК может быть результатом, например, следующих причин:
• ошибки на этапе кодирования;
• ошибки компилятора (к негативным воздействиям при формировании ИК можно отнести оптимизацию кода в ходе компиляции в тех случаях, когда в этом либо нет необходимости, либо оптимизация недопустима, например, при формировании программных задержек с использованием циклов);
• ошибки компоновки, которые возможны при сборке программы из нескольких исходных модулей, особенно в тех случаях, когда исходные модули разрабатывались на различных языках программирования.
ИК должен быть не только надежным, но и безопасным, т.е. не содержать таких разрушающих средств, как компьютерные вирусы и программные закладки [3] .
Следовательно, ИК как итоговая форма представления исходного алгоритма должен пройти те же контрольные мероприятия (анализ, тестирование, верификация), что и другие формы представления программы.
Для проведения подобных мероприятий ИК должен быть преобразован в удобную для обработки форму представления. Наиболее естественной представляется графовая модель. В соответствии с [4] вершинами графа ИК будут команды управления последовательностью выполнения команд, а дугам соответствовать либо линейные участки последовательных команд обработки данных, либо пустые дуги, соответствующие безусловным переходам.
В данной работе дается оценка степени сложности такого представления в сравнении со схемой алгоритма исходной задачи. Известно, что схема любого алгоритма может быть представлена с помощью трех типов вершин: функциональной, предикатной и объединяющей (рис. 1).
Для одного алгоритма может существовать множество эквивалентных ему схем. Доказано, что любая схема алгоритма может быть представлена структурной схемой, элементами которой могут быть линейная последовательность функциональных вершин, альтернатива и итерация [5] .
о
Рис. 1. Типы вершин схемы алгоритма: а) функциональная; б) предикатная; в) объединяющая
Лемма 1 (о композиции функциональных вершин).
Алгоритм может быть представлен структурной схемой так, что путь между любыми двумя предикатными и(или) объединяющими вершинами будет проходить не более чем через одну функциональную вершину.
Справедливость данной леммы основана на том, что любую линейную последовательность функциональных операторов можно объединить в составной оператор (блок) без потери семантики. С позиций визуального формализма алгоритмов данная лемма проиллюстрирована на рис. 2.
Рис. 2. Две эквивалентные формы представления алгоритма
Доказательство. Тождественность алгоритмов на рисунках 2,. а и 2,. б может быть доказана в терминах пред- и постусловий для функциональных вершин [6]. Пусть VI,
У2 и У3 - предусловия операторов (или последовательностей операторов), связанных с функциональными вершинами Б2, Б3 и Б4, соответственно, а Р1, Р2 и Р3 -соответствующие этим вершинам постусловия. Связь функциональной вершины Б2 с соответствующими ей пред- и постусловием принято записывать в следующей форме: {VI} 32 {Р1} (1)
Постусловие Р1 совпадает с предусловием У2. В соответствии с этим {VI} Б2 {У2} (2)
Следовательно,
У1 ^ У2 & {У2} Б3 {Р2} (3)
Выражение (3) эквивалентно
{У1} (Б2, Б3) {Р2}. (4)
Очевидно следующее обобщение (4), для любых п идущих подряд функциональных вершин:
{У1} (31, Б2, ... Бп) {Рп-1}. (5)
Пусть { - составной оператор такой, что последовательно выполняются операторы из списка Б1, Б2, ... Бп. Тогда
{У1} ? { Рп-1}. (6)
Лемма доказана. ■
Будем называть схему алгоритма нормализованной, если в ней любая композиция операторов представлена одной функциональной вершиной в соответствии с леммой 1.
Возможные способы комбинирования предикатной и функциональных вершин, (альтернатива) показаны на рис. 3. Пусть ИК, соответствующий каждому из приведенных фрагментов схемы алгоритма, строится для процессора, набор команд которого включает условные двухадресные переходы (например, семейство процессоров 1п1е180х86). Тогда после перевода алгоритмов на язык ассемблера будут получены последовательности команд, приведенные в таблице 1. Очевидно, что в обоих случаях реализация ветвления требует помещения в ИК не более двух команд условного и безусловного переходов (в таблице мнемоники соответствующих команд выделены). Следовательно, каждому ветвлению будет соответствовать одна или две вершины графа ИК.
Г=а/Ь; е=Г+10 Г=а*10+Ь Ь=-а
ч>
т
б
а
Рис. 3. Два способа связи предикатной и функциональных вершин.
Комбинация предикатных и функциональных вершин типа "итерация" могут быть представлены одним из вариантов, показанных на рис. 4. В таблице 2 приведены соответствующие им последовательности команд. В соответствии с полученной
программной реализацией схемам итерации будет соответствовать одна или две вершины графа ИК Определим сложность графа как число его вершин. Назовем функциональной программой ИК, полученный при трансляции нормализованной схемы алгоритма.
Таблица 1
Реализация ветвления с двумя альтернативами. Реализация ветвления с одной альтернативой
mov ax,a
cmp ax,b mov ах,Ь
jng metkal стр ах,Ь
/последовательность команд jng metka1
/реализующих первую /последовательность команд
альтернативу /реализующих функциональную
mov ax,a ;вершину
imulax,10 mov ах,а
add ax,b пед ах
mov f,ax mov Ь,ах
jmp metka2 metka1:
/последовательность команд / последующие команды
/реализующих вторую
альтернативу
metkal:
mov ax,a
cwd
div b
mov f,ax
add ax,10
mov e,ax
metka2:
/последующие команды
Теорема. Сложность графа функциональной программы имеет тот же порядок, что и сложность нормализованной схемы исходного алгоритма описания задачи.
Доказательство. В соответствии с данными из табл. 3 число вершин NHC для нормализованной схемы алгоритма может быть определено следующим образом:
Nhc = 3 + 3NВ1 + 2NB2 + 2МИПр + 2МИПост . (7)
Число вершин Nгфп для графа функциональной программы:
Nr0n = 2 + 2NВ1 + NB2 + 2Nипp + Nипост , (8)
где Nm - число операторов выбора первого типа; N^ - число операторов выбора второго типа; ^Пр - число итераций с предусловием; N^oct - число итераций с постусловием.
Из анализа (7) и (8) очевидно, что число вершин графа функциональной программы не больше числа вершин нормализованной схемы алгоритма. Следовательно, они имеют один и тот же порядок сложности. ■
Полученные в статье результаты показывают, что обратное проектирование (reverse engineering) для исполняемого кода может быть программно автоматизировано, поскольку число вершин графа функциональной программы "обозримо" и зависит не столько от объема программы, сколько от числа ветвлений в ней.
Таблица 2
Реализация схемы итерации с предусловием. Реализация схемы итерации с постусловием.
next: cmp i, 10 mov ax,s
jge exit next: mov si,i
mov ax,s shl si,1
mov si,i add ax,a[si]
shl si,1 add i,1
add ax,a[si] cmp a[si+2],0
add i,10 jg next
jmp next /последующие команды
exit:
/последующие команды
Таблица 3
№ Тип фрагмента Число вершин
п/ программы нормализованная схема граф функциональной
п алгоритма (без учета вершины типа «объединение») программы
1 линейная программа 3 2
2 оператор выбора первого типа 3 2
3 оператор выбора второго типа 2 1
4 итерация с предусловием 3 2
5 итерация с постусловием 3 1
Литература
1. Вендров А.М. САБЕ-технологии. Современные методы и средства проектирования информационных систем. М.: Финансы и статистика, 1998.176 с.: ил
2. Дейкстра Э. Дисциплина программирования. М.: Мир, 1978. 275с.: ил.
3. Основы верификационного анализа безопасности исполняемого кода программ. / Матвеев В.А., Молотков С.В., Зегжда Д.П.,Мешков А.В., Семьянов П.В., Шведов Д.В. Под редакцией проф. Зегжды П.Д. СПб.: СПбГТУ, 1994. 58 с.
4. Лаздин А.В. Построение графа функциональной программы // Диагностика веществ, изделий и устройств: Материалы всероссийской научно-технической конференции. Орел. Изд-во Орл.гос.тех.ун-та, 1999. 189с., ил.
5. Гудман С., Хидетниеми С. Введение в разработку и анализ алгоритмов. М.: Мир. 1981. 366с.:ил.
6. Бейбер Л.Р.. Программное обеспечение без ошибок. М. Радио и связь. 1996. 173 с. ил.