Формы спецификации программы

Распространена точка зрения, что спецификацию программы можно представить в виде функции. Поскольку это не всегда так, возникает вопрос о классификации форм, которые может принимать спецификация программы. Определим следующие три формы спецификации программы: предикатную, процессную и процессорную.

Спецификация называется предикатной, если она эксплицируема в виде формулы на языке исчисления предикатов [2]. Такая экспликация возможна для спецификации, представленной в математической форме. Для программы с предикатной спецификацией характерна простая схема взаимодействия программы с окружением: ввод входных данных происходит в начале исполнения программы, вывод результирующих данных - в конце, а других взаимодействий с окружением нет. В данной схеме спецификация определяет функцию, отображающую значения входных данных в значения результатов.

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

Спецификация называется процессной, если эффект исполнения программы определяется в виде процесса. Процесс исполнения программы обычно определяется как бесконечный. При исполнении программа обменивается информацией с окружением, причем взаимодействие программы с окружением может быть произвольной сложности. Довольно часто процессная спецификация определяется в виде набора взаимодействующих параллельных процессов. Структура спецификации описывается следующими моделями: машиной конечных состояний [6], сетью Петри [4], моделью CSP [12] Т. Хоара, машиной абстрактных состояний [7] Ю. Гуревича и др. Предикатная спецификация может рассматриваться как частный случай процессной. Однако большинство процессных спецификаций нельзя представить в виде предикатных.

Разработка программы с процессной спецификацией является частью более общей задачи по созданию системы, функционирование которой реализует базовый процесс. В отличие от математических задач спецификация обычно не существует изначально и вырабатывается в процессе конструирования системы. Принято считать, что спецификация является результатом этапа определения требований в разработке системы и программы как ее части.

Спецификация называется процессорной, если она описывает функционирование процессора некоторого языка программирования. Спецификация определяет единую форму множеств исполнений произвольной программы на данном языке. Спецификация процессора является частью спецификации языка программирования и определяется семантикой исполнения программы. В пользовательском описании языка программирования спецификация процессора представлена частично и неявно. Формализованное описание семантики исполнения, абстрагированное от синтаксиса и статической семантики [3], применяется для проектирования внутреннего представления программы в трансляторе [8].

Формальная семантика есть математическое описание семантики языка программирования. Она используется преимущественно для целей верификации программ. Различают следующие виды формальной семантики: операционную, денотационную и аксиоматическую [14; 15]. В большинстве подходов описание формальной семантики оказывается сложным и громоздким. Перспективным является метод алгебраической семантики (разновидности денотационной), в которой состояние исполняемой программы определяется в виде многоосновной алгебры [16; 17], компоненты которой соответствуют один в один состоянию памяти исполняемой программы и операциям по манипулированию ячейками памяти. Описание алгебраической семантики в определенном смысле подобно трансляторной модели программы. Оно прозрачно и компактно, дает возможность однозначного понимания языка и становится полезным для разработчика транслятора.

Известно, что процессор для чистого языка функционального программирования можно написать на том же языке, из чего следует, что спецификация процессора представима в виде функции. Например, интерпретатор Lisp-программы можно написать на языке Lisp [9]. Однако спецификация процессора языка императивного программирования не может быть предикатной. Косвенно это следует из того, что спецификация процессора не может быть проще спецификации программы, исполняемой процессором. По нашей гипотезе процессорная спецификация сложнее процессной, поскольку процессор находится на метауровне по отношению к программе (с процессной спецификацией), которую он исполняет.

Представленные три формы спецификации определяют три принципиально различных класса программ. В первый класс входят программы для математических задач. Второй класс включает программы, работающие в режиме реального времени. Третий класс содержит значительную часть программ системного программирования. Методы разработки программ одного класса не всегда переносимы на программы другого класса.