Лекция 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 : IntInt axiom forall x : Int :- f(x) > x Мы наложили ограничение на функцию, чтобы результат был больше входного аргумента, однако, как выглядит сама функция, мы не знаем, у нас для этого недостаточно информации. С другой стороны, на верхних уровнях спецификации мы не знаем, как будут выглядеть эти функции, поэтому оставляем их недоспецифицированными, а затем на этапах детализации, мы вернемся к их уточнению, если такие действия потребуются. Недетерминированная спецификация констант. А как вообще мы можем написать недетеринированное выражение(оно в разные моменты времени может принимать разные значения, то есть, в выполняемой программе первый раз выражение может принять одно значение, а во второй раз –другое, а может случиться так, что все время оно принимает одно и то же значение. Заметим, что выбор не идет случайным образом ) Мы пользуемся оператором недетерминированного выбора. value x : Int = 1 |^| 2 |^| 3 (x принимает значение либо 1, либо 2, либо 3) Но что же это за константа, которая может принимать разные значения? Это бессмысленная запись является ошибочной. Так писать нельзя. Не существует недетерминированной спецификации констант!! Недетерминированная спецификация функций. Такая спецификация действительно существует. Однако, следующий фрагмент программы является ошибкой : f : IntInt f(x) is 1 |^| 2 |^| 3 Функция f тотальная(total). Это значит, что она осуществляет однозначное отображение XY .Любому элементу 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 11 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><BoolBool 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 Результат вычисления этого выражения неопределен.