Неполная спецификация функций.

advertisement
Лекция
12.11.2001
Недетерминизм и недоспецификация
Недоспецификация- неоднозначное определение понятий.
Неполная спецификация констант.
Пример.
value x : Int,
y : Int :- y ~ = 0
Мы не знаем, чему равна x, но знаем лишь, что она целого типа.
Мы знаем, что y целого типа и неравна 0, но какая она конкретно – не знаем.
Чтобы дополнить спецификацию, необходимо :
1. Добавить инициализацию
value x : Int = 10
2. Дописать аксиомы
value x : Int
axiom x = 10 is true
Неполная спецификация функций.
Пример
value f : IntInt
axiom forall x : Int :- f(x) > x
Мы наложили ограничение на функцию, чтобы результат был больше входного
аргумента, однако, как выглядит сама функция, мы не знаем, у нас для этого
недостаточно информации.
С другой стороны, на верхних уровнях спецификации мы не знаем, как будут
выглядеть эти функции, поэтому оставляем их недоспецифицированными, а
затем на этапах детализации, мы вернемся к их уточнению, если такие действия
потребуются.
Недетерминированная спецификация констант.
А как вообще мы можем написать недетеринированное выражение(оно в разные
моменты времени может принимать разные значения, то есть, в выполняемой
программе первый раз выражение может принять одно значение, а во второй раз
–другое, а может случиться так, что все время оно принимает одно и то же
значение. Заметим, что выбор не идет случайным образом )
Мы пользуемся оператором недетерминированного выбора.
value x : Int = 1 |^| 2 |^| 3
(x принимает значение либо 1, либо 2, либо 3)
Но что же это за константа, которая может принимать разные значения?
Это бессмысленная запись является ошибочной. Так писать нельзя. Не
существует недетерминированной спецификации констант!!
Недетерминированная спецификация функций.
Такая спецификация действительно существует.
Однако, следующий фрагмент программы является ошибкой :
f : IntInt
f(x) is 1 |^| 2 |^| 3
Функция f тотальная(total). Это значит, что она осуществляет однозначное
отображение XY .Любому элементу x из X соответствует только один
элемент y из Y. По аргументу x однозначно определен результат функции.
Вычисление нетотальной функции в разные моменты времени приводит к
различным результатам, что невозможно для тотальной функции.
Итак, недетерминированными могут быть лишь частично вычислимые
функции(partial).
f : Int -~->Int
f(x) is 1 |^| 2 |^| 3
Такая спецификация может использоваться в распараллеливании программ.
Недетерминизм состоит в том, что используется то значение, которое появится
первым. А если мы сами не хотим вводить в спецификацию недетерминизм?
Иногда он появляется помимо нашего желания.
Let и case – выражения.
Замечание. В языках программирования case – это оператор, а в RSL конструкция.
Let-выражения вводят новые имена, создают блок, в котором эти имена и видны
до конца блока. В теле let эти имена – value.
Существует понятие local variables, связанное с локальными переменными, но
это отлично от локальных имен в let !
Две разновидности let :
1 Explicit форма вводит новые имена и задает значения
let x : Int = 3 in
expr
end
2 Implicit форма let похожа на недоспецификацию. Вводит новые имена и лишь
накладывает ограничения на их типы.
let x : Nat :- x < 3 in
expression
end
Такие выражения не имеет смысла использовать в выражениях, но как часть
аксиомы- очень даже удобно.
Case – выражение.
Рассмотрим спецификацию функции reverse
value reverse Int-list  Int-list
reverse(lst) is
case lst of
<> <>
< i > ^ <lst>  reverse(lst) ^ i
end
Что есть результат вычисления выражения case? Это конструкция,
формирующая блок, возвращающий значение последнего выражения в этом
блоке.
В качестве выбора (например, в функции reverse это <i>) служат шаблоны
подстановки(binding)
Такие шаблоны заменяют конструкцию if(let…), мы вместо нее пишем шаблон,
в котором в определенных местах производим поименование.
В case нет break. Каждый раз вычисляется одна ветвь(если и нет break, то
вычисление само по “нижним” веткам не идет).
case expr of
pattern_1  expr_1
pattern_n  expr_n
end
Нет явного слова default, но есть шаблон подстановки, под который подходит
все, что угодно.
Имеется 6 видов шаблонов подстановки. (pattern)
1. Литеральный (просто его можно подставить без введения новых имен)
2. Wildcard ( _ ) – это и есть шаблон, заменяющий default
Пример. Числа Фибоначчи.
type Nat1 = {|n : Nat :- n > 0|}
value fib: Nat1  Nat1
fib(n) is
case n of
11
2 1
_fib(n-2) + fib(n-1)
end
3.Списочный (в функции reverse использован именно такой)
Замечание. Можно не только разорвать голову и хвост, но и выделить,
например, и второй элемент(a фактически столько элементов списка, сколько
необходимо ) <i1,i2,i3 ><i1> ^ lst1 ^ <i2>
4.Product patterns. Шаблоны декартового произведения.
Пример
Value ex_or Bool><BoolBool
ex_or(b1,b2) is
case(b1,b2) of
(true,false)true
(false,true)true
_
false
end
Реализована функция “исключающее или”
5. Name pattern(именованный шаблон)
Пример. type Color = = black | white
6. Record pattern (шаблон-“структура”)
Пример. type List = = empty | add(head : Color, tail : List)
Мы ввели функцию-конструктор, работающую со списком.
value invert : List  List
invert(l) is
case l of
Обращает цвет
empty  empty
add(i,l1)add(invert(i), invert(l1))
end
Обращает список
value invert : Color  Color
invert(l) is
case l of
white black
black white
end
Замечание. Функции invert в параметрах add() –разные, так как имеют
различную сигнатуру. Empty – это не литерал, а именованный шаблон(смотрите
определение типа List)
Перепишем функцию инвертиования списка по-другому.
value rev_inv : Color_List Color_List
rev_inv(l) is
case l of
<> <>
< = black> ^ l1 rev_inv(l1) ^ <white>
< = white> ^ l1 rev_inv(l1) ^ <black>
end
equality pattern- внутренний
нельзя использовать без =
Тем самым пишем обращения
к элементам функции без
использования invert()
В Let –выражениях используются не все паттерны.
Явные : let binding = expr in expr end
Здесь в отличии от case нет выбора, если не подошло выражение в Let-pattern, то
неудача применения выражения, то появился недетерминизм. Тут в теле let
вводятся имена, и чему они равны.
Неявные : let typing in expr end
Только введение имен. Ограничение типов тоже влечет недетерминизм, если
pattern не удовлетворен.
Пример.
let x : Nat :- x < 3 in x end
Результат вычисления этого выражения неопределен.
Download