Как инженер-программист, я пишу много кода для промышленных продуктов. Относительно сложные вещи с классами, потоками, некоторыми проектными усилиями, но также и некоторыми компромиссами для производительности. Я много тестирую, и я устал от тестирования, поэтому я заинтересовался инструментами формального доказательства, такими как Coq, Isabelle ... Могу ли я использовать один из них, чтобы формально доказать, что мой код не содержит ошибок, и все готово? с этим? - но каждый раз, когда я проверяю один из этих инструментов, я не уверен, что они пригодны для повседневной разработки программного обеспечения. Теперь это может быть только я, и я ищу указатели / мнения / идеи по этому поводу :-)
В частности, у меня складывается впечатление, что для того, чтобы заставить один из этих инструментов работать на меня, потребовались бы огромные инвестиции, чтобы правильно определить, проверять объекты, методы ... рассматриваемой программы. Затем я задаюсь вопросом, не исчерпает ли прувер пар, учитывая размер всего, с чем ему придется иметь дело. Или, может быть, мне придется избавиться от побочных эффектов (эти средства проверки, кажется, действительно хорошо работают с декларативными языками), и мне интересно, приведет ли это к «проверенному коду», который нельзя будет использовать, потому что он не будет быстрым или достаточно небольшой. Кроме того, я не могу позволить себе роскошь менять язык, с которым я работаю, это должен быть Java или C ++: я не могу сказать своему боссу, что с этого момента я буду писать код в OXXXml, потому что это единственный язык в что я могу доказать правильность кода ...
Может ли кто-то с большим опытом формальных инструментов доказательства прокомментировать? Опять же - я ЛЮБЛЮ использовать формальный инструмент проверки, я думаю, что они великолепны, но у меня сложилось впечатление, что они находятся в башне из слоновой кости, которую я не могу достать из скромного рва Java / C ++ ... (PS: я также ЛЮБЛЮ Haskell, OCaml ... не поймите неправильно: я фанат декларативных языков и формальных доказательств, я просто пытаюсь понять, как я могу реально сделать это полезным для разработки программного обеспечения)
Обновление: поскольку это довольно широкий вопрос, давайте попробуем ответить на следующие более конкретные вопросы: 1) есть ли примеры использования средств проверки, чтобы доказать правильность промышленных программ на Java / C ++? 2) Подойдет ли Coq для этой задачи? 3) Если подходит Coq, должен ли я сначала написать программу на Coq, а затем сгенерировать C ++ / Java из Coq? 4) Может ли этот подход обрабатывать потоки и оптимизацию производительности?
Ответы:
Я постараюсь дать краткий ответ на некоторые ваши вопросы. Пожалуйста, имейте в виду, что это не совсем моя область исследований, поэтому некоторые из моих данных могут быть устаревшими / неверными.
Существует множество инструментов, специально разработанных для формального подтверждения свойств Java и C ++.
Однако мне нужно сделать небольшое отступление: что значит доказать правильность программы? Средство проверки типов Java подтверждает формальное свойство Java-программы, а именно то, что некоторые ошибки, такие как добавление a
float
и anint
, никогда не могут возникнуть! Я предполагаю, что вы заинтересованы в гораздо более сильных свойствах, а именно в том, что ваша программа никогда не может войти в нежелательное состояние или что вывод определенной функции соответствует определенной математической спецификации. Короче говоря, существует широкий градиент того, что может означать «проверка правильности программы», от простых свойств безопасности до полного доказательства того, что программа соответствует детальной спецификации.Теперь я собираюсь предположить, что вы заинтересованы в доказательстве сильных свойств ваших программ. Если вас интересуют свойства безопасности (ваша программа не может достичь определенного состояния), то в целом, кажется, что лучший подход - это проверка модели . Однако, если вы хотите полностью указать поведение Java-программы, лучше всего использовать язык спецификации для этого языка, например, JML . Существуют такие языки для определения поведения программ на C, например, ACSL , но я не знаю о C ++.
Когда у вас есть свои спецификации, вам нужно доказать, что программа соответствует этой спецификации.
Для этого вам нужен инструмент, который формально понимает как вашу спецификацию, так и операционную семантику вашего языка (Java или C ++), чтобы выразить теорему адекватности , а именно, что выполнение программы учитывает спецификацию.
Этот инструмент должен также позволить вам сформулировать или сгенерировать доказательство этой теоремы. Теперь обе эти задачи (определение и доказательство) довольно сложны, поэтому их часто разделяют на две части:
Один инструмент, который анализирует код, спецификацию и генерирует теорему адекватности. Как упоминал Фрэнк, Кракатау является примером такого инструмента.
Один инструмент, который доказывает теорему (ы), автоматически или в интерактивном режиме. Таким образом Coq взаимодействует с Кракатау, и есть несколько мощных автоматизированных инструментов, таких как Z3, которые также можно использовать.
Один (второстепенный) момент: есть некоторые теоремы, которые слишком трудно подтвердить с помощью автоматических методов, и известно, что автоматические средства проверки теорем иногда имеют ошибки в надежности, которые делают их менее надежными. Это область, где Coq сияет в сравнении (но это не автомат!).
Если вы хотите сгенерировать код Ocaml, то сначала обязательно напишите в Coq (Gallina), а затем извлеките код. Однако Coq ужасен при создании C ++ или Java, если это вообще возможно.
Могут ли вышеуказанные инструменты справиться с поточностью и проблемами производительности? Вероятно, нет, проблемы производительности и многопоточности лучше всего решаются специально разработанными инструментами, поскольку они представляют собой особенно сложные проблемы. Я не уверен, что у меня есть какие-либо инструменты, чтобы рекомендовать здесь, хотя проект Мартина Хофманна PolyNI кажется интересным.
В заключение: формальная проверка «реального мира» программ на Java и C ++ является большой и хорошо разработанной областью, и Coq подходит для выполнения части этой задачи. Вы можете найти общий обзор здесь, например.
источник
Я хотел бы упомянуть три замечательных применения формальных методов / инструментов формальной проверки в промышленности или нетривиальных реальных системах. Обратите внимание, что у меня мало опыта по этой теме, и я изучаю их только из чтения статей.
Инструмент с открытым исходным кодом Java Pathfinder (сокращенно JPF), выпущенный НАСА в 2005 году, представляет собой систему для проверки исполняемых программ Java-байт-кода (см. Java Pathfinder @ wiki ). Он был использован для обнаружения несоответствий в исполнительном программном обеспечении для K9 Rover в НАСА Эймс.
Эта статья: Использование проверки моделей для поиска серьезных ошибок файловой системы @ OSDI'04 показывает, как использовать проверку моделей для поиска серьезных ошибок в файловых системах. Система под названием FiSC применяется к трем широко используемым, тщательно протестированным файловым системам: ext3, JFS и ReiserFS, и обнаружено 32 серьезных ошибки. Он выиграл награду за лучшую бумагу.
В этом документе: Как веб-службы Amazon используют формальные методы @ CACM'15 описывает, как AWS применяет формальные методы к своим продуктам, таким как S3, DynamoDB, EBS и диспетчер внутренней распределенной блокировки. Основное внимание уделяется инструменту Lamport TLA + . Кстати, Лампорт интенсивно использовал свой собственный набор инструментов TLA. Он часто дает (довольно полную) формальную проверку в TLA алгоритмов / теорем, предложенных им (а также соавторами) в приложениях к статьям.
источник
Формальная спецификация программы - это (более или менее) программа, написанная на другом языке программирования. В результате, спецификация, безусловно, будет содержать свои ошибки.
Преимущество формальной проверки заключается в том, что, поскольку программа и спецификация являются двумя отдельными реализациями, их ошибки будут разными. Но не всегда: один общий источник ошибок, пропущенных случаев, часто будет совпадать. Таким образом, формальная проверка не является панацеей: она все равно может пропустить нетривиальное количество ошибок.
Недостатком формальной проверки является то, что она может налагать вдвое больше затрат на реализацию, возможно, больше (вам нужен специалист по формальной спецификации, и вам нужно использовать более или менее экспериментальные инструменты, которые идут с ней; это не будет дешевым). ).
Я полагаю, что установка тестовых случаев и создание лесов для их автоматического запуска будут лучшим использованием вашего времени.
источник
Формальная проверка теперь возможна для программ, написанных подмножеством C ++, предназначенных для критичных для безопасности встроенных систем. См. Http://eschertech.com/papers/CanCPlusPlusBeMadeAsSafeAsSpark.ppt для краткой презентации и http://eschertech.com/papers/CanCPlusPlusBeMadeAsSafeAsSpark.pdf для полной статьи.
источник
Вы задаете несколько разных вопросов. Я согласен, что кажется, что формальные методы проверки для промышленных / коммерческих приложений не так распространены однако следует понимать, что многие принципы «формальной проверки» встроены в компиляторы для определения правильности программы! таким образом, если вы используете современный компилятор, вы используете большую часть современного уровня в формальной проверке.
Вы говорите: «Я устал от тестирования», но формальная проверка на самом деле не заменит тестирование. таким образом, это вариация на тестирование.
Вы упоминаете Java. Есть много продвинутых формальных методов проверки, встроенных в программу проверки Java под названием FindBugs, которые действительно могут работать на больших кодовых базах. Обратите внимание, что в результате появятся как «ложные срабатывания, так и ложные отрицания», и результаты должны быть рассмотрены / проанализированы разработчиком-человеком. Но обратите внимание, что даже если он не выявляет реальных функциональных дефектов, он обычно выявляет «антипаттерны», которых в любом случае следует избегать в коде.
Вы больше не упоминаете о вашем конкретном приложении, кроме «промышленного». Формальная проверка на практике имеет тенденцию зависеть от конкретного применения.
Методы формальной проверки, как представляется, широко используются в ЭЭ для подтверждения правильности схемы, например, при разработке микропроцессора.
Вот пример исследования формальных инструментов проверки в области ЭЭ, проведенного Ларсом Филипсоном .
источник
Возможно, модель проверки может быть полезной.
http://alloytools.org/documentation.html Alloy - это средство проверки моделей.
Хорошая презентация, объясняющая концепцию проверки модели с использованием Alloy: https://www.youtube.com/watch?v=FvNRlE4E9QQ
В том же семействе инструментов идет «тестирование на основе свойств», все они пытаются найти контрпример для данной модели спецификации вашего программного обеспечения.
источник