Можно ли опередить технический прогресс?

24

Об авторе: Анатолий Шалыто, профессор, д.т.н., Университет ИТМО

В мае 2025 года случился мой очередной день рождения. Получил поздравления, самое удивительное из них было от моего бывшего аспиранта Владимира Ульянцева.

Сначала он сказал: «Анатолий Абрамович, а знаете ли Вы, что более чем на 20 лет опередили технический прогресс?»

Выждав некоторое время, чтобы я успел «переварить» это откровение, он продолжил: «Тогда и позже Вы мучили студентов курсовиками по созданию проектной документации на программы. Это тогда, да многим и теперь, казалось большим чудачеством, так как при создании программ на практике такую документацию почти никто не делал и не делает, и Ваша «Инициатива за открытую проектную документацию» не получила поддержку в промышленности, хотя за всё это Вы были включены в авторский коллектив, получивший в 2008 г. премию Правительства РФ по образованию.

Прошло более 20 лет, и, делая проекты с использованием больших языковых моделей, я понял, что качество программ, генерируемых ими, напрямую зависит от качества промпта, «скармливаемого» моделям. Так вот, найти промпт, лучший, чем Ваша проектная документация, содержащая грамотно и чётко написанный текст, включающий требования (в том числе и поведенческие) к программе, описание всех используемых в ней символов и переменных, а также различные диаграммы, включая системы графов переходов взаимосвязанных конечных автоматов, формально описывающих поведение будущей программы, тесты для её проверки программы, а то и темпоральный формулы для её верификации, вряд ли удастся».

При этом, если я предлагал проектировать программу с использованием диаграмм, и только после её написания или генерации, оформлять документацию на программу, рассматривая её создание как проект, которого без выпуска проектной документации (а не только программной) не бывает, то теперь это всё надо делать до применения языковых моделей, если мы хотим получить качественную программу. Кстати, диаграммы тоже можно сгенерировать, используя те же модели (Vyatkin V., Patil S., Drozdov D., Shalyto A. LLM-based Iterative Requirements Refinement in FSM with IEC 61499 Code Generation (Итеративное уточнение требований к LLM для построения FSM с генерацией кода IEC 61499) / 23th IEEE International Conference on Industrial Informatics (INDIN 25)), написав для этого качественный промпт без грамматических ошибок и других чудачеств, которые так любят использовать, сами того не замечая, люди, пишущие технические тексты.

Обычно главная проблема при создании ПО для систем управления не в навыках программистов. Они знают, как кодировать. Проблема в том, что кодировать. Обычно средства для описания того, что программа должна делать – это разговоры, словесные описания, рисунки на листе бумаги. Это слишком отличается от средств, описывающих то, что ПО делает – от самого кода. Очень многое, в том числе время, теряется при переходе от такого описания к коду. Идея, лежащая в основе проектирования на основе моделей (не больших и не языковых), состоит в том, чтобы исключить этот разрыв. Одна и та же модель используется как системными проектировщиками для выражения того, что они хотят, так и компьютером для автоматической генерации кода.

Конечно, чтобы этот подход был успешным, бо́льшую часть работы нужно сделать задолго до начала проекта. Сначала программисты должны создать инструмент для разработки моделей, которые будут естественны для разработчиков ПО систем управления, и в то же время будут достаточно «ясными» (однозначными) для «понимания» компьютером. Программисты должны создать программу, которая превратит эти модели в код. И, наконец, они должны доказать, что сгенерированный код всегда будет делать то, что он должен делать.

И тут надо вспомнить о книге Брукс Ф. «Мифический человеко-месяц, или как создаются программные системы«, в которой сказано, что самолёт начинает летать, когда вес конструкторской документации к нему превысит его вес. Переход к безбумажным технологиям ничего по сути этого вопроса не изменяет!

При этом возникает очень интересная коллизия: никто не сомневается, что конструктив современного самолёта нельзя создать без проектной документации, и в то же время многие программисты считают, что проектную документацию на ПО никто выпускать не будет, так как после первого же изменения в программе (а изменения неизбежны) она «разойдется» с документацией. Однако в авиации, например, уже много лет назад были приняты стандарты, которые регламентируют технологию для обеспечения высокого качества ПО для самолётов.

Основным международным стандартом для достижения этой цели является стандарт DO-178C (Software Considerations in Airborne Systems and Equipment Certification), который признан «золотым» стандартом для разработки и сертификации ПО авионики во всем мире. Вспомогательные документы к DO-178C включают стандарты для современных технологий разработки: формальные методы (DO-333), разработка на основе моделей (DO-331) и объектно-ориентированные технологии (DO-332).

Ещё в стандарте DO-178B чёрным по белому было написано, что процесс сертификации ПО для бортовых систем включает в себя: тщательное документирование процессов разработки и проверки, демонстрацию прослеживаемости между требованиями, проектированием и тестированием, а также предоставление доказательств тщательного тестирования и проверки.

А вот информация об обеспечении с помощью универсального авиационного ПО ALM на базе ИИ соответствия требованиям стандарта DO-178C.

Ещё один стандарт – ISO 9001 – международный стандарт системы управления качеством, который часто используется в авиационных компаниях для построения процессов, связанных с качеством разработки, производства и обслуживания ПО.

Цель указанных стандартов – гарантировать надёжность, прослеживаемость и соответствие нормативным требованиям в авиации.

Одна из компаний, разрабатывающих технологии для создания ПО для ответственных систем – это компания Esterel Technologies (Франция), которая выросла из исследований, начатых в 1980-х годах во французской ядерной и аэрокосмической отраслях промышленности. Сотрудники Esterel Technologies были обеспокоены тем, что по мере усложнения критически важного для безопасности кода становится все труднее и труднее содержать его в порядке. В конце 80-х годов те, кто работал над военными системами авионики, отмечали, что число программных ошибок в них увеличивается. Это было связано с тем, что в это время число бортовых компьютеров на самолетах резко возросло. Вместо одного бортового компьютера теперь их было десятки, каждый отвечал за узкоспециализированные задачи, связанные с управлением, навигацией и связью. Координация этих систем для управления самолётом по мере поступления данных с датчиков и ввода команд пилотами требовала идеально синхронизированных реакций. Обработка сотен и даже тысяч событий в правильном порядке и в правильное время была определена как главная причина увеличения числа ошибок.

Стало ясно, что писать такой сложный код вручную больше нельзя. Было слишком сложно понять, что он делает, и почти невозможно проверить правильно ли он работает. Надо было что-то с этим делать, но менять инструменты в таком процессе чрезвычайно дорого. Это решение не было бы принято, если бы создателей ПО для систем управления «не припёрли к стене».

В сложившейся ситуации создатели авионики стали, в частности, сотрудничать с учёным из французского исследовательского центра INRIA Жераром Берри (G. Berry) по созданию инструмента под названием Esterel (от французского слова «реальное время»), основой которого был одноименный язык. Идея Esterel состояла в том, что, хотя традиционные языки программирования хороши для описания простых процедур, которые происходят в предопределённом порядке, но если попытаться использовать их в системах, где события могут происходить практически в любое время и практически в любом порядке, неизбежно получался беспорядок, а он в управляющем ПО катастрофичен. При этом Берри утверждал, что методы низкоуровневого программирования не будут приемлемыми для больших программ, критически важных для безопасности, поскольку они делают понимание поведения и анализ таких программ практически невозможным.

Уже почти двадцать лет назад (в июне 2006 года) мы провели Tutorial on Automata-Based Programming в рамках первой международной конференции International Computer Symposium in Russia (CSR 2006) (ПОМИ им. В.А. Стеклова), в котором было заслушано 24 доклада по тематике семинара.

Одним из докладчиков был упомянутый выше Жерар Берри, который участвовал в разработке ПО для Airbus (тип самолета – А380). В работе семинара принял участие и мой старинный знакомый Михаил Кишиневский, в то время работавший в корпорации Intel, который совместно с Берри разработал текcтово-графический автоматный язык Estrelv 7. Если Вы ознакомитесь с презентацией Берри, то поймете, насколько отличается то, как Вы создаете ПО, от того, как оно разрабатывается для ответственных систем. Я думаю, что отличия во всем, начиная с языков программирования.

Интересно, что, когда рассказал Кишеневскому о предложенной мной технологии автоматного программирования, он удивился, что она создана мною практически в одиночку, в то время как Европе нечто подобное создавали несколько коллективов ученых.

Интересно, что в 1975 году в первом издании упомянутой выше книги Брукс-мл. считал, что для создания качественного ПО «серебряной пули» не существует, а через 25 лет – в 2010 году – в третьем издании книги в отсутствии такой пули он уже был не так уверен, потому что ознакомился со статьёй Дэвида Харела (Harel D. Statechart: A Visual Formalism for Complex Systems // Science of Computer Programming. 1987. № 8, pp. 231-274, в которой описан подход к созданию ПО, близкий к автоматному программированию.

Теперь «всё, уже всё», как говорят в Тик Токе!

Но оказалось, что ещё далеко не всё – я вспомнил о существовании литературного или грамотного программирования, предложенного более тридцати лет назад Дональдом Кнутом (Literate Programming. Stanford: Center for the Study of Language and Information, 1992), суть которого состоит в том, что программа пишется так, чтобы быть понятной прежде всего человеку, а не компьютеру.

В 1983 году Кнут писал: «Я верю, что пришло время для существенно лучшего документирования программ, и что мы можем достигнуть этого, сделав программы литературными произведениями. Давайте изменим наше традиционное отношение к построению программ: вместо представления, что нашей главной задачей является объяснение компьютеру что делать, давайте сосредоточимся на объяснении человеку что мы хотим, чтобы сделал компьютер. Мне так нравится эта новая методология, что трудно удержаться от того, чтобы не вернуться к каждой когда-либо написанной мной программе и не переделать её в «литературную». Мои программы не только объяснены лучше, чем когда-либо прежде, но они ещё и лучше сами по себе, так как новая методология заставляет меня делать свою работу лучше».

Вот что ещё говорил Кнут по этому поводу: «Можно написать маленькую программу и сравнить её с маленькими драгоценными камнями, но когда речь идет о большой программе, то мы, конечно, можем притвориться, что это драгоценность, только она вряд ли ей будет. И я не думаю, что многие создатели программ были бы рады тому, что другие люди прочитают их программы в том виде, в котором они были выпущены. Я начал думать, как бы написать программу так, чтобы и людям нравилось читать её. Грамотное программирование – это отношение к программе, как к литературе: она пишется не столько для компьютера, сколько для людей, чтобы люди могли её прочитать и понять. И поскольку я пишу такие программы, то я, в некотором роде, учитель. Мне нравится учить. Я не просто обучаю компьютер, я учу читателей моих программ. Надеюсь, что однажды будут присуждать Пулитцеровскую премию за самую грамотную программу».

При таком стиле программирования программист объясняет свои решения не столько компьютеру, сколько другим людям, описывая реализацию не только «как», но и «почему». Это облегчает понимание программы, повышает её понятность для других разработчиков и пользователей. При этом программа оформляется как связное повествование или книга, где описание алгоритмов, идей и принципов перемежается с фрагментами исходного кода, которые, потом связываются между собой с помощью специальных ссылок и макросов. Грамотное программирование позволяет создавать хорошо документированные, легко поддерживаемые и понятные программы, в которых документация и код неразделимы. Первая система для грамотного программирования – WEB – была создана Кнутом для разработки редактора TeX.

Кнут считает, что грамотное программирование – это самая важная вещь, которая вышла из проекта TeX. Оно не только позволило ему быстрее и надёжнее, чем когда-либо, писать и поддерживать программы, но и было одним из самых больших источников его радости в то время. Иногда без грамотного программирования ему было не обойтись: «Некоторые из моих главных программ, таких как мета-симулятор MMIX, не могли бы быть написаны с помощью любой другой методологии, о которой я когда-либо слышал. Они были просто чересчур сложны для моего ограниченного мозга. Без грамотного программирования подобное предприятие просто провалилось бы».

Вот что написал один из тех, кому подход Кнута нравится: «В книге «TeX The Program» все 20 тысяч строк программы TeX, написанной на «Паскале», описаны простым понятным человеческим языком – это литературное произведение, в котором подробное описание программы с высоты птичьего полёта соседствует с описанием мельчайших деталей».

Но все-таки эта методология не прижилась, так как, по мнению Кнута, предложенный им подход – очень личная вещь. Он считает, что этот подход потрясающий, и использует его при написании каждой программы, которые он пишет постоянно даже сейчас, продолжая работу над книгой «Искусство программирования».

Джон Бентли, известный серией статей и книг «Жемчужины программирования», высказал свое мнение по вопросу о том, почему грамотное программирование не покорило мир: «Только небольшой процент людей хорош в программировании, и небольшой процент хорош в писательстве, а Вы хотите, чтобы многие люди хороши были сразу в этих двух ипостасях сразу».

При этом отмечу, что предложенный Кнутом подход к программированию не привился даже у того небольшого числа людей, которые хорошо пишут и тексты, и код, так как, во-первых, мало кто о нём знает, во-вторых, оно непривычно – ему практически никто не учит, а в-третьих, оно кажется более трудоёмким по сравнению с традиционным подходом, учитывая то, что после корректировки кода надо изменить и соответствующую ему литературную часть документа. С последним Кнут не согласен – выше отмечено, что сложные алгоритмы другим путём ему реализовать было бы чрезвычайно сложно.

Я же в грамотное программирование верю, так как благодаря моим усилиям выдающийся спортивный программист Дмитрий Павлов (чемпион мира по программированию по версии ICPC 2004 года + третье место там же в 2005 году) сдал мне курсовую работу «Автоматный серпентарий», в которой из-за сложности алгоритма по своей воле он использовал грамотное программирование. Посмотрите, как выглядит его программа, реализующая сложный алгоритм. Похожа она, на то, как программируете Вы? Я, конечно, понимаю, что Павлов «штучный товар», но все-таки…

Кстати, слова «по своей воле» соответствует действительности, так как Дима очень не хотел делать курсовик по автоматному программированию с выпуском проектной программной документации, но, учитывая мою «мёртвую хватку» в этом вопросе, пришёл к использованию грамотного программирования, что являлось компромиссом, который устроил и его, и меня.

Вот что писал Кнут тем, кому нравится неграмотное программирование: «Если грамотное программирование не Ваш стиль, забудьте о нем и делайте то, что Вам нравится». Обратите внимание, насколько документ в грамотном программировании отличается от так называемых самодокументирующихся программ, в которых выбираются смысловые обозначения переменных и время от времени используются комментарии, которые якобы позволяют понять, что делает программа.

Вот что даже про такие программы было написано 25 лет назад: «Центральный вопрос в практике программирования – вопрос о понимании программных текстов. Всегда хорошо иметь исходники, но проблема состоит в том, что зачастую их недостаточно. Чтобы понять некоторую нетривиальную программу, обычно требуется дополнительная документация. Эта потребность растёт экспоненциально с ростом объёма кода. Анализ текстов программ, направленный на восстановление первоначальных проектных решений, принятых разработчиками, и понимание программ являются двумя важными ветвями технологии программирования, существование которых неразрывно связано с недостаточностью исходных текстов для понимания программ. В качестве примера попробуйте понять структуру нетривиального компилятора при условии, что Вы не располагаете определением того языка, который им компилируется.

Каждый, кто участвовал в крупном проекте по реконструкции ПО, навсегда запомнит то чувство беспомощности и потерянности, которое испытываешь, когда впервые видишь гору плохо документированных (но не всегда плохо написанных) исходных текстов. Доступность исходных текстов не слишком помогает, когда отсутствует доступ к ключевым разработчикам. Если программа написана на сравнительно низкоуровневом языке типа C и плохо документирована, то все основные проектные решения обычно растворяются в деталях кодирования и требуют реконструкции. При этом ценность документации более высокого уровня, такой, как спецификация интерфейсов и описание архитектуры, может превышать ценность самого исходного текста».

Я более 50 лет проработал в проектной организации, связанной с созданием систем управления ответственными объектами, да и сейчас там работаю, и знаю, что проектов без соответствующей проектной документации не бывает. И эту документацию после каждого вида испытаний и результатам эксплуатации корректируют путём внесения изменений, на которые выпускаются в установленном порядке извещения, по которым специально обученные люди вносят изменения в контрольный экземпляр документации. При этом документация на ПО в большинстве случаев является не проектной, а программной и отличается от предлагаемой мной, но и она также в ходе всего жизненного цикла корректируется в установленном порядке. Иначе бы наступил несусветный бардак, и следующую систему этого типа было бы сдавать столь же трудоёмко, как и предыдущую.

Сегодня людям нравятся промпты, которые на первый взгляд кажутся грамотным программированием без программирования. Правда, в качество такого грамотного программирования без программирования Кнут не очень-то верит. Я думаю, что это связано с тем, что если промпт написан не в стиле грамотного программирования – разбит не на фрагменты или модули будущей программы, а на программу в целом, то не исключено, что языковая модель сгенерирует такую программу, что человек вряд ли сможет её понять.

А вот моё мнение по этому поводу. Я думаю, что промпты весьма трудно втолковать машине, так как по-человечески писать на русском языке мало кто умеет. Я уверен, что в мире и на других языках люди в настоящее время пишут тексты не лучше. Поэтому программирование по промптам я предлагаю назвать в стиле Кнута – «неграмотное программирование».

Известный советский журналист Анатолий Аграновский в свое время писал: «Кто плохо пишет, тот не плохо пишет, а плохо думает». Поэтому я предполагаю, что у того, кто плохо пишет тексты, программы написаны не на много лучше, но всё-таки несколько лучше, так как на написание кода программисты тратят значительно больше времени, чем на написание текстов. В этой ситуации, с одной стороны, такие «писатели» должны применять грамотное программирование, но с другой, вспоминая приведенные выше слова Бентли, на их неграмотную писанину скорее всего будет жутко смотреть. Однако, если людей учить, чтобы такого не было, то всё может оказаться не таким жутким.

При этом надо научить писать и оформлять проектную документацию, которая будет использоваться в качестве промпта, а также научить классно программировать либо для того, чтобы все-таки воспользоваться «грамотным программированием», либо для того, что проверить, что языковая модель сгенерировала по промпту.

О том, что я понимаю под понятием «учить», и как пишут программы даже очень толковые молодые люди, расскажу такую историю. Один очень толковый студент выполнял у меня курсовой проект по автоматному программированию, который, как и все выполненные у меня проекты, содержал проектную документацию, включавшую текст на Java. С пояснительной запиской, как обычно, мы долго возились, так как я не только принимал или не принимал у студентов работы, а долго и упорно учил их создавать.

Над кодом студент тоже долго работал, но так как я не настолько компетентен в этом вопросе, как в «писанине», то попросил «гика по Java» посмотреть код. Он посмотрел, и студент пошёл его переписывать. Напоминаю, что студент был классный, а кроме того, к этому времени он уже сдал зачёт упомянутому гику по языку Java.

Через некоторое время он переписал код, и принёс его мне, чтобы наконец-то сдать курсовик. Я был готов расписаться в его зачётке, но в этот момент ко мне зашёл ещё один «гик по Java», и я, видимо, для того чтобы похвастаться этой работой показал ему код, и … студент пошел его переписывать. После этого мне позвонил его научный руководитель спросил, что за курсовой проект у меня, если студент, который пишет статьи в лучшие физические журналы страны, не может несколько месяцев сдать курсовик. Я его успокоил тем, что это «издевательство» над студентом происходило при условии, что в ведомости к требуемом сроку, чтобы студента не дай Бог не отчислили, зачёт стоял. Научрук не успокоился, так как ему было надо, чтобы студент продолжал исследования по физике, а не тратил столько времени неизвестно на что. Я выразил ему сочувствие, но продолжил свое «чёрное дело» – обучение студента. Когда студент принёс переделанную работу, никто из «гиков по Java» её больше не смотрел, и мы на этом закончили. Кстати, с этим выпускником я дружу по сей день…

Эту историю я рассказал для того, чтобы подтвердить высказанное выше предположение о том, что на код, как и написанные тексты, лучше не смотреть, и тем более не читать. По своему опыту знаю, что инструкции по эксплуатации большинства устройств написаны так, что каждую из них можно понять только в том случае, если Вы … знаете, как устройство работает, либо Вы настолько умны, что либо всё-таки поймете, что там написано, либо додумаете за «писателей» и в состоянии понять, что же они всё-таки хотели написать.

История с грамотным программированием мне напоминает историю с технологией автоматного программирования, которая не только предполагает использование системы графов переходов взаимосвязанных конечных автоматов для описания поведения программ, но и создание грамотно (по-человечески) написанной проектной документации. И здесь тоже нужны хорошие специалисты в нескольких ипостасях. Я, как и Кнут, являюсь учителем, который учит этому с «выхлопом», близким к «кнутовскому».

Но и Кнут, и я уверены в правильности того, что каждый из нас «проповедует», тем более что при моём подходе каждая исполняемая спецификация, заданная в виде указанной систем графов переходом, также является и языком программирования, что резко упрощает корректировку документации.

Чтобы не пропустить самое интересное, читайте нас в Телеграм

Поделиться:

ОСТАВЬТЕ ОТВЕТ

Пожалуйста, введите ваш комментарий!
пожалуйста, введите ваше имя здесь