• скачать файл

Лекция 22. 09. 04 Темы: Введение в язык rsl

с. 1
Лекция 22.09.04
Темы:


  1. Введение в язык RSL.

  2. Введение в метод RAISE методологии.

Мы начинаем введение в RAISE с изучения языка спецификации, который принят в этой методологии, – RSL (RAISE Specification Language). Язык RSL не слишком сильно отличается от традиционных языков программирования. Более того, он похож на язык Ада начала 80-х, то есть без объектно-ориентированных возможностей.

Заметим, что знакомство с RSL не является главной целью курса. Языков спецификаций немало, и нельзя указать на самый лучший из них. Нам RSL подходит по той причине, что он достаточно мощный и одновременно очень экономный. Цель проекта RAISE (Rigorous Approach to Industrial Software Engineering) состояла, в частности, в том, чтобы в максимальной степени ограничить возможности языка спецификаций для упрощения внедрения методологии в реальную практику промышленного программирования. Таким образом, RSL – это не цель, а средство для технологии разработки ПО с использованием формальных методов.

Первые лекции по RSL будут вполне традиционны. Данная лекция посвящена базовым типам RSL, логике и простейшим составным структурам данных: декартовым произведениям и множествам.

RSL – язык спецификаций, поэтому в нем есть только описания.

Описания RSL:



  • типы

  • значения

  • переменные

  • каналы

  • модули (схемы, объекты)

Ключевые слова:

  • type

  • value

  • variable

  • channel

  • scheme, object



Примеры



type

my_type,


my_type1=Nat-set x Real

value

/* определение констант и функций */

const: my_type,

const1: Nat := 10


/* можно в одном месте только объявить константу */

value

const: Nat

/* а в другом месте определить */

axiom

const is 10


Описание функций
Func: тип_входных_параметров -> тип_результата

или


/* частично вычислимая функция */

Func: тип_входных_параметров -~-> тип_результата


Семантику функции можно описать либо вместе с объявлением, либо вынести в аксиомы.
value

func: Real -~-> Real

func (a) is 1.0/ a

pre a ~= 0.0 /* предусловие на входной параметр */


Базовые типы языка


  • Bool {true, false}

  • Nat <. 0, 1, 2, ... .>

  • Int <. ... –1, 0, 1, ... .>

  • Real ... 0.0 ...

  • Char 'a', 'A', ...

  • Text "abc"

  • <никакой тип> Unit

В RSL 6 базовых типов, не считая Unit. Unit говорит о том, что на данном месте (например, при описании формальных параметров функции или при описании результатов функции) вообще ничего нет – нет никакого параметра или нет никакого явного результата.

Типы Nat, Int и Real в RSL соответствуют математическим понятиям «натуральное», «целое» и «действительное» число, и все вычисления с ними проводятся без погрешностей. В языках программирования это не так, там значения этих типов ограничены сверху и снизу, и действительные числа представлены с ограниченной точностью.

Коротко о других описаниях языка RSL:


  • Модули. Служат для разбивки большой спецификации на отдельные части.

  • Каналы. Потребуются при рассмотрении параллельных асинхронных систем.

  • Переменные. Они есть во всех языках программирования, но языки спецификаций пытаются от них избавиться. Если в языке нет переменных, то в принципе не может быть побочного эффекта.


Логика в RSL
Особенности RSL-логики:

  • она короткая

  • отсутствуют ситуации, когда нечто не удается вычислить

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

Значение chaos есть не только в булевском типе, но и во всех остальных. Таблицы значений булевых функций:




Λ

true

false

chaos

true

true

false

chaos

false

false

false

false

chaos

chaos

chaos

chaos




V

true

false

chaos

true

true

true

true

false

true

false

chaos

chaos

chaos

chaos

chaos




=>

true

false

chaos

true

true

false

chaos

false

true

true

true

chaos

chaos

chaos

chaos




=

true

false

chaos

true

true

false

chaos

false

false

true

chaos

chaos

chaos

chaos

chaos




is

true

false

chaos

true

true

false

false

false

false

true

false

chaos

false

false

true



~

true

false

chaos




false

true

chaos

Рассмотрим операцию тождество (≡):






true

false

chaos

true

true

false

false

false

false

true

false

chaos

false

false

chaos

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



Декартово произведение

Рассмотрим первый составной тип – декартово произведение.



Пример



type

T = T0 x T1 x … x TN


При описании составного типа можно использовать комбинатор x. Слева и справа от знака могут стоять различные типовые выражения. Построить значение такого типа можно таким образом:

g: ( x, 10, f(y), …)


Мы написали обращение к константе или переменной (x какого-то типа, литеральное значение либо натурального, либо целого типа, функция возвращает значение определенного типа). Результатом такого вычисления будет n-ка значений, возможно разных типов.

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


Множества
type

ST1 = T1-set

ST2 = {|s: ST1 • (card s < maxset)|}
Т – произвольное типовое выражение. ST1 – новый тип данных, элементы которого являются подмножествами типа Т. ST2 – также новый тип данных.

Литералы и агрегаты:



  • {1,2,3}

  • {}

  • {x: Text • x(1) = ‘a’}

Круглые (хитрые) скобочки – это задание агрегатных значений для подмножеств. Результатом вычисления таких скобок является какое-то подмножество. В случае ST2 значениями будут элементы типа Т. В данном случае мы ограничены максимальным значением множества.

сard – встроенная функция, определенная над всеми множествами, вычисляющая количество элементов в них. Различают конечные и бесконечные множества. Множество неупорядочено, и в нем нет повторяющихся элементов.

{1,2,3,1} – в этом множестве три элемента.


Встроенные операции над множествами


  • inter

  • isin Î

  • union È

  • << Ì

  • <<= Í

  • >> É

  • >>= Ê

  • card число элементов в множестве

По определению card({}) = 0



Пример


Напишем спецификацию базы данных. В этом примере используются особенности языка, которые были рассмотрены выше.
SET-DATABASE =

class

type

Record = Key >< Data,

Database = {| rs: Record-set • is_wf_Database(rs) |},

Key, Data



value

is_wf_Database: Record-set -> Bool

is_wf_Database(rs) is ("k: Key, d1,d2: Data • ((k,d1) isin rs /\ (k,d2) isin rs) => d1 = d2),

empty: Database is {},

insert : Key >< Data >< Database -> Database

insert(k,d,db) is remove(k,db) union {(k,d)},

remove: Key >< Database -> Database

remove(k,db) is db \ {(k,d) | d : Data • true},


defined: Key >< Database -> Bool

defined(k,db) is ($ d : Data. (k.d) Î db),


lookup: Key >< Database -~-> Data

lookup(k,db) as d post (k,d) Îdb pre defined(k,db)



end

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

Пример: разработка системы управления запуском баллистических спутников.



  1. Провести тестовые проверки на стартовой установке.

  2. Если все проверки дали положительный результат, начать пуск.

  3. Когда корабль поднимется на орбиту, запустить программу его миссии.

  4. По завершении работы задачи запустить программу спуска.

Задача легко делится на части, и каждая из частей может разрабатываться параллельно. Для решения таких задач было разработано несколько языков проектирования, например PDL.

Домашнее задание


  1. Кто-то хочет продать Вам некоторый метод разработки программ. Разработать шкалу оценок таких методов.

  2. Попробовать, следуя этим критериям, улучшить метод пошаговой детализации за счет спецификаций и моделей, чтобы самим продавать этот метод.

с. 1