В
первой лекции дано представление о
формальной спецификации программ -- базисе
формальных методов. Для
программ-функций спецификация определяется в виде
предусловия и
постусловия. Управляющие программы КА относятся к классу
реактивных систем. Их спецификация есть
спецификация требований; см.
другой ликбез.
Глава 2. Верификация программ
Программа является
корректной, если она соответствует своей спецификации. Требование соответствия программы и спецификации определим здесь
лишь для программ-функций: если перед исполнением программы истинно предусловие, то в случае завершения программы должно быть истинно постусловие. Данное условие принято называть условием
частичной корректности. Программа-функция обязана всегда нормально завершаться, поскольку она не взаимодействует с окружением программы, а бесконечное исполнение -- бессмысленно. Это требование есть
условие завершения программы. Объединение условий частичной корректности и завершения программы дает условие
тотальной корректности программы.
Определим
формально условия частичной корректности и завершения программы. Пусть П -- программа-функция со списком аргументов
x и списком результатов
y, P(x) -- предусловие, Q(x, y) -- постусловие, *П* обозначает предикат (зависящий от x и y), истинный
тогда и только тогда, когда программа П нормально завершается. Предикат *П* строится по программе П на базе
формальной семантики языка программирования.
Условия частичной корректности и завершения программы определяются, соответственно,
формулами корректности:
Доказательство истинности формул корректности является целью
дедуктивной верификации, являющейся наиболее сильной среди формальных методов. Доказательство формул дает стопроцентную гарантию корректности программы относительно спецификации.
Напомним, что изложение формальных методов на данном Форуме дается в упрощенном виде. Полное детальное описание представленного выше можно найти в
статье.
Верификация программы -- процедура проверки соответствия программы и ее спецификации в целях обнаружения ошибок в программе (или спецификации). В зависимости от применяемого метода различаются следующие виды верификации программ:
Развернутая классификация методов верификации программ дается в
обзорной статье нашего классика Виктора Кулямина.
Экспертиза реализуется специалистами, не являющимися авторами программы. Они детально изучают программу на предмет соответствия ее спецификации и другим документам, а также стандартам и соглашениям. Изучается и оценивается процесс разработки программы, в частности, результаты тестирования. Оцениваются характеристики программы.
Методов тестирования огромное множество. Одним из наиболее эффективных является
тестирование на базе формальных спецификаций.
Статический анализ обнаруживает семантические ошибки периода исполнения (деление на ноль, разыменование нулевого указателя и др.) статически на стадии компиляции программы не прибегая к исполнению кода. Статические анализаторы являются полезными для обнаружения ошибок, особенно в больших программных системах. Их недостаток в том, что они выдают большое число сообщений о возможных ошибках, которые на практике не подтверждаются. Следующее поколение статических анализаторов -- статические верификаторы, использующие SMT-решатели.
Статические верификаторы (
Software model checkers) способны эффективно проверять достижимость любой точки программы, а также истинность любого условия, вставляемого в код в виде оператора
assert. Статические верификаторы весьма эффективны и применяются практически во всех крупных софтверных корпорациях. Интересен опыт использования статических верификаторов для
верификации драйверов ядра операционной системы Linux.
Метод
проверки на модели (
model checking) применим для автоматической верификации систем с конечным числом состояний. Для программы строится модель в виде недетерминированного конечного автомата (обычно, модель Крипке). Проверяемые условия записываются на языке темпоральной логики LTL, CTL или др. В реальных приложениях инструмент проверки на модели может работать несколько недель. Ответом инструмента является вердикт об истинности проверяемого условия, либо контрпример, на котором проверяемое условие оказалось ложным.
В процессе
дедуктивной верификации реализуется доказательство истинности формул корректности программы, которые предварительно должны быть автоматически сгенерированы по программе и ее спецификации. При доказательстве формул корректности необходимо использовать
свойства предметной области, в рамках которой сформулирована исходная решаемая
задача. Эти свойства должны быть записаны в виде
логических утверждений и представлены в составе дополнительных
теорий, все утверждения которых должны быть предварительно доказаны. Доказательства формул корректности проводятся с помощью инструментов автоматического доказательства теорем. Простые утверждения доказываются
автоматически применением SMT-решателей. Для доказательства оставшихся утверждений используют инструменты интерактивного доказательства: PVS, Coq, HOL и др.
Возможна комбинация разных методов. Методы автоматического программного синтеза иногда рассматривают в интеграции с дедуктивной верификацией. Статический верификатор часто снабжается средствами автоматической генерации тестов в ситуациях, когда не удается построить хорошей аппроксимации цепочки условий, ведущих к месту исследуемого
assert'а.
Формальные методы базируются на использовании формальных спецификаций. Поэтому не все виды верификации являются формальными методами. Применение статических верификаторов и тестирование на базе формальных спецификаций относятся к
легковесным формальным методам. Проверка на модели, дедуктивная верификация, абстрактная интерпретация и суперкомпиляция считаются
формальными методами верификации.