- •1. Введение в декларативные языки.
- •Прозрачность по ссылкам.
- •Логическое программирование
- •Правила
- •Примеры
- •Рекурсивные определения
- •Литература
- •Синтаксис пролога.
- •Структуры
- •Предикаты
- •Семантика пролога
- •Как происходит сопоставление
- •Алгоритм Эрбрана
- •Алгоритм вычисления целей(работы пролог машины).
- •Процедурный смысл правил
- •Использование списков и
- •Использование накапливающего параметра(прием)
- •Операторная запись
- •Управление перебором
- •Алгоритмы сортировки
- •1 Пузырьковая сортировка
- •Сортировка вставками
- •Быстрая сортировка.
- •Использование предикатов, анализирующих типы или структуру термов
- •Применение подстановки к структурированному терму
- •Недетерминированное программирование
- •Метод «породить и проверить»
- •Алгоритм сортировки
- •Программирование второго порядка
- •Рассмотрим, как работать с базой данный
- •Поиск в глубину
- •Темы кр
- •Использование формальных языков
- •Недетерминированный конечный автомат
- •Ввод и вывод
- •Рассмотрим ввод вывод алфавитно – цифровых символов
- •Функциональное программирование
- •Базовый язык
- •Рекурсивное определение функций
- •Функции высших порядков
- •Отображение списков
- •Декартово произведение множеств
- •Композиция функций.
- •Бесконечные списки
- •Рассмотрим как можно исп беск списки.
- •Метод породить и проверить
- •Сети связанных процессов
- •Определение ф чисел фибоначи
- •Задача хэмминга
- •Решето Эратосфена
- •Язык типов
- •Рассмотрим алгебраические типы данных.
- •Деревья – рекурсивные типы данных
- •Сделать дерево плоским
- •Удаление элемента дерева
- •Извлечение самого правого элемента
- •Функция форматирования числа
- •Законы функциональных программ
- •Наиболее важные законы функц программ доказываются по индукции
- •Закон map через foldr
- •Закон: композиция
- •Коммутативна
- •Дистрибутивность map относительно композиции:
- •Преобразование программ
- •Пример1
- •Стратегия для композиции
- •Приведение рекурсивной формы к итеративной форме
- •Введение в лямбда исчисление
- •Синтаксис лямбда исчисления
- •Множество связанных переменных
- •Множество свободных переменных
- •Подстановка
- •Конфликт имен(захват переменных)
- •Преобразование термов
- •Вторая теорема Черча – Россера “Теорема о стандартизации”
- •Комбинатор y
- •Вычислим fact 3
- •Вычислим fact 0
- •(Рассказ про y комбинатор – сразу зачёт)
Процедурный смысл правил
Процедурный смысл правила p :- p1,p2,…pn, определяет порядок обработки целей: для достижения цели p нужно достичь последовательно подцели p1,p2,…pn.
Пример. Отношение мать.
Mother (X,Y) :-
Rod(X,Y),
Fm(X).
Т.е. правило – это процедура с параметрами, а в теле одни вызовы процедур.
Мы можем рассматривать вопрос как вызов процедуры.
P(t1c,t2c,tnc)
Правило – процедура
P(t1r,t2r,…..tnr) :-
P1(…),
P1(…),
Pm(…),
Передача параметров в процедуру идет на основе сопоставления.
После того, как была вызвана процедура, то вызываем p1,,..p2,…pn.
Из лабы 2, как работает
Call Exit
n(x,y) :- p(x,y).
n(x,y) :- p(z,x),
n(z,y).
Fail Redo
Использование списков и
По слайдам.
Важное свойство списка – его легко разделить на первый элемент и оставшуюся часть списка.
Обозначение списка используя переменные [H | T] –
H1, H2 – несколько первых элементов…
2 списка сопоставимы, если сопоставимы их соответствующие элементы.
{H/a, T[b,c,d]}
Получим {H1/a, H2/b, T/[c,d]}
Рассмотрим несколько функций, обр список…
Т.к. список это структура рекурсивна, то и алгоритмы, которые работают со списками будут рекурсивные.
1) принадлежность элемента списку
Надо определить предикат…
Базовый случай, если заданный списка, то предикат истинен.
Общий случай…..
Если элемент принадлежит хвосту списка….
Сцепление списков
Базовый случай. если первый список пуст, то результат совпадает со вторым списком.
Общий случай работает…в противном…когда первый не пуст….. Результатом будет список с головой как у первого списка, а хвостом полученным сцеплением хвоста списка со вторым списком.
Удаление эелемента из списка….
Delete1(X,[X|Xs], Xs).
Delete1(X, [Y|Ys], [Y|L]
3й аргумент результат…
Базовый случай – если удаляемый эелемент совпадает с головой списка то результат будет хвост списка. В общем случае результат имеет голову такую же как и у исходного списка, а хвост – результат удаления из хвоста списка… если такого элемента нет если в писке нет….
Рассмотрим то что для каждого предиката параметр может быть либо входным либо выходным……
Обратное исп предикатов
В прологе аргументы одного и того же предиката могут исп и как вхожные, и как выходные. Если вызываем…то такой предикат будет выходным….поскольку переменная должна конкретизироваться каким либо значением.
В рассмотренной нами процедуре appen1 мы предполагали, что первые 2 параметра входные, а 3й выходной. Но нашу процедуру append можно и использовать и по-другому. Выходным может быть первый параметр. В этом вызове указывается элемент C по которому нужно разделить список на 2 части.
Append1([], L,L).
Рассмотрим как наша цель выполняется…Надо учесть что первое правило применимо, если 2 и 3 списки сопоставимы. Поэтому в начале применимо 2ое правило, мы вызываем…. Список l’ становится конректнее…
Для этой цели применимо первое правило…
Использование накапливающего параметра(прием)
?- reverce1([a,b,c], X).
X=[c,b,a]
reverce1([X|Xs], Ys):- reverce1(Xs,Ys),
append(Zs, [X], Ys).
reverce1([], []).
Рассмотрим пример процедуры, которая реверсирует список.
Базовый случай – пустой список.
А в общем случае мы можем обратиться к реверсированному хвосту,..
Которому в конец добавляется одноэлементный список, содержащий голову исходного списка.
….на каждом шаге рекурсии формируемый значение список строится заново процедурой append.
Эту процедуру можно было бы оптимизировать, сделать более эффективной если была бы возможность объявления локальной переменной в процедуре… с этой переменной можно связать стек, в который бы заносились последовательно головы исходного списка и когда исходный список станет пустым то можно просто выдать готовый результат. Такую переменную можно смоделировать, добавив в процедуру еще один параметр, он играет роль локальной переменной
Опишем reverse2
Две процедуры reverse2, арности 2 и арности 3.
Reverse2/2 reverse2/3
………Это как раз параметр который будет работать как стек, будет накапливать результат, он еще называется накапливающим параметром……….. В определении процедуры reverse2/3 он называется Acc(accumulator), накапливает значение……… Если исходный список имеет голову и хвост Xs то надо реверсировать хвост а голову занести в накапливающий параметр……………
Базовый случай reverse2 ([], acc, acc).
Лекция 3.03.12
Есть числовые константы, их можно ключать в структуры. В прологе уже есть встроенные структуры
+/2
-/2
*/2
….
Так с помощью тих структур можно предсталвлять ариф.выражения.
Возьмем факт expr(+(1, *(2,3))).
Если мы сделаем запрос
?- expr (X).
X = +(1, *(2,3))
На прологе можно описывать ариф. выраж, преобразовывать их, т.е. работать с ними как с обычными структурами.
Как быть если нужно получить значение этого выраж ? Для этого есть спец.встроенный предикат is. Он имеет инфиксную(между операндами) форму. Этот предикат вычисляет для выражения.
?- expr (X, Y is X).
X = +(1, *(2,3))
Y = 7
Вычисление выражения запускается при исп операции сравнения.
Есть встроенные операции для сравнения чисел:
X>Y,
X<Y,
X>=Y,
X =:=Y, (X и Y дают одинаковый результат)
X=Y, (сопоставимы)
X=\=Y (X и Y дают разные результаты)
+(1,2) =:= +(2,1)
True
+(1,2) =+(2,1)
False