Лекция 15.10.2001 Метод RAISE Абстрактная модель аксиомы алгоритмы Реализационная модель Рассмотрим детализацию по шагам сверху вниз от абстрактной модели к конечному продукту реализации. Шаг 0 Именуются типы и операции. Функции. Для функций именуются параметры. Шаг 1 Записываем знания о сущностях в виде аксиом – абстрактных(алгебраических) спецификаций. Введем 2 термина. В RAISE между моделями различных уровней абстракции существует отношение одна реализует (implements) другую. Поэтому, чтобы подчеркнуть такое отношение, используем термин implementation. Refinement - это процесс перехода от одной абстрактной модели к другой. Шаг 2 Накладываем пред и постусловия на функции. Имплицитные спецификации. Уточнение подтипов. Замечание. Проверять конкретные алгоритмы на машине естественно просто по сравнению с проверкой аксиом. Каждая требует проверки выполнения большого числа операций(алгоритмов). А одну операцию(алгоритм) можно проверить. Шаг 3 Переход от неявных спецификаций к явным. Шаг 4 Перевод на некоторый целевой язык. Опциональный этап. Так как такая трансляция не является оптимальной. Результат такой трансляции может испольоваться как прототип системы. Он медленно работает, зато правильно(так как полностью удовлетворяет спецификации) Если он не нравится заказчику, то изменяем спецификацию и еще раз транслируем. Происходит уточнение прототипа. Но обычно спецификации используются для тестирования, документации. А реализация пишется “вручную” по прототипу. Алгебраическая спецификация Базы Данных. DataBase = class type Key, Data, Database value empty : Database (это конструктор БД(то есть их может быть много)? Или константа, определяющая одну БД. Различие важно лишь на этапе распараллеливания) Далее, функции работы с БД . 1-ый тип- генераторы. Результатом действия является модификация объекта либо его создание 2- ой тип- обсерверы. Функции поиска, извлечения знаний об объекте, проверки свойств объекта. Генераторы insert : Key><Data><Database Database добавить элемент в БД remove : Key><Data><Database Database удалить элемент из БД Обсерверы defined : Key ><Database Bool Существует ли такой ключ в БД lookup: Key ><Database -~-> Data Извлечь элемент из БД по ключу. Не по любому ключу можно извлечь данные, а по тому, который есть в БД. Замечание. Набор генераторов несколько избыточен. Можно обойтись без remove(). Так как можно построить БД из empty с помощью insert() Мы не стремимся к “чистоте” системы, а стремимся к удобству в ее использовании. Генераторы бывают 2 типов: 1 Те, которые создают множество объектов, образующих базис в своем пространстве 2 Те,которые “портят” это множество . Их называют модификаторами. В нашем примере – это remove(). Аксиомы связывают наборы функций. Какие операции писать на аксиомах? Надо выделить некие специальные логические группы? Будем писать аксиомы для пар операций. А какие пары выбрать из большого числа функций? Какова аксиома для insert() и empty? Будем создавать аксиомы по следующим принципам: 1. Для пар:обсервер с генератором. 2. Модификаторы не надо связывать с генераторами. 3. Правая часть аксиомы из 1. Не должна содержать генераторов(в частности констант). 4. Доказывать только наблюдаемые свойства. 5. Те свойства, которые не включают обсерверов, не рассматриваются, так как не являются наблюдаемыми. Напишем аксиомы. axiom : [defined_empty] forall k : Key :- defined(k, empty) is false [defined_insert] forall k,k1 : Key, d : Data, db : Database :- defined(k, insert(k1,d,db)) is k=k1 \/ defined(k,db) [defined_remove] forall k,k1 : Key, d : Data, db : Database :- defined(k, remove(k1,d,db)) is k~=k1 /\ defined(k,db) Когда пишем аксиомы с lookup(), должны помнить об условии, гарантирующем применение lookup() pre defined(k,db) Например писать аксиому forall k: Key :- lookup(empty) is pre defined(k,empty) это левая часть импликации, из которой и следует сама аксиома. Если pre = false, то pre=>axiom всегда true, писать такую аксиому не нужно. [lookup_insert] forall k,k1 : Key, d : Data, db : Database :- lookup(k, insert(k1,d,db)) is if (k=k1) then d else lookup(k,db) end pre defined(k,db) \/ k=k1 Первый дизъюнкт предусловия возникает как предусловие правой части аксиомы, то есть lookup(), выполнение второго дизъюнкта в pre не противоречит if в правой части аксиомы. Просто какая-то ветвь при соответствующих параметрах не выполнится. В правой части аксиомы нет генераторов. [lookup_remove] forall k,k1 : Key, d : Data, db : Database :- lookup(k, remove(k1,d,db)) is if (k~=k1) then lookup(k,db) end pre defined(k,db) \/ k=k1 end (class) Теперь построим implementation данной модели БД, уточняя ее(refinement) на основе представления данных как множества пар : (ключ,значение). SET_DATABASE= class type Key,Data, Record = Key >< Data Database = {|i1 : Record-set :- is_wf_database(Record-set)|} (функция is_wf_database проверяет, а правильно ли сформирована база данных. Это будет в том случае, если любому ключу соответсвует одно и только одно значение из БД) value is_wf_database : Record-set Bool is_wf_database(rs) is forall k : Key, forall d1,d2 : Data :- ((k,d1) isin rs /\ (k,d2) isin rs)=> d1=d2, empty : Database = {}, insert : Key><Data><Database Database добавить элемент в БД insert(k,d,db) is remove(k,db) union {(k,d)} remove : Key><Data><Database Database удалить элемент из БД remove(k,d,db) is db \ {(k,d) | d : Data :- true} (удалили все ключи k из БД) Напишем явное опеределение defined defined : Key ><Database Bool Существует ли такой ключ в БД defined(k,db) is (exists d : Data :- (k,d) isin db) Напишем неявное опеределение lookup lookup: Key ><Database -~-> Data Извлечь элемент из БД по ключу. lookup(k, db) as d post (k,d) isin db Такая запись не говорит, как мы получаем результат, но связывает результат работы функции со входными параметрами. Это все значения, которые по данному ключу отыщутся в БД, что и написано в теле lookup. End Чтоб проверить корректность нашей уточняющей модели, необходимо доказать справедливость аксиом абстрактной модели для нашей refinement модели. axiom [defined_empty] forall k : Key :- defined(k, empty) is false [all_deduction] правило дедукции defined(k,empty) is false [unfold_empty] раскрытие defined(k,{}) is false идентификаторов [unfold_defined] (exists d : Data :- (k,d) isin {}) is false [isin_empty] тождественное преобразование (exists d : Data :- false) is false [exists_introduction] преобразование квантора false is false [is_annihilation] переход по тождеству true Аналогично доказываются остальные аксиомы исходной модели. Техника такова, что необходимо вместо абстрактных функций в аксиоме подставить конкретные реализации их в модели и проверить, что результат будет таким же, как и в правой части аксиомы первоначальной модели.