Опубликован: 24.09.2008 | Уровень: специалист | Доступ: платный | ВУЗ: Московский физико-технический институт

Лекция 7: Формальные спецификации, доказательство и верификация программ

Разработка спецификации проводится по следующей схеме:

  1. Определение терминов, которыми будет специфицироваться программа.
  2. Описание понятий и объектов, для обозначения которых используется денотат, идентифицируемый с помощью некоторого имени (или фразы).
  3. Описание инвариантных свойств программы.
  4. Определение операций над структурами программы (например, ввести объект, удалить и др.), изменяющие ее состояние и сохранение инвариантных свойств.

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

При реальном выполнении спецификация исполняется итерационно. На первом уровне проверяется только свойства модели программы при заданных ограничениях независимо от среды. Затем используется уточненная и расширенная спецификация с набором формальных утверждений. И так до тех пор, пока окончательно не будет завершен процесс пошагового доказательства спецификации.

Для демонстрации возможностей VDM языка рассмотрим задачу поиска ("Поиск") в каталоге ( catalR ) репозитария компонентов имени компонента С и сравнения его с заданным в запросе пользователя. В случае совпадения имен проверяются параметры, и при их совпадении из каталога извлекается код компонента и передается пользователю.

Спецификация переменных программы "Поиск"

\begin{array}{rcrl}
        repoz & :: = & developеrs :& dl \to Init - set \\
        &&catalR:& cat \to Init - set \\
        &&role :& inst \to facet \\
        facet &:: = &autors:& Milk \\
        &&title :& N \\
        user &:: = &developer :& Itn \\
      &&free :& Bool,
        \end{array}

где developers - cведения о разработчике компонента С ; facet - переменная, в которую посылается код компонента, выбранного из каталога catalR репозитария repoz при совпадении имен в каталоге и запросе; role - переменная, в которой хранится текущий элемент из репозитария, найденный по фасете компонента с номером N для user ; autors: Milk - имя разработчика компонента; free: Bool - переменная, которая используется для задания признака - компонент не найден или к нему никто не обращался.

Описание инвариантных свойств программы

\begin{array}{l}
        type \;inv - repoz: repoz \to Bool \\
        inv - repoz (dev) = \\
        let\; mk \; repoz (cd, c, role) = dev\;in \\
        (\forall i \in dom \; cd)\\
        (\forall i \in cd (i)\\
        ((\exists j \in dom \;cd\; \& \;i \in c) \;\&\; \exists a \in elems\;role (i)\text{, }autors (a \in dom cd)\\
        \&\; free = false \Leftrightarrow developer = catalR \;\&\; facet (N) = role \dots
        \end{array}

Операторы программы проверяют список имен компонентов в каталоге, который содержит N элементов типа set. Если они совпадают с именем в запросе, результат сохраняется в role.

Доказательство инвариантных свойств программ должно проводиться автоматизированным способом с помощью специально созданных инструментальных средств поддержки VDM языка.

6.1.2. Спецификация программ средствами RAISE

RAISE-метод и RSL-спецификация (RAISE Specification Language) [6.9, 6.10] были разработаны в 80-х годах как результат предварительного исследования формальных методов и их пополнения новыми возможностями. Метод содержит нотации, техники и инструменты для конструирования программ и доказательстве их правильности. Он имеет программную поддержку в виде набора инструментов и методик, которые постоянно развиваются и используются при доказательстве правильности программ, описанных в RSL и ЯП (С++ и Паскаль). Язык RSL содержит абстрактные параметрические типы данных (алгебраические спецификации) и конкретные типы данных (модельноориентированные), подтипы, операции для задания последовательных и параллельных программ. Он предоставляет аппликативный и императивный стиль спецификации абстрактных программ, а также формальное конструирование программ в других ЯП и доказательство их правильности. Синтаксис этого языка близок к синтаксису языков С++ и Паскаль.

В RSL-языке имеются предопределенные абстрактные типы данных и конструкторы сложных типов данных, такие как произведение ( product ), множества ( sets ), списки ( list ), отображения ( map ), записи ( record ) и т.п. Далее рассмотрим некоторые конструкторы сложных типов данных.

Произведение типов - это упорядоченная конечная последовательность типов Т_{1}, Т_{2}, \dots, Т_{n} произведения ( product ) Т _{1} \times Т_{2} \times, \dots, \times  Т_{n}. Представитель типа имеет вид ( v_{1}, v_{2} , \dots, v_{n} ), где каждое v_{i} -это значение типа Т_{i}. Компонент произведения можно получить операцией get и переслать set, т.е.

\begin{array}{l}
       get\;component(i, d) = get\;value(i, d), \\
       set\;component(d, i, val) = d \Rightarrow \nabla(I \to val).
    \end{array}

Количество компонентов произведения d находится таким образом:

size (d) = id \nabla (null (couter inc(counter))).

Конструктор произведения d_{1} и d_{2} строит произведение d_{1} \times d_{2} вида:

product (d_{1}, d_{2}) = id \nabla (size(d_{1}) \Rightarrow couter\;1) \nabla (null (couter\;2) inc\; couter\; 2))).

Для каждого конкретного типа product(Т_{1} \times  Т_{2} \times, \dots, \times Т_{n}) можно построить конструктор значения этого типа из отдельных компонентов произведения таким образом:

make\; product (value_{1}, \dots, value_{n}) =
    (value_{i} \Rightarrow 1) \nabla \dots \nabla (value_{n} \Rightarrow n),

где каждое значение value_{i} имеет тип Т_{i}, а результирующее значение - тип произведения Т_{1} \times Т_{2} \times, \dots, \times Т_{n}

Списки типов - это последовательность значений одного типа list\;Т, могут быть конечным списком типов Т^k и неконечными списком типов T^n. В качестве структур данных типа списка может быть бинарное дерево, в котором есть голова ( head ) и сын ( tail ), который следует за ним в списке, и хвост. К операциям списка относится операция hd - взятия первого элемента списка, т.е. головы, и операция tl - хвоста остальных элементов (аналогично как в VDM).

Функция Caddr (I) = L \Rightarrow tail \Rightarrow tail \Rightarrow Head выбирает из списка I -элемент. Индекс элемента помогает выбрать нужный элемент списка:

Index(I, idx) = L(idx) = \text{ while }(\neg \text{ is }null(idx))\text{ do }((L \Rightarrow tail \Rightarrow L) \nabla dec(idx)) L \Rightarrow Head.

Для определения количества элементов в списке выполняется функция:

\begin{array}{l}
    len (L) = (ld\; \nabla\; null (result)) \\
    \text{while }(L \Rightarrow)\text{ do }(( L \Rightarrow tail \Rightarrow tail \Rightarrow L)\; \nabla\; inc (result)) \\
    result \Rightarrow.
    \end{array}

Элемент списка находится так:

\begin{array}{l}
    elem (L) = (ld\; \nabla \;empty (result)) \\
    \text{while }(L \Rightarrow)\text{ do }(( L \Rightarrow tail \Rightarrow L)\; \nabla \\
    (result \uparrow ( L \Rightarrow head \Rightarrow) \Rightarrow elem ) \Rightarrow result) \\
    result \Rightarrow.
    \end{array}

Аналогично можно представить функции конкатенации, преобразование типов данных, добавления элемента в голову и хвост списка и др.

Отображение - это структура ( map ), которая ставит в соответствие значениям одного типа значение другого типа. Вместе с тем отображение - это бинарное отношение декартова произведения двух множеств как совокупности двухкомпонентных пар, в которых первый компонент - arg содержит элементы аргументов отображения, а второй компонент res - соответствующие элементы значений этого отображения.

В языке имеются разные допустимые операции над отображениями: наложение, объединение, композиция, срез и др. Среди этих видов отношений рассмотрим, например, композицию отображений ( m_{1}, m_{2} ):

\begin{array}{l}
    (ld\;\nabla\; (compose (m_{1}, m_{2}) \Rightarrow m))\;apply\;(m, elem) \\
    apply\; to\; composition\;(m_{1}, m_{2}, elem) =\\
    =(ld\; \nabla\; (image (elem, m1)\Rightarrow s)\;restrict\;(m_{2}, s) \Rightarrow map \\
    (ld\; \nabla\; (map\text{ getname }elem \Rightarrow name))\;getvalue\;(name, map).
    \end{array}

При этом используются функции:

\begin{array}{l}
    \text{Apply (}m\text{, elem) = image (elem,}m)\text{ elem }\Rightarrow, \\
    \text{Apply (}m\text{, elem) = getvalue (elem,}m)\text{ elem }\Rightarrow.
    \end{array}

Запись - это совокупность именованных полей. Этот тип соответствует типу record в языке Паскаль и struct в языке С++. В языке RAISE для записи определено два конструктора - record, shurt record, описание которых имеет вид

\begin{array}{l}
    type\; record\; id =\\
    type\; mk\_id\; (short _record\; id ) ::=\\
    destr\_id_{1} : type\_expr_{1} \leftrightarrow recon\_id\\
    \;\;\;\;\;\;\dots\\
    destr\_id_{n} : type\_expr_{n} \leftrightarrow recon\_id.
    \end{array}

Идентификатор mk\_id - это конструктор типа record, для которого задается деструктор destr\_id_{n} как функции получения значения компонентов записи.

Объединение - это конструктор union для объединения типов type id = id_{1} , id_{2} ,\dots, id_{n}, при котором тип id получает одно из значений в списке элементов.

Конструктор типа имеет вид

\text{type }id = id \text{\_from\_} id_{1}(id \text{\_to\_} id_{1:} id_{1})\;|\;\dots\;| \;
    id \text{\_from\_} id_{n}(id\text{\_to\_}idn_{:} id_{n}).

Операции над самим типом не определены в языке RAISE.

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

Александр Медов
Александр Медов

Здравствуйте,при покупке печатной формы сертификата,будут ли выданы обе печатные сторны?

Александр Медов
Александр Медов

Здравствуйте, прошел курс МБА Управление ИТ-проектами и направил документы на получение диплома почтой. Подскажите, сроки получения оного в бумажной форме?

:

Максим Гуринович
Максим Гуринович
Россия, г.Ноябрьск