Зачет >= 90 баллов Можете уже в следующий раз приходить с зачеткой >= 70 баллов Пришлите, пожалуйста, 3 темы не позже 10:00 10.12 1 Задача на листке про toStr toStr’ Empty s = 'e':s toStr’ (Node v l r) = let s1 = toStr’ r s s2 = toStr’ l s1 in 'n':v:s2 Задача на листке: записать эти правила, не используя явно строки s, s1, s2, c помощью операций над функциями toStr’ Empty = ('e':) toStr’ (Node v l r) = ('n':) . (v:) . toStr’ l . toStr’ r 2 Еще про >>= 3 return1 Хотим писать цепочки: Philip Wadler ff = findpos (>3) >>>= \x-> findpos (>x) >>>= \y -> return1 (x+y) Тип: return1 (x+y) список -> (значение, список) return1 значение -> список -> (значение, список) Итого return1 val xs = (val, xs) 4 Символьные вычисления 5 На чем мы остановились data Expr = Num Integer | Var String | Add Expr Expr | Mult Expr Expr eval eval eval eval (Num i) _ = i (Var name) env = getValue name env (Add x y) env = eval x n + eval y n (Mult x y) env = eval x n * eval y n getValue name env = head [v | (n, v) <- env, n == name] 6 Let Хотим добавить в Expr let конструкции Например, (let x = 10 in x*y) + 1 Add ( Let "x" (Num 10) (Mult (Var "x") (Var "y"))) (Num 1) data Expr = Num Integer | Var String | Add Expr Expr | Mult Expr Expr | Let String Expr Expr Вариант 1 eval (Let name (Num val) in_expr) env = eval in_expr ((name, val):env) Может быть и выражение eval (Let name expr in_expr) env = let val = eval expr env in eval in_expr ((name, val):env) 7 Когда вычислять? (Если мы хотим быть ленивыми) Когда вычислять let выражение? 1. При вычислении let Недостаток: Получается не лениво 2. Добавлять в env не вычисленное значение Недостаток: Будем вычислять значение несколько раз Но с этим мы бороться не будем, условно будет тут считать, что это нормально Еще проблема Что будет, если let выражение содержит переменные? 8 Связывание let x=5 in let y = x*x in let x = 10 in y+1 Что должно быть? 10*10 + 1 5*5+1 Чем лучше 5*5? Иначе получится, что y в разных местах имеет разные значения. См. referential transparency Мы проходили для этого специальное название: статическое связывание 9 Как это реализовать Как это реализовать? Запоминать в env: выражение + контекст контекст – env, в котором вычислять выражение Фактически это то, что мы называли замыкание Техническая проблема: получится, что env будет содержать тройки: (имя, выражение, env-для-этого-выражения) Но список не может содержать сам себя Выход: ввести вспомогательный тип, который создаст ‘прослойку’ между env и его элементом который тоже env Например, описать тип data Closure = Closure Expr [(String, Closure)] И это будет доп.задача, в субботу 10 LetFunc – напоминание постановки задачи data Expr = Num Integer | Var String | Add Expr Expr | Mult Expr Expr | Let String Integer Expr | LetFunc String String Expr Expr | Call String Expr Пример вызова: eval (LetFunc "F" "X" (Mult (Var "X") (Var "X")) (Add (Num 1) (Call "F" (Num 5)))) [] [] 11 LetFunc - решение eval (LetFunc name param body expr) env funcEnv = eval expr env ((name, (param, body)):funcEnv) (param, body) – что-то вроде лямбда выражения eval (Call name expr) env funcEnv = let (param, body) = getFuncValue name funcEnv paramValue = eval expr env funcEnv in eval body ((param, paramValue):env) funcEnv Недостаток: тоже так не получается статическое связывание 12 Лямбда-исчисление 13 Числа Черча - напоминание \f \f \f \f \ f x -> … x x x x -> -> -> -> x fx f (f x) f (f (f x)) 0 1 2 3 14 toInt Число Черча – машинка, которая повторяет данное действие данное число раз (начиная с данного значения) toInt chNum = chNum (+1) 0 toInt (\f x -> f (f (f x))) (\f x -> f (f (f x))) (+1) 0 (+1) ((+1) ((+1) 0)) 3 15 add, inc add chNum1 chNum2 add chNum1 chNum2 = \f x -> let x1 = chNum1 f x x2 = chNum2 f x1 in x2 inc inc chNum = \f x -> let x1 = chNum f x in f x1 или короче inc chNum = \f x -> f (chNum f x) или короче add chNum1 chNum2 = \ f x -> chNum2 f (chNum1 f x) 16 dec – подсказка, как это можно сделать с парами Идея 1: используем пары Взять (0,0) Повторить n раз: (a, b) -> (inc a, a) Получится: (n, предыдущее перед n) Пример для 3: (0,0) (1,0) (2,1) (3,2) Под 0, n, a, b имеются в виду соответствующие числа Черча "Повторить n раз" – это как раз то, что числа Черча умеют делать 17 dec – подсказка, как моделировать пары лямбда выражениями реализовать Идея 2: пары можно моделировать функциями Примерно так же, как мы функциями моделируем числа «Пара Черча» для a и b - \f -> f a b Например, пара Черча для 2 и 3: \f -> f 2 3 Создать пару: pair a b = \f -> f a b p = pair 2 3 функция, которой мы даем на вход фунцкию от двух переменных, и она ее вызывает p (+) 5 p (*) 6 Остается понять, что для пар Черча соответствует fst и snd И это будет еще одна доп.задача, в субботу 18 Редукции Что такое вычисление для чистого лямбда исчисления? Что-то вроде упрощения выражения Упрощаем выражение по данным правилам пока что-то можно упростить Правило по сути одно: бета-редукция Есть еще альфа-конверсия, гамма-редукция и эта-конверсия, но они менее важные Например: альфа-конверсия: связанные переменные можно переименовать. Например, \x f x – это то же, что \y f y 19 Бета-редукция (\ x (mult x x)) 5 mult 5 5 Бета-редукция (\ x expr1 ) expr2 expr1, в котором вместо всех вхождений x подставленно выражение expr2 Еще примеры: (\ x x) y y (\ x (x x)) y yy (Формулировка специально не совсем корректная, см. д.з.) 20 Более формально: что такое вычисление по Черчу. Существование нормальной формы Редекс – подвыражение, к которому можно применить бета- редукцию Нормальная форма – выражение, в котором нет редексов Вычисление по Черчу – это применение редукций, пока не получим нормальную форму Типичные вопросы в математике: существование единственность Всегда ли существует нормальная форма? Нет. Например: (\x x x) (\x x x) (\x x x) (\x x x) … и так до бесконечности 21 Единственность нормальной формы. Конфлюентность Верно ли, что если нормальная форма существует, то она единственна? Определение: Выражение A редуцируемо к B, если B можно получить из A применением некоторого количества редукций (может быть, нулевого количества) Определение: Редукции обладают свойстом конфлюентности, если для любого выражения A: Если A редуцируемо к выражению B и в то же время A редуцируемо к выражению С то существует такое выражение D, что B редуцируемо к В и С редуцируемо к D. То есть, в частности, любое выражение редуцируемо к самому себе confluent сливающийся 22 Конфлюентность - продолжение Теорема (Черч, Россер) (не очень простая): чистое лямбдаисчисление обладает свойством конфлюентности Теорема (очень простая): Если у лямбда выражения существует нормальная форма, то она единственна Будет в д.з. 23 Порядок вычислений Значит, порядок редукций вообще не важен? Все-таки важен Может получиться, что при одном порядке вычислений мы получаем нормальную форму, а при другом – не получаем (зацикливаемся) 24 Нормальный и аппликативный порядок Обычно рассматривают такие порядки редукций: Аппликативный Каждый раз берем тот редекс, который расположен глубже всего (в нем нет других редексов) Нормальный Каждый раз берем самый внешний редекс, который не содержится ни в каком другом редексе Замечательное свойство: Если есть нормальная форма, то нормальный порядок обязательно к ней придет Д.з.: Привести пример выражения, для которого при нормальном и аппликативном порядке получаются разные результаты 25 Оператор неподвижной точки На занятии мы говорили про то, что такое оператор неподвижной точки, но, пожалуй, лучше мы это в следующий раз еще повторим 26