Теорема о структурированной программе , также называемая теоремой Бёма–Якопини , [1] [2] является результатом в теории языков программирования . Она утверждает, что класс графов потока управления (исторически называемых блок-схемами в этом контексте) может вычислить любую вычислимую функцию , если он объединяет подпрограммы только тремя определенными способами ( структуры управления ). Это
Структурированная диаграмма, подчиняющаяся этим ограничениям, в частности, ограничению цикла, подразумевающему единственный выход (как описано далее в этой статье), может, однако, использовать дополнительные переменные в форме битов (хранящихся в дополнительной целочисленной переменной в исходном доказательстве) для того, чтобы отслеживать информацию, которую исходная программа представляет по местоположению программы. Конструкция была основана на языке программирования Бёма P′′ .
Теорема составляет основу структурного программирования — парадигмы программирования, которая избегает команд goto и использует исключительно подпрограммы, последовательности, выбор и итерацию.
Теорема обычно приписывается [3] : 381 статье 1966 года Коррадо Бёма и Джузеппе Якопини . [4] Дэвид Харел писал в 1980 году, что статья Бёма–Якопини пользовалась «всеобщей популярностью», [3] : 381 особенно среди сторонников структурного программирования. Харел также отметил, что «из-за своего довольно технического стиля [статья Бёма–Якопини 1966 года], по-видимому, чаще цитируется, чем читается подробно» [3] : 381 и, после обзора большого количества статей, опубликованных до 1980 года, Харел утверждал, что содержание доказательства Бёма–Якопини обычно неверно представлялось как народная теорема , которая по сути содержит более простой результат, результат, который сам по себе можно проследить до зарождения современной теории вычислений в статьях фон Неймана [5] и Клини . [3] : 383
Харель также пишет, что более общее название было предложено HD Mills как «Структурная теорема» в начале 1970-х годов. [3] : 381
Эта версия теоремы заменяет весь поток управления исходной программы одним глобальным while
циклом, который имитирует счетчик программ, проходящий по всем возможным меткам (блокам блок-схемы) в исходной неструктурированной программе. Харел проследил происхождение этой народной теоремы до двух статей, знаменующих начало вычислений. Одна из них — описание архитектуры фон Неймана 1946 года , в котором объясняется, как работает счетчик программ в терминах цикла while. Харел отмечает, что один цикл, используемый народной версией теоремы о структурном программировании, в основном просто обеспечивает операционную семантику для выполнения блок-схемы на компьютере фон Неймана. [3] : 383 Другим, еще более старым источником, который Харел проследил для народной версии теоремы, является теорема Стивена Клини о нормальной форме 1936 года. [3] : 383
Дональд Кнут раскритиковал эту форму доказательства, которая приводит к псевдокоду, подобному приведенному ниже, указав, что структура исходной программы полностью теряется в этом преобразовании. [6] : 274 Аналогично, Брюс Ян Миллс писал об этом подходе, что «Дух блочной структуры — это стиль, а не язык. Симулируя машину фон Неймана, мы можем воспроизвести поведение любого спагетти-кода в пределах блочно-структурированного языка. Это не мешает ему быть спагетти». [7]
p := 1 while p > 0 do if p = 1 then выполнить шаг 1 из блок -схемы p := результирующий последующий шаг номер шага 1 из блок -схемы ( 0 , если нет последователя ) end if if p = 2 then выполнить шаг 2 из блок -схемы p := результирующий последующий шаг номер шага 2 из блок -схемы ( 0 , если нет последователя ) end if ... if p = n then выполнить шаг n из блок -схемы p := результирующий последующий шаг номер шага n из блок - схемы ( 0 , если нет последователя ) end if end while
Этот раздел нуждается в расширении . Вы можете помочь, дополнив его. ( Июль 2014 ) |
Доказательство в статье Бёма и Якопини проводится методом индукции по структуре блок-схемы. [3] : 381 Поскольку оно использовало сопоставление с образцом в графах , доказательство Бёма и Якопини не было по-настоящему практичным в качестве алгоритма преобразования программ , и, таким образом, открыло дверь для дополнительных исследований в этом направлении. [8]
Теорема об обратимой структурированной программе [9] является важной концепцией в области обратимых вычислений . Она утверждает, что любое вычисление, достижимое обратимой программой, может быть также выполнено с помощью обратимой программы, использующей только структурированную комбинацию конструкций потока управления, таких как последовательности, выборки и итерации. Любое вычисление, достижимое традиционной необратимой программой, также может быть выполнено с помощью обратимой программы, но с дополнительным ограничением, что каждый шаг должен быть обратимым и иметь некоторые дополнительные выходные данные. [10] Более того, любая обратимая неструктурированная программа также может быть выполнена с помощью структурированной обратимой программы с помощью только одной итерации без каких-либо дополнительных выходных данных. Эта теорема закладывает основополагающие принципы построения обратимых алгоритмов в рамках структурированного программирования.
Для теоремы о структурированной программе известны как локальные [4] , так и глобальные [11] методы доказательства. Однако для ее обратимой версии, хотя глобальный метод доказательства и признан, локальный подход, аналогичный подходу, предпринятому Бемом и Якопини [4], пока не известен. Это различие является примером, подчеркивающим проблемы и нюансы в установлении основ обратимых вычислений по сравнению с традиционными вычислительными парадигмами.
Доказательство Бёма–Якопини не решило вопрос о том, следует ли принимать структурное программирование для разработки программного обеспечения, отчасти потому, что конструкция скорее запутывала программу, чем улучшала ее. Напротив, оно положило начало дебатам. Знаменитое письмо Эдсгера Дейкстры « Go To Statement Considered Harmful » последовало в 1968 году . [12]
Некоторые ученые придерживались пуристского подхода к результату Бёма–Якопини и утверждали, что даже инструкции вроде break
и return
из середины циклов являются плохой практикой, поскольку они не нужны в доказательстве Бёма–Якопини, и поэтому они выступали за то, чтобы все циклы имели одну точку выхода. Этот пуристский подход воплощен в языке программирования Pascal (разработанном в 1968–1969 годах), который до середины 1990-х годов был предпочтительным инструментом для преподавания вводных классов программирования в академических кругах. [13]
Эдвард Йордон отмечает, что в 1970-х годах существовала даже философская оппозиция преобразованию неструктурированных программ в структурированные с помощью автоматизированных средств, основанная на аргументе, что нужно было думать в стиле структурного программирования с самого начала. Прагматический контрапункт состоял в том, что такие преобразования приносили пользу большому количеству существующих программ. [14] Среди первых предложений по автоматизированному преобразованию была статья Эдварда Эшкрофта и Зохара Манны 1971 года . [15]
Прямое применение теоремы Бёма–Якопини может привести к введению дополнительных локальных переменных в структурированную схему, а также может привести к некоторому дублированию кода . [16] Последняя проблема в этом контексте называется проблемой цикла и половины. [17] Pascal подвержен обеим этим проблемам, и согласно эмпирическим исследованиям, на которые ссылается Эрик С. Робертс , студенты-программисты испытывали трудности с формулированием правильных решений на языке Pascal для нескольких простых задач, включая написание функции для поиска элемента в массиве. Исследование Генри Шапиро 1980 года, на которое ссылается Робертс, показало, что при использовании только управляющих структур, предоставляемых Pascal, правильное решение было дано только 20% испытуемых, в то время как ни один испытуемый не написал неправильный код для этой задачи, если ему было разрешено написать возврат из середины цикла. [13]
В 1973 году С. Рао Косараджу доказал, что можно избежать добавления дополнительных переменных в структурном программировании, если разрешены произвольной глубины многоуровневые разрывы из циклов. [1] [18] Кроме того, Косараджу доказал, что существует строгая иерархия программ, в настоящее время называемая иерархией Косараджу , в которой для каждого целого числа n существует программа, содержащая многоуровневый разрыв глубины n , которая не может быть переписана как программа с многоуровневыми разрывами глубиной меньше n (без введения дополнительных переменных). [1] Косараджу ссылается на конструкцию многоуровневого разрыва в языке программирования BLISS . Многоуровневые разрывы в виде ключевого слова были фактически введены в версии BLISS-11 этого языка; в оригинальном BLISS были только одноуровневые разрывы. Семейство языков BLISS не предоставляло неограниченного goto. Язык программирования Java позже также следовал этому подходу. [19] : 960–965 leave label
Более простой результат из статьи Косараджу заключается в том, что программа сводится к структурированной программе (без добавления переменных) тогда и только тогда, когда она не содержит цикла с двумя различными выходами. Сводимость была определена Косараджу, грубо говоря, как вычисление той же функции и использование тех же «примитивных действий» и предикатов, что и исходная программа, но, возможно, с использованием других структур потока управления. (Это более узкое понятие сводимости, чем то, что использовал Бём–Якопини.) Вдохновленный этим результатом, в разделе VI своей часто цитируемой статьи, в которой было введено понятие цикломатической сложности , Томас Дж. МакКейб описал аналог теоремы Куратовского для графов потока управления (CFG) неструктурированных программ, то есть минимальных подграфов , которые делают CFG программы неструктурированной. Эти подграфы имеют очень хорошее описание на естественном языке. Они таковы:
Маккейб фактически обнаружил, что эти четыре графа не являются независимыми, когда появляются как подграфы, что означает, что необходимым и достаточным условием для того, чтобы программа была неструктурированной, является то, чтобы ее CFG имел в качестве подграфа один из любого подмножества трех из этих четырех графов. Он также обнаружил, что если неструктурированная программа содержит один из этих четырех подграфов, она должна содержать еще один отличный от набора из четырех. Этот последний результат помогает объяснить, как поток управления неструктурированной программы становится запутанным в том, что обычно называют « спагетти-кодом ». Маккейб также разработал численную меру, которая, учитывая произвольную программу, количественно определяет, насколько она далека от идеала быть структурированной программой; Маккейб назвал свою меру существенной сложностью . [20]
Характеристику Маккейба запрещённых графов для структурного программирования можно считать неполной, по крайней мере, если рассматривать структуры Дейкстры D в качестве строительных блоков. [21] : 274–275 [ необходимо разъяснение ]
До 1990 года было предложено довольно много методов для устранения goto из существующих программ, сохраняя при этом большую часть их структуры. Различные подходы к этой проблеме также предлагали несколько понятий эквивалентности, которые являются более строгими, чем просто эквивалентность Тьюринга, чтобы избежать вывода, подобного обсуждаемой выше народной теореме. Строгость выбранного понятия эквивалентности диктует минимальный набор необходимых структур потока управления. Статья JACM 1988 года Лайла Рэмшоу рассматривает область до этого момента, а также предлагает свой собственный метод. [22] Алгоритм Рэмшоу использовался, например, в некоторых декомпиляторах Java , поскольку код виртуальной машины Java имеет инструкции ветвления с целями, выраженными как смещения, но высокоуровневый язык Java имеет только многоуровневые break
и continue
операторы. [23] [24] [25] Аммаргуэлла (1992) предложил метод преобразования, который восходит к обеспечению единственного выхода. [8]
Этот раздел нуждается в дополнительных цитатах для проверки . ( Август 2013 ) |
В 1980-х годах исследователь IBM Харлан Миллс курировал разработку COBOL Structuring Facility, которая применяла алгоритм структурирования к коду COBOL . Преобразование Миллса включало следующие шаги для каждой процедуры.
Эту конструкцию можно улучшить, преобразовав некоторые случаи оператора выбора в подпроцедуры.
Материалы, еще не рассмотренные выше: