Як створити критичне програмне забезпечення для місії?


15

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

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

Але тоді як переконатися, що програмне забезпечення (не тільки специфікація) справді правильне?

Відмова: Я 90% ідіот, коли йдеться про теоретичні інформатики. Тож будьте милосердні, відповідаючи.


2
Що ви точно маєте на увазі під "... що програмне забезпечення дійсно правильне ..." ? Який із наведених нижче 2 ви маєте на увазі: 1) Програмне забезпечення відповідає специфікації 2) Конкретні блоки коду стосуються деякої заданої властивості або деякого співвідношення введення-виведення.
Джорджіо Камерані

@GiorgioCamerani: Перший
фаджріан

2
Правильність програми зазвичай означає, що (1) вона відповідає специфікації та (2) вона ніколи не виходить з ладу. Точка (1) - це дійсно твердження про пару (програму, специфікацію), а не про саму програму. Наступним ускладненням є те, що "програма" зазвичай є скороченням для "моделі програми", оскільки самі програми є надто складними або не мають точної семантики. З огляду на це, я думаю, ви запитуєте про розрив між програмою та її моделлю, але я не зовсім впевнений.
Раду ГРИГо

@RaduGRIGore: Насправді я не розумію, що таке "модель". Але я думаю, ви досить уважно звертаєтесь до мого питання. В основному, мені цікаво, що це розрив між специфікацією та вихідним кодом програми. Багато дурних речей може статися, коли програмісти (як я) реалізують специфікацію.
Фаджріан

1
@fajrian: Я підозрюю, що ви говорите "специфікація" для того, що я б назвав "модель". Є інструменти, які працюють над програмами, написаними на таких мовах, як C або Java, або навіть машинний код. (Це все-таки модель, оскільки вони повинні припускати певну семантику, яка повинна , але може не відповідати тому, що робить компілятор / процесор.)
Radu GRIG

Відповіді:


11

Питання досить широке. Щоб відповісти на це в розумному просторі, я зроблю багато спрощень.

Давайте погодимось з термінологією. Програма є правильною, коли вона передбачає її специфікацію. Це розпливчасте твердження багато в чому робиться точним, уточнюючи, що саме є програмою, а що саме є специфікацією. Наприклад, при перевірці моделей програма є структурою Kripke, а специфікація часто є формулою LTL . Або програма може бути переліком інструкцій PowerPC, а специфікація може бути набором тверджень Хоара-Флойда, написаних, скажімо, логікою першого порядку. Можливих варіацій дуже багато. Заманливо зробити висновок, що в одному випадку (структура Kripke) ми не перевіряємо фактичну програму, тоді як у другому випадку (перелік інструкцій PowerPC) ми робимо. Однак важливо усвідомити, що ми дійсно дивимось на математичні моделі в обох випадках, і це цілком чудово. (Ситуація досить схожа на фізику, де, наприклад, класична механіка є математичною моделлю реальності.)

Більшість формалізацій розрізняють синтаксис і семантику програми; тобто як вона представлена ​​і що це означає. Семантика програми - це те, що враховується з точки зору перевірки програми. Але, звичайно, важливо мати чіткий спосіб присвоєння значень (синтаксичним уявленням) програм. Два популярні способи:

  • (невеликий крок) оперативна семантика : Це дуже схоже на визначення мови програмування, написавши для неї перекладача. Для цього вам потрібно сказати, що таке стан , і на це впливає кожне твердження мовою. (Ви можете задуматися, якою мовою ви пишете перекладача, але я буду робити вигляд, що ви цього не зробите.)
  • аксіоматична семантика : Тут кожен тип висловлювань має схему аксіоми. Отже, приблизно, щоразу, коли використовується певна заява цього типу, це означає, що можна використовувати певні аксіоми. Наприклад, призначення поставляється зі схемою { P [ x / e ] }х: =е ; конкретне завдання x : = x + 1 поставляється з аксіомою { x + 1 = 1 }{П[х/е]}х: =е{П}х: =х+1 якщо ми інстанціюємо схему з P = ( x = 1 ) .{х+1=1}х: =х+1{х=1}П=(х=1)

(Є й інші. Я відчуваю себе особливо погано, якщо опускати денотаційну семантику, але ця відповідь вже тривала.) Машинний код плюс оперативна семантика є досить близьким до того, що більшість людей називають «реальною програмою». Ось настільний документ, в якому використовується оперативна семантика для підмножини машинного коду DEC Alpha:

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

Підсумовуючи, я міг би придумати три причини, які спричинили ваше запитання:

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

Ця відповідь просто намагається визначити три різні способи, якими я зрозумів питання. Заглиблюючись у будь-яку з цих точок, потрібно багато місця.


8

Один із підходів до зменшення розриву між програмою та її специфікацією - це використання мови з формальною семантикою. Цікавим прикладом тут був би Естерел . Перегляньте веб-сторінку Жерара Беррі, щоб ознайомитись із цікавими розмовами про його роботу, що впроваджує формальні методи у реальний світ. http://www-sop.inria.fr/members/Gerard.Berry/

ps Був у Airbus? Ви прилетіли формальними методами!


1
будь-яка інформація про те, як airbus використовує формальні методи, була б корисною. (зрозумійте, що його можливість є власною інформацією.)
vzn

@RossDuncan Я знайшов цю веб-сторінку після переходу на веб-сторінку Беррі та декількох пошуків. Це формальні методи, якими користувався Airbus, про які ви посилалися?
scaaahu

Я не маю ніякої внутрішньої інформації щодо використання Естерелом Airbus; мій коментар просто повторює зауваження, яке Беррі зробив під час лекції. Однак ця сторінка промовляє на успішне використання продукту SCADE з Airbus. Якщо подивитися на історію Естерела, то її було прийнято Дассо досить рано. Google - ваш друг.
Росс Дункан

2
Airbus також використовує astree.ens.fr
Radu GRIGо

7

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

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

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

  • тестування . усі типи - тестування блоку, тестування інтеграції, тестування приймання користувача, тестування регресії тощо.

  • нині автоматизоване тестування за допомогою тестових наборів, які можна запускати без нагляду, є більш розвиненим / важливим. тестові пакети, що працюють, часто поєднуються з інструментом збирання.

  • Важливою концепцією тестування є покриття коду . тобто який код здійснюється з допомогою тесту. тест не може знайти помилку в коді, який не торкається тесту.

  • Ще одна ключова концепція тестування - це тестовий джгут , який не може легко отримати доступ до коду вправ.

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

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

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

  • можна захопитися тестуванням! Існує і проблема з занадто малою або занадто великою кількістю тестування. є "солодка пляма". програмне забезпечення не може бути успішно вбудовано в будь-якій крайності.

  • використовувати всі основні інструменти найефективніше. налагоджувачі, профілі коду, засоби тестового покриття коду, система відстеження дефектів тощо! не обов’язково зобов’язуватися виправляти, але відслідковуйте навіть найменші дефекти програмного забезпечення для відстеження.

  • ретельне використання SCM, управління вихідним кодом та методи розгалуження важливо для уникнення регресії, ізоляції та прогресування виправлень тощо

  • Програмування N-версій : практика, яка часто використовується для розробки програмного забезпечення, що належить до критичних місій. Передумова цієї практики полягає в тому, що N незалежно розроблених програм навряд чи матимуть однакову помилку / помилку. Це було піддано критиці в кількох статтях . Однак, НВП є практикою не теоретичною концепцією.

Я вважаю, що фізик Фейнман має певний виклад методу, який NASA використовував для гарантування надійності систем космічних човників у своїй книзі "Що вам байдуже, що думають інші?" - Він сказав, що у них є дві команди, скажімо, команда A та команда B. команда A створила програмне забезпечення. команда B застосувала змагальний підхід до команди A і спробувала зламати програмне забезпечення.

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


8
Хтось повинен перевірити вашу ОС на правильність щодо специфікацій, що натискання клавіші Shift та літери видає велику літеру.
Андрій Бауер

1
додаток: обмеження у графіку можуть вплинути на якість. див. також проектний трикутник проекту, що складається з обсягу, вартості, графіку якості, "область", на яку впливають усі 3. див. також "Чому ІТ-індустрія не може швидко виконувати великі бездоганні проекти, як в інших галузях промисловості?" . сам не додав пункт N-версії (його інша відповідь), але зауважив, Фейнман зазначив, що NASA використовував його також у дизайні космічного човника.
vzn


1
Ще одне цікаве тематичне дослідження - марсохід Rover, який має великі амти коду, багато з яких автогенерується. у такому випадку поле попередніх роверів протестувало більшість програмного забезпечення & воно було повторно використане.
vzn

6

Старий підхід (але він все ще використовується в деяких додатках) - це програмування N-версій

З Вікіпедії:

Програмування N-версій ( NVP ), також відоме як мультиверсійне програмування , є методом або процесом в інженерії програмного забезпечення, де кілька функціонально еквівалентних програм незалежно генеруються з одних і тих же початкових специфікацій. Концепція програмування N-версій була введена в 1977 році Лімінг Чен і Альгердом Авізієнісом з центральною думкою про те, що "незалежність зусиль програмування значно знизить ймовірність виникнення однакових помилок програмного забезпечення в двох і більше версіях програми". NVP полягає у підвищенні надійності роботи програмного забезпечення шляхом побудови відмовок або надмірності.
….

Див. Наприклад: " Проблеми у вини будівництва - толерантна система управління польотом для цивільного літального апарату "


Варто зазначити, що n-версія програмування не працює . Фундаментальне припущення - а саме те, що помилки в повторних випробуваннях процесу розробки програмного забезпечення є незалежними - є абсолютно помилковим . Ця ідея теоретично не має сенсу (важко реалізований алгоритм не стане магічно простішим для другої незалежної команди), і він був також дебютований експериментально: експеримент Джона Найта та Ненсі Левесон показав, що припущення про незалежність не є статистично достовірним є однією з найвідоміших робіт у галузі програмної інженерії.
Ніл Крішнасвамі

@NeelKrishnaswami: Я згоден! Однак я думаю (але я не фахівець), що не працює, його слід замінювати, це не покращує надійність настільки, наскільки має порівняно з іншими підходами . Посилаючись на K&L: " ... Ми ніколи не пропонували використовувати наш результат як основу для прийняття рішення про ефективність програмування N-версій. Ми просто припустили, що обережність буде доречною ... ". Я думаю, що дискусія щодо того, наскільки підхід NVP може бути корисним для критичного дизайну системи, все ще залишається відкритим (див. Нещодавню роботу Khoury та ін.)
Marzio De Biasi,

4

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

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

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

Тільки тестування не є формальним підходом до методу, його підвищення підвищує надійність, але не перевіряє правильність.


3

Два-три роки тому я почав вивчати формальні методи, застосовані до програмного забезпечення. Це був квест, керований цікавістю та відчуттям, що мені доведеться вивчити інструменти та методи програмування з більш тривалими проміжками часу. Хоча я бажав мріяти про Срібну кулю , я справді думав, що немає відповіді на питання: "Як я можу написати правильну програму?".

У цей момент квесту після спробу деяких інструментів (Z, B, VHDL та Estelle) я використовую TLA + . Це варіант часової логіки з програмними засобами для перевірки моделі та механічних доказів. Я думаю, що я обираю такий підхід, тому що Л. Лампорт стояв за ним, синтаксис був простим, було багато прикладів, громада піклувалася про нього, а мова та інструменти були досить добре зафіксовані.

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

Коротше кажучи, я вважаю, що така метафора (від Lamport) справді потужна: "Ви очікуєте, що будинок буде автоматично побудований з креслення? Ви придбаєте будинок, який ще не побудований, і він не має креслення?" .

Під час цього квесту я знайшов корисні такі ресурси:

Удачі!


1

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

Як створити критичне програмне забезпечення?

Існують інструменти, які автоматично аналізують ваш код на предмет помилок (порушення специфікації або "типові помилки"). Наскільки мені відомо, ці методи здебільшого ґрунтуються на статичному аналізі і не мають безпосереднього відношення до згаданих вами теорій (LTL / CTL / ...), але вони знаходять помилки в реальному коді, і це вже можливо з практичної точки зору Думаю, використовувати такі інструменти у промислових проектах. Я особисто не використовував багатьох з них, але, схоже, ці інструменти починають сприймати практикуючі. Для подальшого читання я можу порекомендувати наступну статтю в блозі:

http://www.altdevblogaday.com/2011/12/24/static-code-analysis/


Приклад реалізації з Java, open source apache— findbugs
vzn

0

Сертифікаційні алгоритми можуть бути корисні при складанні критичного програмного забезпечення.

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

Детальніше читайте в цьому оглядовому документі Сертифікуючі алгоритми McConnell, RM and Mehlhorn, K. and Naher, S. and Schweitzer, P.


У 1998 році Пнуелі, Зігель та Сінгерман описали цю ідею, застосовану до компіляторів, під валідацією перекладу імен . Компілятори за своєю суттю вищого порядку (вхід - це програма, вихід - програма), тому їх, як правило, важко перевірити. Але є такі божевільні люди, як X. Leroy, які так чи інакше розробляють перевірені компілятори. (Божевільний у найкращому сенсі!)
Раду ГРИГо

-2

Але тоді як переконатися, що програмне забезпечення (не тільки специфікація) справді правильне?

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

Теоретично кажучи, якщо ваші одиничні тести мають покриття коду на 100% (тобто кожен метод у вашому коді перевіряється), ваше програмне забезпечення повинно бути правильним, за умови, що самі тести є точними та реалістичними.


5
Для будь-якої досить складної програми охоплення кодом (шляхом тестування) не може забезпечити правильність. Вам доведеться покрити всі можливі страти; всі рядки коду НЕ достатньо.
Radu GRIGо

1
Покриття коду поняття занадто розпливчасте. Ми розрізняємо, наприклад, покриття методу, охоплення оператора, покриття гілки, покриття контуру тощо. Як зазначає Раду, для нетривіальних програм тестування часто стикається з комбінаторними вибухами. Зважаючи на це, програмне забезпечення з повітроплавання має неабиякий досвід, і його правильність часто базується на широких тестуваннях.
Мартін Бергер

Якщо ви маєте на увазі тестування такими інструментами, як JUnit, цей тип стандартного автоматичного тестування не може охопити всі випадки (якщо програма надзвичайно мала). Для типового застосування такого випробування, як правило, достатньо. Але для критичного застосування місії я не знаю, чи цього достатньо (чи ні).
Фаджріан

2
@vzn: З мого досвіду, існує надзвичайна згода між тим, що вважається помилкою вчених та, відповідно, практиків. Також я думаю, що більшість моїх (колишніх) колег з галузі погоджуються з тим, що "кожен метод у вашому коді перевірений" не здається дуже заспокійливим. (І, ні, я не спровокував. Я майже ніколи цього не роблю.)
Radu GRIGДо

1
@vzn: Я сказав, ти сказала інакше? Я просто намагався пояснити, чому я вважаю, що інші не підтримують цю відповідь. На даний момент я не можу відповісти на це запитання, тому що не розумію.
Radu GRIGо
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.