Правильність програми, специфікація


17

З Вікіпедії: У теоретичній інформатиці правильність алгоритму стверджується, коли кажуть, що алгоритм правильний щодо специфікації.

Але проблема полягає в тому, що отримати "відповідну" специфікацію не є тривіальним завданням, і немає 100% правильного методу (наскільки я знаю), щоб отримати правильний, це просто оцінка, тому якщо ми збираємось приймати присудок як специфікацію лише тому, що він "виглядає" як "один", чому б не прийняти програму як правильну лише тому, що вона "виглядає" правильною?


2
Оскільки, сподіваємось, специфікація менш складна, ніж програма, тому вона матиме менше помилок, ніж програма.
користувач253751

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

@immibis, але якщо є лише одна помилка, вся справа не так
Майкель Джексон

@MaykelJakson Щоправда ... Я одного разу помилково вклав протиріччя в аксіомі у Родена (те, що я намагався зробити, було правильно, але синтаксис був неправильним). Перш ніж я помітив, мені знадобилося певний час, "начебто, авто-довідник працює незвично добре".
користувач253751

Відповіді:


30

По-перше, ви абсолютно праві: ви переживаєте справжню проблему. Офіційна перевірка передає проблему впевненості у правильності програми до проблеми впевненості у правильності специфікації, тому це не є срібною кулею.

Однак є кілька причин, чому цей процес все ще може бути корисним.

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

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

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

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

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

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

Можливо, вам також сподобається формальна перевірка програми на практиці, і чому ми не досліджуємо більше, щоб скласти гарантії часу? для отримання більшої перспективи, яка має певне відношення до цього.


По мірі того, як специфіка стає більш детальною, ймовірність того, що вона може бути записана у міру збільшення псевдокоду. Використовуючи ваш приклад сортування, більш детальною версією "вихід має бути в порядку зростання" було б "кожне ціле число на виході, після першого, повинно бути більше попереднього числа". Це, у свою чергу, легко можна записати як щось на зразок for each integer I<sub> N</sub> in set S (where N > 1) { assert I<sub> N</sub> > I<sub> N - 1</sub> }. Не на 100% впевнений у позначенні.
Час Джастіна - Відновіть Моніку

Отже, хороша специфікація може також допомогти створити код, а не просто перевірити його.
Час Джастіна - Поновіть Моніку

1
Очевидний спосіб виконання специфікації сортування - перерахувати всі перестановки вхідних даних і вибрати впорядковану. Проблема з цим , однак, повинна бути зрозумілою ...
Дерек Елкінс вийшов SE

19

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

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

Не могли б ви довести цю властивість з коду? Зрештою, ось що відбувається, якщо ви дотримуєтесь повністю формального підходу¹. Але код має багато різних частин; гальма, камери, двигун тощо керуються автономно. Властивість коректності гальм буде чимось на кшталт "якщо сигнал" застосувати гальмо "увімкнено, тоді гальма застосовуються". Властивістю правильності двигуна було б "якщо сигнал зчеплення вимкнено, то двигун не веде колеса". Потрібно дуже високого рівня, щоб зібрати їх разом. Специфікація створює проміжні шари, де різні компоненти системи можуть бути зчленовані разом.

Насправді така складна система, як автопілот автомобіля, мала б декілька рівнів технічних характеристик з різною кількістю доопрацювань. У дизайні часто використовується підхід до вдосконалення: почніть з властивостей високого рівня, таких як "автомобіль не вріжеться в стіну", а потім з’ясуйте, що для цього потрібні датчики і гальмо, і розробіть деякі основні вимоги до датчиків, гальм. і пілотне програмне забезпечення, а потім ще раз уточнити ці основні вимоги до дизайну компонента (для датчика мені знадобиться радар, DSP, бібліотека обробки зображень ...) тощо. У формальному процесі розробки, доведено, що кожен рівень специфікацій відповідає вимогам, встановленим рівнем над ним, від властивостей найвищого рівня до коду.

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

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


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

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