- •1. Введение в декларативные языки.
- •Прозрачность по ссылкам.
- •Логическое программирование
- •Правила
- •Примеры
- •Рекурсивные определения
- •Литература
- •Синтаксис пролога.
- •Структуры
- •Предикаты
- •Семантика пролога
- •Как происходит сопоставление
- •Алгоритм Эрбрана
- •Алгоритм вычисления целей(работы пролог машины).
- •Процедурный смысл правил
- •Использование списков и
- •Использование накапливающего параметра(прием)
- •Операторная запись
- •Управление перебором
- •Алгоритмы сортировки
- •1 Пузырьковая сортировка
- •Сортировка вставками
- •Быстрая сортировка.
- •Использование предикатов, анализирующих типы или структуру термов
- •Применение подстановки к структурированному терму
- •Недетерминированное программирование
- •Метод «породить и проверить»
- •Алгоритм сортировки
- •Программирование второго порядка
- •Рассмотрим, как работать с базой данный
- •Поиск в глубину
- •Темы кр
- •Использование формальных языков
- •Недетерминированный конечный автомат
- •Ввод и вывод
- •Рассмотрим ввод вывод алфавитно – цифровых символов
- •Функциональное программирование
- •Базовый язык
- •Рекурсивное определение функций
- •Функции высших порядков
- •Отображение списков
- •Декартово произведение множеств
- •Композиция функций.
- •Бесконечные списки
- •Рассмотрим как можно исп беск списки.
- •Метод породить и проверить
- •Сети связанных процессов
- •Определение ф чисел фибоначи
- •Задача хэмминга
- •Решето Эратосфена
- •Язык типов
- •Рассмотрим алгебраические типы данных.
- •Деревья – рекурсивные типы данных
- •Сделать дерево плоским
- •Удаление элемента дерева
- •Извлечение самого правого элемента
- •Функция форматирования числа
- •Законы функциональных программ
- •Наиболее важные законы функц программ доказываются по индукции
- •Закон map через foldr
- •Закон: композиция
- •Коммутативна
- •Дистрибутивность map относительно композиции:
- •Преобразование программ
- •Пример1
- •Стратегия для композиции
- •Приведение рекурсивной формы к итеративной форме
- •Введение в лямбда исчисление
- •Синтаксис лямбда исчисления
- •Множество связанных переменных
- •Множество свободных переменных
- •Подстановка
- •Конфликт имен(захват переменных)
- •Преобразование термов
- •Вторая теорема Черча – Россера “Теорема о стандартизации”
- •Комбинатор y
- •Вычислим fact 3
- •Вычислим fact 0
- •(Рассказ про y комбинатор – сразу зачёт)
Деревья – рекурсивные типы данных
Data BinTree a = Empty
| Node (BinTree a) a (BinTree a)
(BinTree a) |
a |
(BinTree a) |
A
/ \
BinTree a BinTree a
Сделать дерево плоским
(вкладывает его в список)
flatten :: BinTree a -> [a]
flatten Empty = []
flatten (Node l v r) = flatten l ++
v : flatten r
можно поулчить более эффективный алгоритм, используя накапливающий параметр.
Применим накапливающий параметр
flatten’ :: BinTree a -> [a]
flatten’= inorder t []
where
inorder Empty xs = xs
inorder (Node l v r) xs =
inorder l (v : inorder r xs)
Удаление элемента дерева
delT y Empty = Empty
delT y (Node l x r)
| y>x = Node l x (delT y r)
| y<x = Node (delT y l) x r
| x==y = rebuild l r
Легко выполнить поиск по дереву, мы каждый раз можем решить если элемент не совпадает со знач в узле, то мы можем решить в левой или правой ветви искать. Дерево упорядочено.
Если X==Y то из двух деревьев нужно построить одно дерево (rebuild).
Объединение двух деревьев
15
7
20
3
12
18
25
9
15
В левом дереве найдем самое правое значение, удалим его и с этим значением в корне построим общее дерево.
rebuild Empty r = r
rebuild l r = (Node l’ x r)
where (l’ , x) = rightmost l
rightmost самый правый, берет дерево и наход самый правый элемент, возвр пару значений l’ оставш чатсь дерева и x удаленный элемент.
Извлечение самого правого элемента
Самый правый элемент:
rightmost (Node l x Empty) = (l,x)
rightmost (Node l x r) = (Node l x r’ , y)
where (r’,y) = rightmost r
append :: [a]->[a]->[a]
[1,2,3]
Такой вид полиморфизма(аппенд) слишком общий и он не подходит для случая перезагружаемых операторов.
(==) :: a->a->a нельзя, т.к. не все значения можно проверять на равенство.
Например, две функции проверить на равенство нельзя. Поэтому в таком случае нужно исп ограниченный полиморфизм. Нужно определить класс типов для которого есть метод проверки на равенство.
Название класса пишется с большой буквы, в нем надо указать типовую переменную обязательно, член класса тоже и методы присущие данному классу. Для каждого члена класса нужно определить конкретные методы.
*начинается с ключевого слова instance. Eq – класс, включает тип Int.
Int Eq встроенная ф, которая проверяет на равенство целочисленные значения.
Аналогично тип для вещественных чисел в классе.
След пример это проверка на равенство двух деревьев. Элементы хранящиеся в дереве должны принадлежать к классу Eq.
Пример, если еть множества заданные списками то их можно проверять на равенство написав для этого соответ методы.
Допустим,
data Set a = Set [a]
instance (Eq a)=>Eq(Set a) where
(Set []) == (Set [])= True // два пустых множества равны
(Set []) == (Set (x:xs))= False
(Set (x:xs)) == (Set []) = False
(Set xs) == (Set ys) = .. нужно проверить что каждый элемент из xs принадлежит ys и каждый элемент ys принадлежит xs.
В классах можно исп методы по умолчанию.
Эти методы можно переопределить если есть более эффективный метод или можно оставить метод в общем виде.
На слайде пример метода по умолчанию x/=y он реал как not (x==y)
Если в это определение класса добавить x==y = not (x/=y) (так и сделано в станд библ) то для включения элемента в класс достаточно определить любой из методов.
Наследование
class (Eq a) => Ord a where
(<), (<=), (>), (>=) :: a -> a -> Bool
min, max :: a -> a -> a
Eq для Ord – суперкласс,
Ord для Eq – подкласс.
Класс ord, элементы которого строго упорядочены и их можно проверят на больше меньше. Он явл подклассом класса Eq, он наследует проверку на равно и неравно.
Если пишем ф сортировки sort ord a => [a] -> [a]
Множественное наследование
class (Eq a, Show a) => C a where ...
Члены класса С наследуют операции из Eq и из Show .
Здесь приведен станд класс Show, в него входят те типы, значения которых можно представить в форме строки.
Есть еще класс Read, класс, элементы которого можно прочитать из строки.
data T …
…
Derioing Show
Строки
Строка – это список элементов типа Char;
[‘h’,’I’]
Более компактная запись:
“hi”.
a::Char
a = ‘x’
полезные функции
isSpace, isUpper, isLower, isAlpha, isDigit, isAlpanum:: Char->Bool
isSpace c = c == ‘ ‘ || c == ‘\t’ || c == ‘\n’
isUpper c = c >= ‘A’ && c <= ‘Z’
isLower c = c >= ‘a’ && c<= ‘z’
isAlpha c = isUpper c || isLower c
isDigit c = c >= ‘0’ && c <= ‘9’
isAlpanum c = isAlpha c || isDigit c
digitValue c =
| isDigit c = ord c – ord’0’
digitChar :: Int ->Char
digitChar n = chr (n+ord ‘0’)
toUpper:: Char ->Char
toUpper c
| isLower c
= chr (ord c – ord ‘a’ + ord ‘A’)
| otherwise = c
Форматирование числf
5 678
iterate (‘div’ 10)
[5678, 567, 56, 5, 0, 0, 0, …]
takeWhile (/=0)
[5678, 567, 56, 5]
map (`rem` 10)
[8,7,6,5]
reverse
[5,6,7,8]
map digitChar
“5678”
Здесь предполагается строгая последовательность действий.
Примерим оператор композиция функций
f :: a->b
g :: c -> a
(.) :: (a->b) -> (c->a) -> c -> b
(f . g) x = f (g x)
Те функции которые мы описали можно соединить в конвейер и получить ф, форматирующую число.
