
- •1. Введение в декларативные языки.
- •Прозрачность по ссылкам.
- •Логическое программирование
- •Правила
- •Примеры
- •Рекурсивные определения
- •Литература
- •Синтаксис пролога.
- •Структуры
- •Предикаты
- •Семантика пролога
- •Как происходит сопоставление
- •Алгоритм Эрбрана
- •Алгоритм вычисления целей(работы пролог машины).
- •Процедурный смысл правил
- •Использование списков и
- •Использование накапливающего параметра(прием)
- •Операторная запись
- •Управление перебором
- •Алгоритмы сортировки
- •1 Пузырьковая сортировка
- •Сортировка вставками
- •Быстрая сортировка.
- •Использование предикатов, анализирующих типы или структуру термов
- •Применение подстановки к структурированному терму
- •Недетерминированное программирование
- •Метод «породить и проверить»
- •Алгоритм сортировки
- •Программирование второго порядка
- •Рассмотрим, как работать с базой данный
- •Поиск в глубину
- •Темы кр
- •Использование формальных языков
- •Недетерминированный конечный автомат
- •Ввод и вывод
- •Рассмотрим ввод вывод алфавитно – цифровых символов
- •Функциональное программирование
- •Базовый язык
- •Рекурсивное определение функций
- •Функции высших порядков
- •Отображение списков
- •Декартово произведение множеств
- •Композиция функций.
- •Бесконечные списки
- •Рассмотрим как можно исп беск списки.
- •Метод породить и проверить
- •Сети связанных процессов
- •Определение ф чисел фибоначи
- •Задача хэмминга
- •Решето Эратосфена
- •Язык типов
- •Рассмотрим алгебраические типы данных.
- •Деревья – рекурсивные типы данных
- •Сделать дерево плоским
- •Удаление элемента дерева
- •Извлечение самого правого элемента
- •Функция форматирования числа
- •Законы функциональных программ
- •Наиболее важные законы функц программ доказываются по индукции
- •Закон map через foldr
- •Закон: композиция
- •Коммутативна
- •Дистрибутивность map относительно композиции:
- •Преобразование программ
- •Пример1
- •Стратегия для композиции
- •Приведение рекурсивной формы к итеративной форме
- •Введение в лямбда исчисление
- •Синтаксис лямбда исчисления
- •Множество связанных переменных
- •Множество свободных переменных
- •Подстановка
- •Конфликт имен(захват переменных)
- •Преобразование термов
- •Вторая теорема Черча – Россера “Теорема о стандартизации”
- •Комбинатор y
- •Вычислим fact 3
- •Вычислим fact 0
- •(Рассказ про y комбинатор – сразу зачёт)
Недетерминированное программирование
Основная идея недетерминированного алгоритма – в программе задается несколько путей решения задачи, и будет выдан тот результат, к которому приведет первый удачный путь.
Есть лицо которое выбирает что дальше делать. Может случайны образом. Мы будем когда варианта анализируются последовательно.
Пролог пытается применять факты и правила по очереди, выполняет перебор и этот перебор моделирует недетерминированные вычисления.
Есть важный метод недетерминированного программирования:
Метод «породить и проверить»
find(X):-generate(X), test(X).
Метод можно представить в виде правила. Найти X. Generate генерирует данные, а предикат test проверят их на требование условия задачи. Таким методом можно написать алг сортировки…
Суть заключ в том что алг представляется в виде 2х процессов, один процесс порождает данные среди которых может быть результат, а другой – проверяет данные на соответствие условию задачи.
Алгоритм сортировки
sort(Xs,Ys):- permutation(Xs,Ys), ordered(Ys).
Sort сортируем список Xs, получаем список Ys.из списка Xs строим перестановку permutation, получаем Ys, далее проверяем, упорядочен ли список Ys. Самый неэффективный алгоритм сортировки. Сложность экспоненциальная. Но имея такой алгоритм, можно попытаться его оптимизировать. Проверку test нужно постараться внедрить в процесс генерации, и таким образом, сократить число генерируемых данных.
С помощью рекурсии можно написать алг для генерации перестановок. А если теперь будем сортировать хвост и вставлять элемент не нарушая порядок сортировки, то мы получим алгоритм сортировки вставками.
Пример решения задачи о 8 ферзях.
Условие. На шахм доске разместить 8 ферзей так, чтобы они не угрожали друг другу.
Число генерируемых вариантов можно сократить, если учесть что каждый ферзь должен занимать свой ряд. Нужно найти свою поз в этом ряду. Это значит что нам нужно список
Pattern – шаблон. Он содержит список мест place, мест 8. X фиксированы, Y будут меняться.
Этот список можно заполнять по очереди.
Если мы ставим первого ферзя в произ место по У, второго, чтобы он не конфл к первым,
solut([]).
solut([place(X,Y)|Rest]) :-
solut(Rest),
member(Y,[1,2,3,4,5,6,7,8]),
safe_place(place(X,Y), Rest).
pattern([place(1,Y1),place(2,Y2), place(3,Y3),place(4,Y4), place(5,Y5),place(6,Y6), place(7,Y7),place(8,Y8)]).
Лекция
Метод…который предполагает то алгоритм состоит из2х процессов, один порождает поток данных среди которых может быть результат, а процесс проверить проверяет , явл ли …
Задача о 8 ферзях…. Нужно заполнить шаблон который содержит список из 8 элементов, каждый элемент – позиция ферзя. Матрицу нужно заполнить…. Заполнять мы будем процедурой solut.
В общем программа будет работать след образом
safe_place(_,[]).
safe_place(place(X,Y),[place(Xi,Yi)|Rest]) :-
Y =\= Yi,
Y-Yi =\= Xi-X,
Y-Yi =\= X-Xi,
safe_place(place(X,Y),Rest).
?- pattern(S), solut(S).
Метод будет реал в проц solut.
Solut – рекур процедура, которая шаг за шагом заполняет список.
Базовый случай – если список пустой – то он явл решением. Пустой список возвр без изменений, там заполнить нечего.
Общий случай.список с головой place(x,y) и хвостом Rest явл решением (голова на половину заполнена, хвост не заполнен) , рекурсивный вызов хвост. Нужно заполнить ферзями хвост. А не весь список. Далее нужно выбрать позицию Y, member(Y,[1,…8]). Выбираем. Этот предикат порождает возможные позиции по У, он породитель варианта. ставит на 1 из 2х возможных леток в данном ряду ферзя. След предикат проверяет явл ли эта позиция безопасной. Он выполняет функцию проверить. У него 2 арг, новая позиция place x y, Rest – расставленные ферзи, которые не угрожают. Если позиция безопасна, то получили решение если позиция с угрозой – то возврат, запуск мембер, след позиция и т.д.
О safe_place. Реализуется рекурсией по списку. Мы должны проверить не угрожает ли вновь поставленный ферзь уже стоявшим на доске ферзям. Второй список мы рассматриваем рекурсивно. Если у нас список пустой – то позиция безопасна. 1го ферзя можем ставить куда захотим. Это базовый случай. Общий случай. Если список имеет голову place xi yi и далее rest, не пустой, естьголова, то мы должны проверить не угрожает ли поставленный ферзь …голове…
Диагнонали… =\=
Если это условие выполняется, то мы должны проверить безопасность нашего условия для хвоста списка.