Формальне доведення правильності алгоритмів обробки дерев
Обмін місцями значень двох змінних. Звичайний цикл "поки" і команда повторення. Теорема про цикл, його інваріант і обмежуючу функцію. Програмування як цілеспрямована діяльність. Стратегія побудови команди вибору. Проектування та захисне програмування.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | дипломная работа |
Язык | украинский |
Дата добавления | 15.06.2013 |
Размер файла | 679,8 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
Дніпропетровський національний університет
імені Олеся Гончара
ФАКУЛЬТЕТ ПРИКЛАДНОЇ МАТЕМАТИКИ
КАФЕДРА КОМП'ЮТЕРНИХ ТЕХНОЛОГІЙ
Дипломна робота бакалавра
на тему «Формальне доведення правильності алгоритмів обробки дерев»
Виконав: студент _IV__курсу, групи___ПК-09
напряму підготовки 6.040302 Інформатика
Злочевський М. І.
Рецензент
доц. каф. ПММ Тонкошкур І.С
м.Дніпропетровськ - 2013 року
Міністерство освіти і науки, молоді та спорту України
Дніпропетровський національний університет імені Олеся Гончара
Факультет прикладної математики
Кафедра комп'ютерних технологій
ДИПЛОМНА РОБОТА
за ОКР бакалавра
Тема: «Формальне доведення правильності алгоритмів обробки дерев»
Виконавець: ст. гр. ПК-09-1
Злочевський Михайло Іванович
Допускається до захисту
Завідувач кафедри КТ к.фіз.-мат. наук,
доц. Зайцев В.Г.
Керівник: доц .каф. КТ к.фіз.-мат. наук,
доц. Хижа О.Л
Рецензент: доц. каф. ПММ
Тонкошкур I.С.
Керівник з розділу «Охорона праці»: ст. викл. каф. БЖД
Тарасенко Ю.В.
Дніпропетровськ
2013р.
Зміст
ВСТУП
ПОСТАНОВКА ЗАДАЧІ
ОГЛЯД ПРОБЛЕМИ
ЧАСТИНА І.ТЕОРЕТИЧНІ ЗАСАДИ ДОВЕДЕННЯ ПРАВИЛЬНОСТІ ПРОГРАМ
1.1 Специфікації програм
1.2 Перетворювач предикатів wp
1.3 Команди skip, abort і композиція команд
1.4 Команда присвоювання
1.4.1 Присвоювання простим змінним
1.4.2 Обмін місцями значень двох змінних
1.4.3 Кратне присвоювання простим змінним
1.4.4 Присвоювання елементу масиву
1.5 Команда вибору
1.6 Команда повторення
1.6.1 Звичайний цикл «поки» і команда повторення
1.6.2 Формальне визначення DO
1.6.3 Теорема про цикл, його інваріант і обмежуючу функцію
1.6.4 Анотування циклу і розуміння анотацій
1.7 Побудова програм
1.8 Програмування як цілеспрямована діяльність
1.8.1 Стратегія побудови команди вибору
1.8.2 Стратегія побудови команди циклу
1.9 Теоретичні аспекти «Програмування за контрактом»
1.9.1 Коректність ПЗ
1.9.2 Формула коректності. Сильні та слабкі умови
1.9.3 Твердження
1.9.4 Передумови та післяумови
1.9.5 Інваріанти класу
1.9.6 Твердження та перевірка вхідних даних
1.9.7 Проектування за контрактом та захисне програмування
ЧАСТИНА IІ.ФОРМАЛЬНЕ ДОВЕДЕННЯ АЛГОРИТМІВ
2.1 Пошук елементу в масиві (саме праве входження)
2.1.1 Специфікація
2.1.2 Доведення
ВИСНОВКИ
СПИСОК ВИКОРИСТАНОЇ ЛІТЕРАТУРИ
РЕФЕРАТ
Дипломна робота: 67 с., рис. 6, табл. 6, джерел 9.
Об'єкт дослідження: теорія доведення правильності деяких алгоритмів обробки дерев.
Мета роботи: вивчити методику доведення правильності роботи програм. Зокрема ознайомитись та довести деякі з алгоритмів обробки дерев.
Метод дослідження: верифікація програм на основі найслабших передумов.
Одержані висновки та їх новизна: розроблено низку прикладів для перевірки правильності програм; створені алгоритми реалізовано на мові С;
Перелік ключових слів: ДОВЕДЕННЯ ПРАВИЛЬНОСТІ ПРОГРАМ, НАЙСЛАБША ПЕРЕДУМОВА, ПІСЛЯУМОВА, ДЕДУКТИВНА ВЕРИФІКАЦІЯ, ПРОГРАМУВАННЯ ЗА КОНТРАКТОМ, БІНАРНІ ДЕРЕВА ПОШУКУ.
ANNOTATION
The graduation research of the fourth year student Zlochevskiy M. (DNU named Oles Gonchar, Faculty of Applied Mathematics, Department of Computer Technologies) deals with the proving programs (that based on some kinds of trees) correct. The aim was to study the methods of proving the correctness of programs. Automation proves the correctness of programs written in C and demonstrate the use of formal methods in computer science to develop effective programs.
The work is interesting both for students specializing in programming and for the programmers who are developing sophisticated algorithms.
Bibliography 9, pictures 6, tables 1.
ВСТУП
Спробуємо відповісти на питання, що означає твердження - програмний елемент коректний? Спостереження і міркування, що відповідають на це питання, можуть здатися тривіальними. Але, як зауважив один відомий вчений, такі всі наукові результати, - вони починаються зі звичайних спостережень і продовжуються шляхом простих міркувань, але все це потрібно робити завзято і наполегливо.
Припустимо, хтось прийшов до вас з програмою на 300 000 рядків на С і питає, чи коректна вона? Ви можете відповісти «ні» і, ймовірно, опинитеся праві. Для того щоб можна було дати розумну відповідь на подібне питання, однієї програми недостатньо, необхідна ще і її специфікація, точно описує, що повинна робити програма. Оператор
сам по собі не є ні коректним, ні не коректним. Ці поняття набувають сенсу лише по відношенню до очікуваного ефекту присвоювання. Наприклад, присвоєння коректно по відношенню до твердження: «Змінні x і y мають різні значення». Але не гарантується його коректність по відношенню до висловлення: «змінна x від'ємна», оскільки результат присвоювання залежить від значення y, яке може бути додатнім.
Програмна система або її елемент самі по собі ні коректні, ні не коректні. Коректність розуміється лише по відношенню до деякої специфікації.
Термін «коректність» не застосовується до програмного елементу, він має сенс лише для пари - «програмний елемент і його специфікація»[2].
Жодне тестування не може гарантувати правильність роботи програми при всіх вхідних даних, а лише при тих, які перевірялись.
Бертраном Мейером було запропоновано новий підхід до по побудови програмних компонентів. Цей підхід отримав назву «Програмування за контрактом».
Проектування за контрактом (Design by Contract) - це встановлення відносин між класом і його клієнтом у вигляді формальної домовленості, які однозначно визначають права та обов'язки обох сторін. Тільки через точне визначення вимог та відповідальності для кожного модуля можна сподіватись на досягнення значного ступеня довіри до великих програмних систем[2].
Під відносинами між викликаючим модулем та виконуваною програмою розуміється наступне: виклакаюча функція зобов'язується передати в функцію ті дані, які ця функція очікує. В цьому випадку, функція, яку викликали в модулі, зобов'язується повернути коректні і правильні дані.
В такому випадку критерієм правильності програми є істинність предиката, основними елементами якого є передумова виконання програми, сама програма та післяумова виконання. Тобто правильність програми визначається не тільки відсутністю синтаксичних помилок, але і відповідністю синтаксично правильного коду тій задачі, для вирішення якого він призначений.
Доведення істинності предиката розглядається в теорії формальної перевірки правильності програм.
Але, як можна побачити, доведення простої програми, такої як сума елементів масиву, за всіма правилами - це досить важка робота. Тому постає питання про автоматизацію доведення програм.
Для автоматизованого доведення існує багато засобів. Одним з найбільш популярних на сьогодні є Frama-C.
Frama-C являє собою набір інструментів, призначених для аналізу вихідного коду програм, написаних на мові C.
Вона об'єднує кілька статичних методів аналізу в одній області співробітництва. Спільний підхід цих статичних аналізаторів дозволяє спиратися на результати вже обчислені іншими аналізаторами в межах програми. Завдяки такому підходу, Frama-C забезпечує складні інструменти, такі як зріз і аналіз залежностей. Таким чином, дозволяючи доводити складні алгоритми.
Для доведення я використовувалась надбудова WP.
ПОСТАНОВКА ЗАДАЧІ
1. Вивчити теоретичні основи доведення правильності програм.
2. Опанувати систему Frama-C доведення програм на мові C.
3. Застосувати систему Frama-C до програмування за контрактом.
Метою роботи є автоматизація доведення правильності програм, написаних мовою С та демонстрація використання формальних методів у інформатиці для ефективної розробки програм.
Для здійснення мети роботи треба було вирішити наступні завдання:
1) ознайомитися з теорією доведення правильності програм;
2) вміти побудувати доведення програм у формальній системі;
3) ознайомитися з системою доведення правильності програм Frama-C та її можливостями;
4) розглянути роботу плагіну WP, який базується на теорії найслабшої передумови, на існуючих прикладах;
5) розробити на основі теорії доведення правильності програм нові програми-приклади для дедуктивної верифікації у системі Frama-C;
6) Довести правильність побудованих програм, використовуючи принци формальної верифікації.
7) перевірити створені програми використовуючи WP плагін та інструменти автоматичного доведення правильності теорем.
ОГЛЯД ПРОБЛЕМИ
Історичні відомості
Програмування включає в себе не тільки складання, а й дослідження програми, доказ її властивостей, головним з яких є правильність програми. Тут мова йде не про синтаксичну правильності (вона автоматично перевіряється транслятором), а про відповідність синтаксично правильної програми тієї задачі, для вирішення якої вона призначена. Тобто, ми розглядаємо семантичну правильність програми.
Традиційні методи аналізу ПЗ пов'язані з доказом правильності програм були закладені роботами П. Наура і Р. Флойда, в яких сформульована ідея приписування точці програми так званого індуктивного, або проміжного твердження і зазначена можливість доказу часткової правильності програми (тобто відповідності один одному її передумови і післяумови), побудованого на встановленні узгодженості індуктивних тверджень.
Фундаментальний внесок в теорію верифікації вніс Ч. Хоар, який висловив ідеї можливості доведення часткової правильності програми у вигляді доведень в деякій логічній системі, а Е. Дейкстра ввів поняття найслабшої передумови, що дозволяє одночасно перевіряти як відповідність один одному передумови і післяумови, так і збіжність алгоритму. Методи доведення правильності програм внесли певну користь в програмування. Було відзначено, що ці методи вказують спосіб міркування про хід виконання програм, дають зручну систему коментування програм і встановлюють зв'язок між конструкціями мов програмування та їх семантикою. Якщо взяти більш широке тлумачення терміна "аналіз програм", маючи на увазі доказ різноманітних властивостей програм або доказ теорем про програми, то цінність методів аналізу стане більш ясною. Зокрема можна досліджувати характер зміни вихідних значень програми, кількість операцій при виконанні програми, наявність зациклення, незадіяних ділянок програми. Таким чином, в деяких окремих випадках методи верифікації можуть застосовуватися і для обґрунтованого виявлення програмних дефектів.
Довести правильність програми досить не просто, і якщо навіть вдасться довести, що програма правильна, то не можна бути в цьому абсолютно впевненим. У самому доказі, як і в програмі, також можуть бути помилки. Всі з нас мають справу з теоремами і добре знають, що формулювання теореми, як правило, коротше її докази. Проте зусилля, витрачені на доказ правильності програми, сприяють глибшому розумінню завдання і алгоритму. Адже щоб довести, що програма правильна, треба дуже добре в ній розібратися. Досвід показує, що саме тому доказ правильності дуже корисно і дозволяє уникнути багатьох помилок, які могли б виникнути в програмі, якби доказ не проводилося.
В наш час існують галузі промисловості та машинобудування, де все залежить від правильності написаного програмного продукту. До них можна віднести, наприклад, літако- та ракетобудування. Непередбачуваний збій в програмі керування може призвести до фатальних наслідків. В таких випадках треба бути повністю впевненому, що програма працює коректно. І щоб бути в цьому впевненому, нам і допомагають математичні методи доведення правильності програм.
Логічне програмування
За довгі роки розвитку логіки було створено багато методів встановлення логічного висновку. Більшість з них засновані на доведенні того, чи є істинною або хибною деяка логічна формула, яка зв'язана теоремою. Але для своєї реалізації такі методи потребують довгої рутинної роботи (переписування, перебирання варіантів), тобто вони занадто трудомісткі і великі за розміром для «ручного» застосування. В той же час вони можуть бути легко запрограмовані на ЕОМ, що робить задачу встановлення логічного висновку набагато доступнішою. Методи та алгоритми, що використовуються для розв'язання таких задач, отримали назву автоматичних (машинних) методів доведення теорем.
Хоча ці алгоритми були запропоновані давно і постійно вдосконалюються, їх реалізація на традиційних мовах програмування викликає суттєві труднощі. Тому це призвело до появи спеціалізованих мов та інструментів для доведення правильності.
Практична необхідність формальної верифікації
В більшості об'єктно-орієнтовних мов програмування не приділяється багато уваги семантичним властивостям класу. Кожен клас має список своїх операцій. Але інформація про те, коли можна викликати той чи інший метод, які параметри не обов'язкові, що треба очікувати в результаті виконання, не є формальною. Більшість такої інформації або відсутня або міститься у вигляді коментарів. В цьому випадку ми отримаємо дублювання інформації, оскільки реалізація методу має відповідати коментарям або іншій документації, і відсутність можливості контролювати поведінку під час виконання коду.
Проектування за контрактом (Design by Contract) - це встановлення відносин між класом і його клієнтом у вигляді формальної домовленості, які однозначно визначають права та обов'язки обох сторін. Тільки через точне визначення вимог та відповідальності для кожного модуля можна сподіватись на досягнення значного ступеня довіри до великих програмних систем[2].
Суттю цього методу є побудова коректного програмного забезпечення.
Коректність ПЗ - це узгодження програмних елементів зі заданою специфікацією. Термін «коректність» не прийнятний до програмного елементу, він має зміст лише для пари - «програмний елемент та його специфікація». [2].
Специфікація і реалізація поєднані між собою. Специфікація визначає що має робити програма, а реалізація визначає як це буде досягнуто. Обидва ці аспекти мають розвиватись одночасно. Якщо специфікація та реалізація знаходяться в різних джерелах, о ми якраз і маємо проблема дублювання інформації, і в цьому випадку невідповідність цієї інформації є лише питанням часу. В проектуванні за контрактом вираз специфікації здійснюється за допомогою механізму тверджень.
Проектування за контрактом виходить з того, що «чим менше і конкретніше завдання, тим простіше розробка, підтримка і супровід коду». «З цієї глобальної точки зору простота стає критичним фактором. Складність - головний ворог якості ... Додаючи надлишкові перевірки, додаєте більше коду. Більше коду - більше складності, звідси і більше джерел умов, що призводять до того, що все піде не так. Це призведе до подальшого розростання коду, і так до нескінченності. Якщо піти по цій дорозі, то безперечно можна сказати одне - ми ніколи не досягнемо надійності. Чим більше пишемо, тим більше доведеться писати »[1].
Існуючі пакети для доведення правильності програм
Сучасні програми продукти розв'язують багато складних задач, але й сама програма стає дедалі більшою. І доводити правильність програми в декілька тисяч рядків - це занадто складна задача. Тому постало питання про автоматизацію доведення.
Зараз існує багато різних систем, в основі яких лежать ті чи інші методи верифікації програмного коду.
Програмні пакети, що виконують автоматичне доведення або деякі його елементи, традиційно поділяють на інтерактивні та автоматичні прувери (системи доведень, interactive/automated theorem provers) та верифікатори моделей (model checkers). Такий поділ є умовним і здебільшого залежить від деяких параметрів задач та участі користувача у процесі доведення.
Важливою особливостю більшості прикладень, які реалізують методи автоматичного доведення, є їх некомерційність, експериментальний характер. З одного боку, це забезпечує безкоштовний необмежений доступ до даного програмного забезпечення для всіх бажаючих, але, з іншого боку, подібні системи, як і багато інших некомерційних ІТ-проектів, можуть функціонувати нестабільно.
Coq - система автоматизованої побудови доведень, розроблена в дослідницькому інституті INRIA (Франція). Являє собою достатньо збалансоване прикладення, яке поєднує в собі підтримку широкого спектру логічних процедур, високу стабільність роботи і відносну простоту опанування для багатьох користувачів. Система супроводжується документацією і може бути вільно завантажена з сайту розробників. Розробники визначають Coq як Proof Assistant, тобто як інтерактивний прувер. Крім того Coq підтримує процедури повного машинного виводу, що є характерним для автоматичних інструментів доведення. Coq реалізована на декількох платформах (Linux, Mac OS, Windows, Solaris) і має набір інтерфейсів, які полегшують взаємодію з користувачем.
Isabelle - система, яка дозволяє виражати математичні формули формальною мовою і містить в собі інструменти для логічного доведення таких формул. Розроблена у Кембриджському університеті та Мюнхинському технічному університеті. Isabelle вільно розповсюджується за умовами ліцензії BSD.
WHY платформа для верифікації програмного забезпечення. Містить в собі декілька інструментів:
· генератор умов верифікації (VCG), який внутрішньо використовується іншими інструментами доведення без втручання користувача, але також може бути використаний для прямої верифікації програми;
· інструмент Krakatoa використовується для верифікації програм, написаних на Java та анотованих за допомогою мови JML. Вільно доступний за умовами ліцензії GNU GENERAL PUBLIC LICENSE;
· інструмент Caduceus використовується для верифікації програм, написаних на С. Але зараз він поступово замінюється системою Frama-C.
Однією з основних властивостей WHY є те, що у систему може бути інтегровано існуючі інструменти, наприклад, ті, що були перераховані вище, а також інструменти автоматичного доведення теорем Simplify, Alt-Ergo, Yices, Z3, CVC3 та інші [6].
Frama-C - нова система для статичного аналізу програм, написаних мовою С, яка використовує платформу WHY для роботи плагіну дедуктивної верифікації. У систему також інтегровані інструменти автоматичного доведення теорем Simplify, Alt-Ergo, Yices, Z3, CVC3 та інші. Frama-C реалізована на декількох платформах (Linux, Mac OS, Windows).
Frama-C являє собою платформу, створену для статичного аналізу вихідного коду, написаного на мові C. Платформа Frama-C об'єднує кілька статичних методів аналізу в єдину систему. Спільний підхід статичних аналізаторів Frama-C дозволяє спиратися на результати вже обчислені іншими аналізаторами в рамках програми. Завдяки такому підходу, Frama-C може забезпечити ряд складних інструментів, таких як розріз та аналізатор залежностей.
ЧАСТИНА І.ТЕОРЕТИЧНІ ЗАСАДИ ДОВЕДЕННЯ ПРАВИЛЬНОСТІ ПРОГРАМ
1.1 Специфікації програм
Розглянемо наступну конструкцію:, яка має назву «трійка Хоара», де - предикат передумови (стан програми на початку виконання), - програма, - предикат післяумови (стан програми при її завершенні). Ця конструкція представляє собою специфікацію програми [1].
Специфікація програми повинна точно описувати, що повинно бути отримано в результаті виконання програми.
«Трійка Хоара» [3] - це предикат, який приймає значення істина тоді і тільки тоді, коли програма почавшись у стані за скінчену кількість кроків закінчиться у стані.
Одним із способів специфікувати програму -- це виразити її у формі наказу використовуючи природну мову.
Якщо виконання почалося у стані, що задовольняє , то є гарантія, що воно завершиться через кінцевий час у стані, що задовольняє .
Предикат називається передумовою або вихідним твердженням; -- після умовою, обіцянкою або результуючим твердженням . Фігурні дужки { і } використовуються для того, щоб відокремити твердження від самої програми.
Також необхідно відзначити, що завершення програми за кінцевий час гарантоване, звичайно ж, за умови, що її виконання продовжується.
1.2 Перетворювач предикатів wp
Для будь-якої команди S і будь-якого предикату R, який описує бажаний результат виконання команди S, визначимо предикат, який позначимо , що представляє множину всіх станів, для яких виконання команди S, яке почалося в такому стані, обов'язково закінчиться через кінцевий час у стані, що задовольняє R.
Приклади:
1. Нехай S - команда присвоювання , а R - цe. Тоді,
так як якщо , то виконання закінчується за , в той час як для виконання оператору не може зробити .
2. Нехай S - це , а R - це . Виконання команди S завжди присвоює z значення , так як .
3. Нехай S - те ж саме, що і у прикладі 2, а R - це . Тоді , так як виконання S, що починається при , присвоює z значення у, а виконання S, що починається за , присвоює z значення х, яке не дорівнює у.
Для зазначення того, що виконання S, яке почалося у стані, що задовольняє предикату Q, закінчиться у стані, який задовольняє предикату R, будемо використовувати позначення .
Q називається передумовою, а R - післяумовою S. Подібно до цього називається найслабшою передумовою для S по відношенню до R, оскільки воно визначає множину всіх станів, таких, що виконання, яке почалося в будь-якому з них, закінчиться при істинному R.
Тобто позначення - це просто інша форма предикату .
Треба звернути увагу на те, що - в дійсності є реченням обчислювання предикатів, так як воно еквівалентно . Таким чином, в будь-якому стані воно або істинне, або хибне.
Зазвичай, команда S створюється з визначеною метою, а саме забезпечити істинність якої-небудь конкретної післяумови R.
- функція з двома аргументами: командою S і предикатом R. Якщо зафіксувати на деякий час довільну команду S, то можна записати як функцію одного аргументу . Функція перетворює будь-який предикат R в інший предикат . Це пояснює походження терміну «перетворювач предикатів» для .
Деякі властивості wp
Розглянемо предикат (для довільної команди S). Цей предикат описує множину станів, таких, що виконання S, яке почалося у будь-якому з цих станів, обов'язково закінчиться у стані, який задовольняє F. Але жоден з станів не може задовольняти F, так як F - це пуста множина. Отже, не може бути такого стану, для якого , і з цього отримуємо першу властивість.
Закон виключення дива:
. (1.2.1)
Дійсно, було б дивом, якби виконання могло завершитись в ніякому стані.
Другий закон такий: для будь-якої команди S і предикатів Q і R виконується наступна властивість.
Дистрибутивність кон'юнкції:
. (1.2.2)
Формула (1.2.2) є тавтологією. Це можна показати, якщо спочатку роздивитися довільний стан , який задовольняє лівій частнині (1.2.2). Виконання команди , яке почалося у стані , закінчиться при істинних і . Отже, буде також істинно, і знаходиться у . Це показує, що із лівої частини випливає права. Далі припустимо, що знаходиться у . Тоді виконання , яке почалося у стані , обов'язково закінчиться в деякому стані , що задовольняє . Будь-яке таке задовольняє і і , так що знаходиться у і у . Отже, з правої частини випливає ліва. Разом з попередньою імплікацією це спричиняє те, що вони еквівалентні.
Закони (1.12.1) і (1.2.2) було отримано, спираючись на неформальну інтерпретацію . Тепер (1.2.1) і (1.2.2) можна прийняти за вихідні аксіоми і використовувати так, як це робиться для інших аксіом і законів обчислення предикатів. За допомогою цих аксіом можна довести ще два корисних закони.
Закон монотонності:
якщо , то (1.2.3)
Дистрибутивність диз'юнкції:
. (1.2.4)
1.3 Команди skip, abort і композиція команд
Розглянемо в якості визначення команди саме визначення в термінах wp.
Команда skip. При виконанні цієї команди нічого не робиться (треба припустити, що протягом дуже короткого часу). Ця команда еквівалентна «порожньому» оператору у мовах програмування.
Визначення:
. (1.3.1)
Команда abort. Ця команда - єдина можлива команда, перетворювач предикатів якої є «постійною» функцією.
Визначення:
. (1.3.2)
Ця команда ніколи не буде виконуватися, оскільки вона може виконуватися тільки у стані, який задовольняє F, але жоден з станів не задовольняє предикату F. Якщо коли-небудь виконання програми доходить до місця, в якому повинна виконуватися команда abort, то зрозуміло, що програма (і її доведення) помилкова, і потрібне аварійне завершення.
Послідовне сполучення - це один із способів складання великих програмних сегментів з менших. Нехай та - дві команди. Тоді - нова команда. Щоб її виконати, потрібно спочатку виконати , а потім .
Визначення:
. (1.3.3)
Наприклад:
()
Розглянемо послідовність трьох команд: . Її виконання повинно містити виконання спочатку , потім і, нарешті, виконання . Треба переконатися в тому, що така послідовність також має смисл у термінах . Операція композиції функцій, яка використовується при визначенні послідовного сполучення, асоціативна. Отже:
Таким чином, може мати як інтерпретацію, так і .
Оператор «;» використовується для з'єднання двох суміжних незалежних команд в єдину команду приблизно так як в природній мові для з'єднання незалежних речень [1].
Доведення коректності команди skip, abort
і послідовного сполучення «;»
Ідея доведення коректності команд полягає у встановленні того, чи відповідає визначення команди визначенню , а це можна зробити перевіришви аксіоми (1.2.1) і (1.2.2) для кожної з команд.
Доведення коректності команди skip:
1. Аксіома «Виключення дива»:
.
Доведення
.
2. Аксіома «Дистрибутивність кон'юнкції»:
.
Доведення
.
Доведення коректності команди abort:
1. Аксіома «Виключення дива»:
.
Доведення
.
2. Аксіома «Дистрибутивність кон'юнкції»:
.
Доведення
.
Доведення коректності команди послідовного сполучення «;»:
1. Аксіома «Виключення дива»:
.
Доведення
з (1.2.1)
2. Аксіома «Дистрибутивність кон'юнкції»:
.
Доведення
.
1.4 Команда присвоювання
1.4.1 Присвоювання простим змінним
Команда присвоювання виглядає наступним чином: , де х - проста змінна, е - вираз, типи х і е співпадають. Таку команду читають «х отримує значення е».
Правильно команда може виконуватися тільки у стані, в якому може бути розраховано значення е (наприклад, якщо не відбувається ділення на 0). Виконання складається з обчислення значення е і запису отриманного значення в комірку пам'яті з ім'ям х. В результаті (значення) х замінюється на (значення) е. Якщо показати таку підстановку синтаксично, отримаємо:
Визначення:
, (1.4.1)
де - предикат, який описує множину всіх станів, в яких може бути обчисленно значення е (тобто, де е визначене).
Так як вирази е не визначаються формально, також формально не буде визначено предикат . Проте він повинен виключати всі стани, в яких обчислення значення е може не дати результату (наприклад, при діленні на нуль або при виході індексу за область значень).
Часто взагалі випускають і записують:
, (1.4.2)
оскільки присвоювання завжди варто писати лише у такому контексті, де вирази, що до нього входять, можуть бути правильно обчислені.
Приклади:
1. . Тобто, виконання ніколи не може зробити .
2. .
3. .
4. Нехай с ? константа. Тоді, . Це означає, що виконання обов'язкого завершиться і дасть значення с в х, якщо і тільки якщо значення виразу е перед виконанням присвоювання було с.
Виконання присвоювання може змінювати лише ту змінну, яка стоїть в його лівій частині.
1.4.2 Обмін місцями значень двох змінних
Послідовність присвоювань може бути використана для взаємної заміни (перестановки) значень змінних х і у. Це можна показати за допомогою наступних перетворень:
Подібні перетворення доволі складно читати і писати. Тому замість них використовують ескіз доведення, такий як наведено нижче:
або
В ескізі доведення (зліва) твердження стоять поміж кожними двома командами. Твердження є післяумовою для першої команди і передумовою для другої. Часто ескіз доведення читається від кінця до початку, оскільки передумова визначається післяумовою та командою. Можна також скорочувати таке доведення, як показано в цьому ж ескізі (справа).
1.4.3 Кратне присвоювання простим змінним
Кратне присвоювання простим змінним має вигляд:
програмування команда вибір повторення
,
де - різноманітні прості змінні, - вирази. Для спрощення присвоювання скорочується до .
Команда кратного присвоювання виконується наступним чином. Спочатку обчислюються всі вирази. Нехай вони дали значення . Далі присвоюється , , ..., саме в такому порядку.
Кратні присвоювання корисні, оскільки вони легко описують зміни стану, які відбуваються більш ніж для однієї змінної. Їх формальне визначення - розширене визначення присвоювання для однієї змінної.
Визначення:
, (1.4.3)
де - описує множину станів, в яких можуть бути обчислені значення всіх виразів з вектору :
.
Приклади:
1. Присвоювання можна використовувати для обміну значень х і у.
2. Присвоювання здійснює «циклічне переставлення» значень х, у і z.
3.
.
1.4.4 Присвоювання елементу масиву
З функціональної точки зору на масиви, масив b являє собою просту змінну, яка містить в покажчику значення-функцію, а звичайна «індексація елементу масива» є просто використанням функції, яка знаходиться в даний момент в b, відносно аргументу і. Через позначається функція, яка відрізняється від b лише тим, що при аргументі і вона приймає значення е.
Тому присвоювання значення змінній з індексом можна розглядати як еквівалент присвоювання , так як обидва вони змінюють b таким чином, щоб отримати .
Визначення:
, (1.4.4)
де
позначає, що значення і знаходиться в області значень індексів масиву b (тобто, є правильним індексом для b).
Приклад:
(за визначенням)
(підстановка)
Отже, виконання завжди присвоює значення 5.
Доведення коректності команди присвоювання
1. Аксіома «Виключення дива»:
.
Доведення
.
2. Аксіома «Дистрибутивність кон'юнкції»:
.
Доведення
.
1.5 Команда вибору
Системи понять мов програмування зазвичай включають умовну команду, або оператор if, який дозволяє варіювати виконання своїх команд в залежності від теперішнього стану програмних змінних.
Наприклад, така команда може мати вигляд:
.
Виконання цієї команди записує в z абсолютну величину х: якщо , то виконується перша альтернатива , в іншому випадку виконується друга альтернатива . Цю команду також можна записати у наступному вигляді:
(1.5.1)
або ж, так як вона достатньо коротка і проста, в один рядок:
.
У команді (1.5.1) містяться дві складові виду (розділені символом ), де - логічний вираз, а - команда. Команда називається охороняємою командою, так як служить охороною входу , забезпечуючи те, що буде виконуватися тільки при виконанні умови .
Загальний вид команди вибору:
… (1.5.2)
де і всі - охороняємі команди. Кожне з може бути довільною командою - skip, abort, послідовним сполученням команд, присвоюванням, іншою командою вибору та ін.
Для скорочення запису загальний вид команди (1.5.2) будемо позначати через , а через будемо позначати диз'юнкцію .
Виконати команду можна наступним чином. Спочатку перевіряємо . Якщо будь-яка охорона не визначена у стані, в якому починається виконання, то може відбутися аварійне завершення програми. Це відбувається через те, що немає ніяких обмежень на обчислення значень охорон. Далі повинна бути істинною щонайменше одна із охорон, в іншому випадку виконання завершиться аварійним виходом. І, нарешті, якщо хоча б одна з охорон істинна, то обирається одна з охороняємих команд , у якої охорона істинна і виконується .
Тепер визначення майже очевидне. Перший кон'юктивний член вказує на те, що всі охорони повинні бути визначеними, другий - на те, що хоча б одна охорона істинна. Інші кон'юктивні члени вказують на те, що виконання будь-якої команди , для якої охорона істинна, завершується при істинному .
Визначення:
(1.5.3)
Зазвичай припускається, що охорони - всюди визначені функції, тобто їх значення визначені у всіх станах. Це припущення дозволяє спростити визначення, опустивши перший кон'юктивний член. За допомогою кванторів визначення перетворюється у наступну форму:
Визначення:
(1.5.4)
Теорема про команду вибору
Доволі часто потрібна не найслабша передумова команди вибору, а лише перевірка того, чи спричиняє її відома передумова. В таких випадках корисна наступна теорема.
Теорема. Розглянемо команду . Нехай предикат задовольняє умовам
1)
2) для всіх і, .
Тоді (і тільки тоді)
.
Доведення. По-перше, покажемо, як виноситься з області дії квантору у другій умові теореми.
(імплікація)
(закон де Моргана)
( не залежить від і)
(імплікація, двічі)
Тобто, маємо
(умови 1 і 2)
(з наведеного вище)
(з (1.4.4))
Отже, кон'юнкція припущень еквівалентна висновку, теорема доведена.
1.6 Команда повторення
1.6.1 Звичайний цикл «поки» і команда повторення
Цикл типу «поки» може мати, наприклад, такий вигляд:
.
Частіше такі цикли описують за допомогою блок-схем
Позначимо цикли типу «поки» так
,
де - охороняєма команда. Цей запис можна узагальнити до наступного, який будемо називати командою повторення і позначимо :
… (1.6.1)
де і кожна з - охороняєма команда.
Якщо описати роботу (1.6.1) одним реченням, то отримаємо: повторюйте (або ітеруйте) наступну дію: обирайте охорону , яка істинна, і виконуйте відповідну команду .
Після завершення всі охорони хибні. Вибір істинної охорони і виконання відповідної команди називають виконанням кроку циклу.
Допускається недетермінізм, тобто якщо істинні дві або більше охорони, обирається будь-яка з них (але тільки одна) і виконується відповідна команда. Така ситуація може виникнути на будь-якому кроці. Звідси видно, що еквівалентна:
…
де позначає диз'юнкцію охорон , або ж
,
де позначає команду вибору з тими ж самими командами, що охороняються, як і в (1.6.1).
Це означає, що, якщо всі охорони хибні, тобто якщо хибне, виконання циклу завершується. В іншому випадку виконується відповідна команда вибору , і процес повторюється. Одна ітерація циклу еквівалентна встановленню, що істинно, і виконанню .
1.6.2 Формальне визначення DO
Наступний предикат визначає множину станів, в яких виконання завершиться за 0 кроків через те, що всі охорони з самого початку будуть хибними, причому після завершення істинне:
.
Напишемо предикат при , який виражає множину всіх станів, в яких виконання закінчиться за або менше кроків при істинному . Визначення буде рекурсивним. Предикат буде визначатися через . Перший випадок, коли завершується через 0 кроків, - це той випадок, коли істинно . В іншому випадку відбувається хоча б один крок. Таким чином, повинно бути істинним на початку, і крок полягає у виконанні відповідної команди . Таке виконання завершується у стані, в якому до завершення циклу залишаеться або менше кроків. Подібний розгляд приводять до виразу
для .
Якщо згадати, що повинно відображати множину станів, в яких виконання завершується за кінцеву кількість кроків і за істинним , тобто з самого початку в кожному з таких станів повинно бути таке , що виконання циклу потребує не більше кроків, отримаємо:
Визначення:
(1.6.2)
1.6.3 Теорема про цикл, його інваріант і обмежуючу функцію
Теорема. Розглянемо цикл . Припустимо, що предикат Р задовольняє умові
1. для усіх і, .
Далі, нехай цілочислова функція задовольняє наступним умовам, де новий ідентифікатор:
2.
3. при
Тоді,
З першої умови виходить, що буде істинним у момент завершення . У другій умові потрібно, щоб функція була обмежена знизу нулем доки виконання ще не завершилося. У третій умові потрібно, щоби зменшувалося щонайменше на 1, так як завершення обов'язково відбудеться. При необмеженій кількості кроків стало би менше за будь-яку заздалегідь встановлену межу, що призвело б до протиріччя з умовою 2. І також у момент завершення всі охорони хибні, тобто істинно.
1.6.4 Анотування циклу і розуміння анотацій
Предикат , який є істинним до виконання і після виконання кожного кроку циклу, називається інваріантним відношенням або просто інваріантом циклу («інваріантний» означає той, що не змінюється під впливом сукупності математичних операцій, що розглядаються. В цьому випадку маємо єдину операцію - виконання кроку циклу за умови істинності на початку).
Для того, щоб показати, що виконання циклу завершиться, вводять цілочислову функцію , визначену на значеннях змінних програми. Ця функція є верхньою межею кількості кроків циклу, які повинні надалі бути виконані. При кожному кроці циклу зменшується щонайменш на 1, і доки виконання циклу ще не завершилося, обмежена знизу нулем. Тобто, цикл повинен завершитися.
Функція називається функцією, що змінюється, в протилежність інваріантному відношенню , так як функція змінюється на кожному кроці, а відношення залишається незмінно істинним. Цю функцію також називають обмежуючою функцією.
Алгоритми анотують для того, щоб показати, коли і в яких точках істинні інваріанти. Найчастіше надають інваріант і обмежуючу функцію у тексті, який супроводжує алгоритм. Якщо їх необхідно включити в алгоритм, то використовують наступні скорочення:
(1.6.3)
…
Якщо є цикл, оформлений подібно до (1.6.3), то відповідно до теореми про цикл, його інваріант і обмежуючу функцію, для того щоб зрозуміти правильний він чи ні, достатньо перевірити пункти, які перераховано нижче.
1. Покажіть, що істинне перед початком виконання циклу.
2. Покажіть, що за всіма , тобто що виконання кожної команди, що охороняється, завершиться при істинному . Звідси випливає, що є інваріантом циклу.
3. Покажіть, що, тобто те, що в момент завершення виконання є істинним бажаний результат.
4. Покажіть, що, тобто, що обмежена знизу, доки цикл не завершиться.
5. Покажіть, що для всіх , тобто що кожен крок циклу призводить до зменшення обмежуючої функції.
1.7 Побудова програм
Програма називається правильною по відношенню до заданої післяумови та передумови , якщо має місце .
Метод побудови програм базується на визначенні найслабшої передумови і використовує визначення програмних конструкцій у термінах найслабших передумов.
Таким чином, цей спосіб заснован на формальному доведенні, яке включає до себе найслабші передумови та теореми о конструкціях вибору та повторення. Тому є важливими наступні принципи.
Принцип 1. Програма і її доведення повинні будуватися одночасно.
Принцип 2. Використовуйте теорію для проникнення у суть роботи; застосовуйте інтуіцію і здоровий глузд там, де це можливо, але одразу повертайтеся до пітримки з боку формальної теорії, коли виникають складнощі.
Принцип 3. Вивчіть властивості об'єктів з якими повинна працювати програма.
Принцип 4. Ніколи не нехтуйте будь-яким з фундаментальних принципів як очевидним, оскільки тільки усвідомлене використання таких принципів може сприяти успіху.
1.8 Програмування як цілеспрямована діяльність
Принцип 5. Програмування - цілеспрямована діяльність.
Принцип 6. Перед тим як пробувати вирішити задачу, треба впевнитися, що ви розумієте, в чому вона складається.
При програмуванні цей загальний принцип перетворюється у наступний.
Принцип 7. Перед тим як будувати програму, уточніть і роз'ясніть для себе передумову і післяумову.
1.8.1 Стратегія побудови команди вибору
Для того щоб створити охороняєму команду, знайдіть таку команду , виконання якої дасть післяумову принаймні в деяких випадках; знайдіть логічний вираз , який задовільняє ; поєднайте їх у вираз . Продовжуйте створювати охороняємі команди доки передумова конструкції не буде забезпечувати, що щонайменше одна із охорон істинна.
Принцип 8. Між інших рівних умов робіть охорони у командах вибору настільки сильними, наскільки це можливо, для того щоб деякі помилки призводили до аварійних зупинок програми.
1.8.2 Стратегія побудови команди циклу
Стратегія полягає у тому, щоб спочатку побудувати таку охорону , для якої ; далі побудувати тіло циклу таким чином, щоб воно зменшувало обмежуючу функцію і зберігало інваріант циклу.
У термінах високого рівня наведену стратегію можна відобразити наступним чином:
Принцип 9. Між інших рівних умов робіть охорону циклу настільки слабкою, наскільки це можливо, для того щоб помилка могла викликати зациклення.
1.9 Теоретичні аспекти «Програмування за контрактом»
В більшості об'єктно-орієнтовних мов програмування не приділяється багато уваги семантичним властивостям класу. Кожен клас має список своїх операцій. Але інформація про те, коли можна викликати той чи інший метод, які параметри не обов'язкові, що треба очікувати в результаті виконання, не є формальною. Більшість такої інформації або відсутня або міститься у вигляді коментарів. В цьому випадку ми отримаємо дублювання інформації, оскільки реалізація методу має відповідати коментарям або іншій документації, і відсутність можливості контролювати поведінку під час виконання коду. Для усунення цих недоліків розроблено формальний спосіб, що визначає відносини між класами та їх клієнтами (тобто кодом, що створює екземпляри цих класів і взаємодіє з ними), який недвозначно встановлює права та обов'язки сторін, що отримав назву "проектування за контрактом".
Проектування за контрактом (Design by Contract) - це встановлення відносин між класом і його клієнтом у вигляді формальної домовленості, які однозначно визначають права та обов'язки обох сторін. Тільки через точне визначення вимог та відповідальності для кожного модуля можна сподіватись на досягнення значного ступеня довіри до великих програмних систем[2].
1.9.1 Коректність ПЗ
Будь-яка функція не є ні коректною, ні некоректною. Поняття коректності набуває сенсу тільки в контексті очікуваного результату. Функція може бути коректною по відношенню до якогось певного висловлювання, і бути хибною по відношенню до іншого. В цьому випадку сигнатура методу не несе достатньо інформації для визначення того, є метод коректним чи ні. Семантика методу передається його назвою (хоча ім'я методу Remove ніяк не може говорити про поведінку цього методу для порожній колекції) або коментарями. Але коментарі часто застарівають, семантика методів змінюється таким чином, що ім'я перестає відображати суть методу, але головне, що це явно не той шлях, який зможе забезпечити надійність розроблюваного ПЗ.
Поняття коректності ПЗ можна розглядати тільки по відношенню до деякої специфікації, в той час, як програмний елемент сам по собі не може бути ні коректним, ні некоректним [2].
1.9.2 Формула коректності. Сильні та слабкі умови
Нехай A - це деяка операція, тоді формула коректності (correctness formula) - це вираз вигляду:
Формула коректності, звана також тріадою Хоара, говорить наступне: будь-виконання А, що починається в стані, де Q істинне, обов'язково завершиться і в заключному стані буде істинним R, де Q і R - це твердження, при цьому Q є передумовою, а R - післяумовою [2].
Наведена вище формула коректності визначає повну коректність (total correctness), яка гарантує скінченність операції A. Крім цього існує поняття часткової коректності (partial correctness), яке гарантує виконання післяумови R тільки за умови завершення виконання операції A.
Розглянемо наступну тріаду Хоара:
Ця тріада коректна, тому що якщо перед виконанням операції передумова виконується і значення x дорівнює 5, то після виконання цієї операції післяумовою (x більше нуля) буде гарантовано виконуватися (за умови коректної реалізації цілочислової арифметики). З цього прикладу видно, що наведена післяумова не є найсильнішою. Найсильнішою післяумовою при заданій передумові є , а найслабшою передумовою при заданій післяумові є . З виконуваної формули коректності завжди можна отримати нові виконувані формули, шляхом послаблення післяумови або посилення передумови.
1.9.3 Твердження
Специфікація і реалізація нерозривно пов'язані один з одним: специфікація говорить про те, що повинна робити система, а реалізація визначає, як це буде досягнуто. Обидва ці аспекти програмного продукту повинні розвиватися одночасно, чого в більшості програмних проектів не відбувається. (Хоча, насправді, далеко не у всіх проектах специфікація взагалі існує в будь-якому формальному вигляді, в такому випадку єдиним джерелом специфікації є вихідний код, що в свою чергу робить неможливим перевірити його коректність.) Якщо специфікація і реалізація знаходяться в різних джерелах, ми стикаємося з класичною проблемою дублювання інформації, і в цьому випадку неузгодженість цієї інформації є всього лише питанням часу. У проектуванні за контрактом вираз специфікації здійснюється за допомогою механізму тверджень (assertions).
Твердження - це логічний вираз, яке має бути істинним на деякій ділянці програми і може включати сутності нашого ПЗ. Твердженнями можуть служити звичайні булеві вирази з деякими розширеннями. Так, у твердженнях крім булевих виразів можуть застосовуватися функції (але з деякими обмеженнями: це повинні бути функції без «побічних ефектів», тобто не змінюють стан об'єкта). А для післяумови необхідна можливість звернутися до результату виконання функції, а також до значення, яке було до початку виконання цієї функції.
1.9.4 Передумови та післяумови
Будь-яка відкрита функція класу - це не просто абстрактний фрагмент коду, призначений для виконання невизначеного завдання. Кожна функція має строгі семантичні властивості, які відображають, що робить ця функція, незалежно від того, як вона це робить. Для чіткого вираження задачі, що виконується конкретної функцією, з нею пов'язують два твердження - передумова і післяумова. Передумова визначає умови, які повинні виконуватися щоразу перед викликом функції, а післяумова визначає властивості, що гарантуються після завершення її виконання. Передумовою та постусловіем визначають контракт функції з усіма її клієнтами.
Нехай передумова визначається ключовим словом «require», а післяумова - ключовим словом «ensure». Тоді, якщо з деякою функцією r пов'язані затвердження «require pre» і «ensure post», то клас говорить своїм клієнтам наступне [2] :
«Якщо ви обіцяєте викликати R в стані, що задовольняє «pre», то я обіцяю в заключному стані виконати «post»».
Передумовою та післяумовою визначають контракт між двома програмними елементами: класами-клієнтами та класами-постачальниками, а будь-який хороший контракт встановлює чіткі зобов'язання між його учасниками. Зобов'язання одного учасника визначають вигоди іншого і навпаки. Це вірно як для контрактів між людьми (або людьми і компаніями), так і для контрактів між програмними елементами.
Передумова зв'язує викликаючий код: визначаються умови, за яких виклик методу клієнтом легітимний (наприклад, x> 0 для функції Sqrt або Count! = 0 для функції Pop класу Stack). При цьому зобов'язання клієнта приносять вигоду класу-постачальнику, оскільки класу, що виконує операцію, не потрібно турбуватись про те, що робити при порушенні передумови: повертати значення за замовчуванням або код помилки, генерувати виключення, зберігати інформацію про помилку в потік вводу-виводу або переривати виконання програми.
1.9.5 Інваріанти класу
Передумови і післяумови характеризують конкретні функції, але не клас в цілому. Екземпляри класу часто мають деякі глобальні властивостями, які повинні виконуватися після створення об'єкта і не порушуватися протягом усього часу життя. Такі властивості носять назву інваріантів класу (class invariants). Вони визначають більш глибокі семантичні властивості та обмеження, властиві об'єктам цього класу.
Такими властивостями можуть служити внутрішні умови (деякий поле не дорівнює null або кількість елементів невід'ємне) або правила узгодженості внутрішнього стану об'єкта. Кожна така умова не пов'язує конкретні функції, а характеризує об'єкт в кожен момент часу.
Інваріант класу повинен виконуватися після завершення функції створення (конструктора) та між викликами всіх відкритих методів. Цілком законно, що деяка функція на початку свого виконання руйнує інваріант класу, а перед завершенням виконання - відновлює його істинність. При цьому виконання інваріантів повинна дотримуватися тільки між викликами відкритих методів, в той час як закриті методи можуть викликатися в стані, в якому інваріант порушений, і завершувати своє виконання, не відновлюючи його істинність.
Затвердження Inv є коректним інваріантом класу, якщо і тільки якщо воно задовольняє наступним двом умовам [2]:
1. Кожен конструктор, який можна застосовувати до аргументів, що задовольняє його передумов в стані, в якому атрибути мають значення, встановлені за замовчуванням, виробляє заключне стан, що гарантує виконання Inv.
2. Кожен відкритий метод класу, що викликається з аргументами в стані, що задовольняє Inv і передумов, виробляє заключне стан, що гарантує виконання Inv.
1.9.6 Твердження та перевірка вхідних даних
Проектування за контрактом призначено для формалізації взаємини двох програмних елементів всередині довіреної середовища і не призначене для взаємодії програмного елемента із зовнішнім світом. Головний принцип захищеного коду «все вхідні дані хибні, поки не доведено протилежне» [8] залишається в силі, і про нього не слід забувати при розробці будь-яких додатків, незалежно від того, побудовані вони за принципами проектування за контрактом або без нього.
Наявність передумов в модулях введення даних не є достатніми, оскільки неможливо покласти відповідальність за їх дотримання безпосередньо на користувача. Всі дані, які перетинають кордон ненадійною і довіреної середовища, вимагають явної і ретельної перевірки. Принципи проектування за контрактом вступають в силу тільки всередині довіреної середовища у вигляді післяумов модулів вводу.
1.9.7 Проектування за контрактом та захисне програмування
Одним з головних принципів проектування за контрактом є відсутність перевірок передумов всередині тіла програми. Це правило суперечить принципам захисного програмування, в якому «відкриті методи класу припускають, що дані небезпечні і відповідають за їх перевірку і виправлення. Якщо дані були перевірені відкритими методами класу, закриті методи можуть вважати, що дані безпечні »[9]. При цьому усередині відкритих методів рекомендується застосовувати обробники помилок (наприклад, генерувати виключення або повертати відповідний код помилки у разі невірних вхідних даних), а в закритих методах застосовувати затвердження (assertions) (оскільки це характеризує програмні помилки).
Як було показано в попередньому розділі, в проектуванні за контрактом ніхто не відмовляється від перевірки ненадійних даних. Ключове розходження між контрактними та захисним програмуванням полягає в місці проходження кордону між ненадійною і довіреної середовищами. У проектуванні за контрактом ця межа проходить в модулях введення і обробки вхідних даних, а в захищеному програмуванні вона проходить по відкритому інтерфейсу будь-якого класу.
Крім того, в захисному програмуванні існує негласне правило, за яким «зайва перевірка ніколи не зашкодить», і дійсно, якщо розглянути простий приклад (наприклад, функцію вилучення квадратного кореня double Sqrt (double x)) може здатися, що жодної шкоди від додаткової перевірки немає і бути не може, але чи так це насправді?
Основні принципи розробки (які не мають ніякого відношення до контрактів) говорять про те, що найкраще, щоб клас або функція вирішувала тільки одну задачу, але робила це добре. Одна додаткова перевірка всередині функції Sqrt в домашній роботі з інформатики ніякої погоди не зробить, але якщо говорити про реальні великих проектах, то в них код обробки помилок може займати більше половини всього коду.
Подобные документы
Використання ітерацій для обчислення приблизних значень величин. Розробка ітераційних алгоритмів з перевіркою правильності введення даних. Побудова блок-схеми і програмування мовою Turbo Pascal обчислення значення функції, розкладеної в степеневий ряд.
лабораторная работа [197,2 K], добавлен 16.12.2010Методика та порядок програмування алгоритмів циклічної структури із заданим числом повторень за допомогою мови програмування VAB. Алгоритм роботи з одновимірними масивами. Програмування алгоритмів із структурою вкладених циклів, обробка матриць.
курсовая работа [27,7 K], добавлен 03.04.2009Мoвa прoгрaмувaння як систeма пoзначень, що служить для точного опису програм або алгоритмів для ЕOM. Вимоги до мов програмування, класифікація за їх особливостям. Загальна характеристика найбільш поширених мов програмування: Сі, Паскаль, Delphi, Бейсік.
реферат [24,4 K], добавлен 10.11.2012Розробка програмного додатку - гри "Jump way", яка поєднала в собі сучасні методи побудови 2D ігор. Обґрунтування вибору мови програмування. Проектування UML-діаграм класів. Користувацький інтерфейс. Програмна реалізація гри. Інструкція користувача.
курсовая работа [1,2 M], добавлен 09.01.2017Аналіз розроблення та програмування обчислювального процесу лінійної структури, налагодження програм. Вивчення правил запису констант, числових і символьних змінних, типів даних. Побудова алгоритму розв’язування завдання та креслення його блок-схеми.
реферат [2,1 M], добавлен 22.04.2012Модель аналізу-синтезу компіляції. Формальний опис вхідної мови програмування. Вибір технології програмування, проектування таблиць транслятора та вибір структур даних. Опис програми реалізації лексичного аналізатора. Розробка дерев граматичного розбору.
курсовая работа [75,8 K], добавлен 26.12.2009Розробка програми на мові програмування Асемблер для обчислення виразу. Розрахунок значень А, В, С у процедурах. Аналіз отриманих результатів за допомогою відлагоджувальника Turbo Debugger при різних заданих значеннях та перевірка їх правильності.
лабораторная работа [203,4 K], добавлен 09.01.2013Проектування і програмування обробки деталей на верстатах з числовим програмним управлінням. Проектування технологічної оперції обробки заготовки: вибір інструменту, ескізи наладок. Керуюча програма обробки деталей "кришка" та "вал". Верифікація програми.
курсовая работа [1,7 M], добавлен 29.11.2011Прототип об'єктно-орієнтованого програмування. Управління процесом реалізації програми. Розвиток апаратних засобів. Об'єктно-орієнтовані мови програмування. Надійність і експлуатаційні якості програм. Візуальне об’єктна-орієнтовне проектування Delphi.
контрольная работа [28,9 K], добавлен 18.05.2009Аналіз предметної області та відомих реалізацій гри 2048. Універсальна мова моделювання UML в процесі проектування гри. Розробка алгоритмів функціонування модулів гри "2048". Оператори мови програмування Python. Особливості середовища Visual Studio.
курсовая работа [1,2 M], добавлен 17.02.2021