Все программы, кроме самых тривиальных, заполнены ошибками, и все, что обещает их устранить, чрезвычайно заманчиво. На данный момент доказательства корректности кода являются чрезвычайно эзотерическими, в основном из-за трудностей в изучении этого и дополнительных усилий, необходимых для доказательства правильности программы. Вы думаете, что пробная версия кода когда-нибудь взлетит?
programming-practices
Casebash
источник
источник
не может быть полностью доказана, чтобы быть правильной с разумными усилиями. Для любого формального доказательства правильности вам нужна хотя бы формальная спецификация, и эта спецификация должна быть полной и правильной. Обычно это не то, что вы можете легко создать для большинства реальных программ. Например, попробуйте написать такую спецификацию для чего-то вроде пользовательского интерфейса этого дискуссионного сайта, и вы поймете, что я имею в виду.
Здесь я нашел хорошую статью на эту тему:
http://www.encyclopedia.com/doc/1O11-programcorrectnessproof.html
источник
printf("1")
правильна или нет (например, потому что требовалось «вывести одинаково распределенное случайное число от 1 до 6»), такой статический анализатор не может решить.Проблема с формальными доказательствами состоит в том, что это только отодвигает проблему на шаг назад.
Сказать, что программа правильная, равносильно тому, что программа делает то, что должна делать. Как вы определяете, что должна делать программа? Вы указываете это. И как вы определяете, что программа должна делать в крайних случаях, которые спецификация не охватывает? Ну, тогда вы должны сделать спецификацию более подробной.
Итак, скажем, ваша спецификация, наконец, становится достаточно подробной, чтобы описать правильное поведение каждого аспекта всей программы. Теперь вам нужен способ, чтобы ваши средства проверки понимали это. Таким образом, вы должны перевести спецификацию на какой-то формальный язык, который может понять инструмент проверки ... эй, подождите минутку!
источник
Формальная проверка прошла долгий путь, но обычно отраслевые / широко используемые инструменты отстают от последних исследований. Вот некоторые недавние усилия в этом направлении:
Spec # http://research.microsoft.com/en-us/projects/specsharp/ Это расширение C #, которое поддерживает контракты кода (предварительные / последующие условия и инварианты) и может использовать эти контракты для выполнения различных типов статического анализа. ,
Подобные проекты существуют для других языков, таких как JML для Java, и Eiffel имеет это в значительной степени встроенный.
Если пойти еще дальше, такие проекты, как slam и blast, могут быть использованы для проверки определенных поведенческих свойств с минимальной аннотацией / вмешательством программиста, но все еще не могут справиться со всей общностью современных языков (такие вещи, как целочисленное переполнение / арифметика указателей не моделируются).
Я полагаю, что в будущем мы увидим гораздо больше этих методов, используемых на практике. Основным препятствием является то, что программные инварианты трудно вывести без ручных аннотаций, и программисты обычно не хотят предоставлять эти аннотации, потому что это слишком утомительно / требует много времени.
источник
Нет, если не появится метод автоматического подтверждения кода без большой работы разработчика.
источник
Некоторые инструменты формальных методов (например, Frama-C для критически важного программного обеспечения для встроенного C) можно рассматривать как (своего рода) предоставление или, по крайней мере, проверку (правильности) доказательства данного программного обеспечения. (Frama-C проверяет, что программа в некотором смысле подчиняется своей формализованной спецификации и соблюдает явно аннотированные инварианты в программе).
В некоторых секторах возможны такие формальные методы, например, как DO-178C для критически важного программного обеспечения в гражданской авиации. Поэтому в некоторых случаях такие подходы возможны и полезны.
Конечно, разработка менее глючного программного обеспечения очень затратна. Но подход формального метода имеет смысл для некоторого программного обеспечения. Если вы пессимистичны, вы можете подумать, что ошибка перенесена из кода в его формальную спецификацию (которая может иметь некоторые «ошибки», потому что формализация предполагаемого поведения программного обеспечения сложна и подвержена ошибкам).
источник
Я наткнулся на этот вопрос и думаю, что эта ссылка может быть интересной:
Промышленные применения Astrée
Доказательство отсутствия RTE в системе, используемой Airbus с более чем 130 тыс. Строк кода в 2003 году, не кажется плохим, и мне интересно, кто-нибудь скажет, что это не реальный мир.
источник
Нет. Общая пословица для этого: «Теоретически, теория и практика одинаковы. На практике нет».
Один очень простой пример: опечатки.
На самом деле выполнение кода через модульное тестирование обнаруживает такие вещи практически сразу, и сплоченный набор тестов сведет на нет необходимость каких-либо формальных доказательств. Все варианты использования - хорошие, плохие, ошибки и крайние случаи - должны быть перечислены в модульных тестах, которые в конечном итоге являются лучшим доказательством того, что код верен, чем любое такое доказательство, отдельное от кода.
Особенно, если требования изменяются или алгоритм обновляется для исправления ошибки - формальное доказательство с большей вероятностью устареет, как это часто бывает в комментариях к коду.
источник
Я думаю, что ограничения, налагаемые на доказательства корректности из-за проблемы остановки, могут стать самым большим препятствием для того, чтобы доказательства корректности стали мейнстримом.
источник
Это уже используется всеми. Каждый раз, когда вы используете проверку типов вашего языка программирования, вы в основном делаете математическое доказательство правильности вашей программы. Это работает уже очень хорошо - просто нужно выбрать правильные типы для каждой функции и структуры данных, которые вы используете. Чем точнее тип, тем лучше будет проверка. Существующие типы, доступные в языках программирования, уже имеют достаточно мощные инструменты для описания практически любого возможного поведения. Это работает на всех доступных языках. C ++ и статические языки просто выполняют проверки во время компиляции, в то время как более динамические языки, такие как python, делают это при запуске программы. Проверка все еще существует на всех этих языках. (например, c ++ уже поддерживает проверку побочных эффектов так же, как это делает haskell,
источник
mutable
илиconst_cast
. Я, конечно, вижу связь, которую вы там делаете, но вкус двух подходов мне кажется довольно разным.