Офіційна перевірка програми на практиці


66

Як інженер програмного забезпечення, я пишу багато коду для промислової продукції. Відносно складні речі з класами, нитками, деякими зусиллями в галузі дизайну, а також деякими компромісами для продуктивності. Я дуже багато тестую, і мені набридло тестування, тому я зацікавився інструментами формального доказування, такими як Coq, Isabelle ... Чи можу я використати один із них, щоб офіційно довести, що мій код відсутній помилок, і це можна зробити з цим? - але кожного разу, коли я перевіряю один із цих інструментів, я відмовляюсь від переконання, що вони корисні для повсякденної інженерії програмного забезпечення. Тепер це могло бути лише я, і я шукаю вказівники / думки / ідеї щодо цього :-)

Зокрема, у мене складається враження, що для того, щоб один із цих інструментів працював для мене, знадобиться величезна інвестиція, щоб правильно визначити об'єкти, методи ... розглядуваної програми. Тоді мені цікаво, чи справді не просто випаде пара, враховуючи розміри всього, з чим йому доведеться мати справу. А може, мені доведеться позбутися побічних ефектів (ці інструменти, що підтверджуються, справді добре справляються з деклараційними мовами), і мені цікаво, чи це призведе до «перевіреного коду», який не можна було б використати, оскільки це не було б швидким або досить маленький. Крім того, у мене немає розкоші змінювати мову, з якою я працюю, це повинна бути Java або C ++: я не можу сказати своєму босу, ​​що я буду кодувати в OXXXml відтепер, тому що це єдина мова в що я можу довести правильність коду ...

Чи може хтось із більшим досвідом офіційних інструментів підтвердження? Знову ж - я ЛЮБИТЬ використовувати офіційний інструмент для перевірки, я вважаю, що вони чудові, але в мене таке враження, що вони знаходяться у вежі зі слонової кістки, до якої я не можу дістатись із низької канави Java / C ++ ... (PS: I також ЛЮБИТЬ Haskell, OCaml ... не розумію неправильного: я фанат декларативних мов та формальних доказів, я просто намагаюся зрозуміти, як я міг реально зробити це корисним для інженерії програм)

Оновлення: Оскільки це досить широко, давайте спробуємо наступні конкретніші питання: 1) Чи є приклади використання доказів для підтвердження правильності промислових програм Java / C ++? 2) Чи підходить Coq для цього завдання? 3) Якщо Coq підходить, я повинен спочатку написати програму в Coq, а потім генерувати C ++ / Java з Coq? 4) Чи міг цей підхід обробляти оптимізацію нитки та ефективність роботи?


3
Я розумію і оцінюю вашу проблему, але я не розумію, що після цього питання (як посада в SE). Обговорення? Досвід? Жоден з них не підходить для SE. "Що я можу зробити?" Тон змушує мене відчувати, що це занадто широке питання.
Рафаель

3
Я бачу ... Я згоден, це питання було сформульовано чітко. Отже, скажімо: 1) чи є приклади використання доказів для підтвердження правильності промислових програм Java / C ++? 2) Чи підходить Coq для цього завдання? 3) Якщо Coq підходить, я повинен спочатку написати програму в Coq, а чи повинен Coq генерувати C ++ / Java з цього? 4) Чи міг би цей підхід впоратися з оптимізацією різьблення та продуктивності?
Френк

2
Отже, це чотири питання. 1), мабуть, краще в інженерії програмного забезпечення, оскільки ви навряд чи зможете зіткнутися з (багатьма) професіоналами галузі. 2) смак дещо суб'єктивний, але у нас можуть бути люди, які можуть запропонувати об'єктивну перспективу. 3) є, наскільки я можу сказати, повністю суб'єктивним. 4) Приємні запитання для цього сайту. Підводячи підсумок: будь-ласка, розділіть свої запитання, перейдіть до Інженерії програмного забезпечення з першим і подумайте над тим, чи можете ви очікувати об'єктивної (!) Відповіді тут (!) Перед публікацією 2).
Рафаель

10
Ви описуєте сон про офіційну перевірку, але ми дуже далекі від того, щоб бути там. AFAIK, перевірка програм є нетрадиційним завданням і стосується лише дуже простих програм. З цього приводу я думаю, що це питання є точковим для сайту, і я би вдячний, щоб хтось із району визнав межі своєї області, пояснивши сучасний стан та обмеження (можливо, посилаючись на якесь опитування ).
Yuval Filmus

9
Проблема з верифікацією програм C ++ полягає в тому, що C ++ не є чітко визначеною мовою. Я не думаю, що широкомасштабна перевірка можлива, поки багато частин програмних систем (ОС, бібліотеки, мови програмування) фактично не перероблені для підтримки перевірки. Як відомо, ви не можете просто скинути 200000 рядків коду на когось і сказати «перевірити!». Вам потрібно разом перевірити і записати код, і ви повинні адаптувати свої звички програмування до того, що ви також перевіряєте.
Андрій Бауер

Відповіді:


35

Я спробую дати коротку відповідь на деякі ваші запитання. Будь ласка, майте на увазі, що це не виключно моя сфера досліджень, тому частина моєї інформації може бути застарілою / неправильною.

  1. Існує багато інструментів, спеціально розроблених для офіційного підтвердження властивостей Java та C ++.

    Однак мені тут потрібно зробити невеликий відступ: що означає довести правильність програми? Перевірка типу Java доводить формальну властивість програми Java, а саме те, що певні помилки, такі як додавання a floatі an int, ніколи не можуть виникнути! Я думаю, що вас цікавлять набагато сильніші властивості, а саме те, що ваша програма ніколи не може входити в небажаний стан, або що вихід певної функції відповідає певній математичній специфікації. Коротше кажучи, існує широкий градієнт того, що може означати "доведення програми правильною", від простих властивостей безпеки до повного підтвердження того, що програма виконує детальну специфікацію.

    Тепер я припускаю, що вам цікаво довести сильні властивості щодо ваших програм. Якщо вас цікавлять властивості безпеки (ваша програма не може досягти певного стану), то загалом найкращим підходом є перевірка моделі . Однак якщо ви хочете повністю вказати поведінку програми Java, найкраще скористатися мовою специфікації для цієї мови, наприклад, JML . Є такі мови для визначення поведінки програм C, наприклад, ACSL , але я не знаю про C ++.

  2. Отримавши свої специфікації, вам доведеться довести, що програма відповідає цій специфікації.

    Для цього вам потрібен інструмент, який має формальне розуміння як вашої специфікації, так і оперативної семантики вашої мови (Java або C ++), щоб висловити теорему адекватності , а саме, що виконання програми дотримується специфікації.

    Цей інструмент також повинен дозволяти формулювати або генерувати докази цієї теореми. Зараз обидва ці завдання (конкретизація та доведення) є досить складними, тому їх часто розділяють на два:

    • Один інструмент, який аналізує код, специфікацію та генерує теорему адекватності. Як згадував Франк, Кракатаа є прикладом такого інструменту.

    • Один інструмент, який доводить теорему (и), автоматично або інтерактивно. Coq взаємодіє з Кракатау таким чином, і є кілька потужних автоматизованих інструментів, таких як Z3, які також можна використовувати.

    Один (другорядний) момент: є деякі теореми, які набагато важко довести автоматизованими методами, і, як відомо, автоматичні докази теореми іноді мають помилки щодо надійності, які роблять їх менш надійними. Це область, де Coq світить у порівнянні (але це не автоматично!).

  3. Якщо ви хочете генерувати код Ocaml, то обов'язково спочатку напишіть у Coq (Gallina), а потім витягніть його. Однак Coq жахливо створює C ++ або Java, якщо це навіть можливо.

  4. Чи можуть вищезгадані інструменти вирішувати проблеми з ниткою та продуктивністю? Мабуть, ні, питання щодо продуктивності та нарізання різьби найкраще вирішувати спеціально розроблені інструменти, оскільки вони особливо важкі проблеми. Я не впевнений, що я маю тут будь-які інструменти, які можна рекомендувати, хоча проект PolyNI Мартіна Хофмана здається цікавим.

На закінчення: формальна перевірка програм Java та C ++ "реального світу" - це велике і добре розвинене поле, і Coq підходить для частин цього завдання. Ви можете знайти огляд на високому рівні здесь , наприклад.


Дякуємо за цю публікацію та додані посилання. ІМХО, мета інженерів-програмників - мати можливість швидко випустити системи, які 1) завжди дають правильні результати, 2) ніколи не виходять з ладу. Тут я можу побачити проблему регресії, де ви, можливо, захочете довести, що сама специфікація є "помилкою" :-) начебто намагається визначити "справжню пропозицію мови" мета-мовою, тоді потрібна інша мета- мова для того, то ще одна ...
Френк

6
Проблема полягає в тому, що те, що користувач "хоче", зазвичай не виражається формальною мовою! Як правило, немає офіційної відповіді на питання: "Чи відповідає ця формальна специфікація моїй неофіційній ідеї?". Можна перевірити формальну специфікацію і довести, що вона має певні математичні властивості, але в кінцевому підсумку вам потрібно співвіднести математику з реальним світом, що є неформальним процесом.
коді

Так, звичайно - я завжди розумів, що формальні методи можуть починатися лише з чітко визначеної точки. Якщо ця специфікація відповідає або не відповідає усвідомленим / несвідомим / нерозкритим потребам користувачів реального життя - це ще одна проблема, яку не можна вирішити формальними методами (але, звичайно, проблема для інженерів).
Франк

Теорема за визначенням є доведеною пропозицією. Отже, ви, мабуть, не маєте на увазі "довести теорему".
nbro

@nbro Вікіпедія, здається, не погоджується з вами. Mathworld, однак, визначає теорему як судження, яке " може бути продемонстровано істинним шляхом прийнятих математичних операцій". У цьому випадку давати докази теорем не тільки можливо, але й потрібно обґрунтувати, називаючи їх такими! :) (це, звичайно, підсумкове підключення)
cody

15

Я хотів би зазначити три чудові застосування формальних методів / формальних інструментів перевірки у промисловості чи нетривіальних реальних системах. Зауважте, що у мене мало досвіду в цій темі, і я їх лише вчу, читаючи документи.

  1. Інструмент з відкритим кодом Java Pathfinder (короткий JPF), випущений NASA у 2005 році, є системою перевірки виконуваних програм байт-коду Java (див. Java Pathfinder @ wiki ). Він був використаний для виявлення невідповідностей у виконавчому програмному забезпеченні для K9 Rover в NASA Ames.

  2. Цей документ: Використання перевірки моделі для пошуку серйозних помилок файлової системи @ OSDI'04 показує, як використовувати перевірку моделі для пошуку серйозних помилок у файлових системах. Система під назвою FiSC застосовується до трьох широко використовуваних, високо перевірених файлових систем: ext3, JFS та ReiserFS, а також виявлено 32 серйозні помилки. Він виграв премію за найкращу папір.

  3. Цей документ: Як веб-сервіс Amazon використовує формальні методи @ CACM'15 описує, як AWS застосовує формальні методи до своїх продуктів, таких як S3, DynamoDB, EBS та внутрішній розповсюджений менеджер блокування. Основна увага приділяється інструменту TLA + Lamport . До речі, Лампорт інтенсивно використовував власну панель інструментів TLA. Він часто дає (цілком повну) формальну перевірку в TLA алгоритмів / теорем, запропонованих ним самим (а також співавторами) у додатках до статей.


4

Офіційна специфікація програми - це (більш-менш) програма, написана іншою мовою програмування. Як результат, специфікація, безумовно, включатиме власні помилки.

Перевага формальної перевірки полягає в тому, що оскільки програма та специфікація є двома окремими реалізаціями, їх помилки будуть різними. Але не завжди: одне поширене джерело помилок, пропущені випадки, часто збігається. Таким чином, формальна перевірка не є панацеєю: вона все одно може пропустити нетривіальну кількість помилок.

Недоліком формальної перевірки є те, що вона може накласти щось на кшталт подвійної вартості впровадження, ймовірно, більше (вам потрібен фахівець з офіційної специфікації, і вам потрібно використовувати більш-менш експериментальні інструменти, які поставляються разом з цим; це не буде дешевим ).

Я б припустив, що кращим використанням вашого часу стане встановлення тестових кейсів та риштування для автоматичного їх запуску.


Перевага формальної перевірки є те , що .... Другим недоліком формальної перевірки є те , що ... Це збиває з толком.
hengxin

Я думаю, що невідповідність між специфікацією та неофіційною задачею - це проблема аналізу програмних вимог, а не проблема програмування.
Каве

3

Офіційна перевірка тепер можлива для програм, написаних підмножиною C ++, розробленою для критично важливих для безпеки систем. Див. Http://eschertech.com/papers/CanCPlusPlusBeMadeAsSafeAsSpark.ppt для короткої презентації та http://eschertech.com/papers/CanCPlusPlusBeMadeAsSafeAsSpark.pdf для повного документу.


5
Дякуємо за посилання. Принаймні, короткий огляд їх вмісту буде корисним для захисту від гниття посилань, тим більше, що ваші посилання на корпоративний веб-сайт: вони, як правило, періодично реорганізовуються, вбиваючи всі посилання на сайт.
Девід Річербі

2

Ви задаєте кілька різних питань. Я погоджуюсь, все ж здається, що формальні методи верифікації промислових / комерційних застосувань не такі поширені. Однак слід розуміти, що в компіляторах вбудовано багато принципів "формальної перевірки", щоб визначити правильність програми! таким чином, якщо ви використовуєте сучасний компілятор, ви використовуєте більшу частину найсучасніших для офіційної перевірки.

Ви кажете "Я втомився від тестування", але формальна перевірка насправді не замінює тестування. певним чином, це є варіацією тестування.

Ви згадуєте Java. Є багато вдосконалених формальних методів перевірки, вбудованих у програму перевірки Java під назвою FindBugs, які дійсно можуть працювати над великими кодовими базами . Зверніть увагу, що це з'явиться як "помилкових позитивних результатів, так і помилкових негативів", а результати потрібно переглянути / проаналізувати розробником людини. Але зауважте, навіть якщо це не з'являється справжніх функціональних дефектів, вони, як правило, з'являються "анти-візерунки", яких у коді все-таки слід уникати.

Ви більше не згадуєте про вашу конкретну заявку, окрім як «промислової». Офіційна перевірка на практиці зазвичай залежить від конкретної програми.

Формальні методи верифікації, здається, широко застосовуються в ЕЕ для підтвердження правильності схеми, наприклад, в мікропроцесорній конструкції.

Ось приклад опитування формальних інструментів перевірки у сфері ЕЕ від Ларса Філіпсона .


2
Неправильно сказати, що "багато" принципів формальної перевірки "вбудовані в компілятори для визначення правильності програми". Те, про що ви посилаєтеся, - це статична перевірка типу, яку роблять деякі компілятори, але перевірені властивості таким чином досить прості, наприклад, уникаючи додавання числа та рядка. Це корисно, але далеко не те, що, як правило, піддається "формальній повірці".
Мартін Бергер

2
не посилався на перевірку статичного типу конкретно, хоча це один простий / поширений приклад. Методи оптимізації компілятора imho, які є широко поширеними та вдосконаленими, приблизно подібні до формальних принципів перевірки, оскільки вони включають в себе передові методи визначення / показника еквівалентності оптимізованих варіантів програм. тому здається, що важливо уникати проблеми "рухомих цілей" і не вважати це лише тому, що компілятор робить це чи вбудований у компілятор, а не його офіційну перевірку.
vzn

2
погодилися, це не є загальним розумінням. методи оптимізації орієнтовно створюють модель поведінки програми, наприклад, циклу або підпрограми, і оптимізують цю модель, а потім генерують новий код, що є еквівалентним. тому деякі з цих оптимізацій є досить складними в перестановці коду, і для мене вони використовують формальні принципи перевірки. мабуть, є багато інших прикладів формальних методів перевірки у компіляторі ... в оригінальному запитанні було задано багато різних запитань, як багато хто зазначив, я не намагаюся відповісти на всі питання, що містяться в ньому.
vzn

2
до речі, мабуть, існують деякі формальні принципи перевірки, які також використовуються в JRE, механізмі виконання Java, наприклад, динамічна оптимізація тощо ...
vzn

3
xy

1

Можливо, корисна модель може перевірити.

http://alloytools.org/documentation.html Сплав - це перевірка моделі.

Приємна презентація, що пояснює концепцію перевірки моделі за допомогою Alloy: https://www.youtube.com/watch?v=FvNRlE4E9QQ

У цьому ж сімействі інструментів відбувається "тестування на основі властивостей", вони намагаються знайти зустрічний приклад для даної моделі специфікацій вашого програмного забезпечення.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.