- •Практическое занятие 1. Основы логического программирования
- •Основные парадигмы программирования
- •Понятие предиката
- •Унификация - процесс нахождения решения в Прологе
- •Факты и правила в Прологе
- •Пример программы на Прологе
- •Практикум 1-1
- •Практикум 1-2
- •Практикум 1-3
- •Контрольное задание 1 Исходные данные
- •Задание 1. Генеалогическое дерево
- •Задание 2. Представление правил
- •Практикум 2-1
- •Практикум 2-2
- •Стандартные предикаты
- •Ввод и вывод
- •Практикум 2-3
- •Описание арифметических операций
- •Практикум 2-4
- •Самостоятельные задания
- •Практическое занятие 3. Управление процессом решения задачи. Поиск с возвратом. Рекурсия
- •Использование предиката fail
- •Практикум 3-1
- •Использование предиката cut
- •Практикум 3-2
- •Использование рекурсии
- •Практикум 3-3
- •Практикум 3-4
- •Практикум 3-5
- •Практикум 3-6
- •Хвостовая рекурсия
- •[Head|Tail] [Голова|Хвост]
- •Практикум 4-1
- •Встроенный предикат findall
- •Практикум 4-2
- •Вычисление длины списка
- •Практикум 4-3
- •Проверка принадлежности элемента списку
- •Практикум 4-4
- •Слияние двух списков
- •Практикум 4-5
- •Вычисление суммы списка чисел
- •Практикум 4-6
- •Практикум 4-7
- •Удаление элемента из списка
- •Практикум 4-8
- •Получение элемента списка по его номеру
- •Практикум 4-9
- •Запись элементов списка в обратном порядке
- •Поиск максимального (минимального) элемента в списке
- •Практикум 4-10
- •Самостоятельные задания
- •Контрольное задание 2 Исходные данные
- •Практическое занятие 5. Решение логических задач
- •Пример простой логической задачи (два измерения)
- •Практикум 5-1
- •Практикум 5-2
- •Пример задачи (три измерения)
- •Практикум 5-3
- •Пример задачи (альтернативные высказывания)
- •Практикум 5-4
- •Практикум 5-5
- •Самостоятельные задания
- •Контрольное задание 3 Исходные данные
- •Задача 1
- •Задача 2
- •Задача 3
- •Задача 4
- •Задача 5
- •Задача 6
- •Задача 7
- •Задача 8
- •Задача 9
- •Задача 10
- •Задача 11
- •Задача 12
- •Задача 13
- •Задача 14
- •Задача 15
- •Задача 16
- •Задача 17
- •Задача 18
- •Задача 19
- •Задача 20
- •Задачи повышенной сложности
Унификация - процесс нахождения решения в Прологе
Процесс нахождения решения в Прологе заключается в сопоставлении предиката цели с предикатами базы знаний. Этот процесс называется унификацией. Пусть Пролог-системе предъявлена цель – найти бабушку и дедушку Святослава
? parent(X, святослав), parent(Y, X).
Пролог выделяет из нее первую подцель
parent(X, святослав),
и начинает сопоставлять ее с базой знаний - проводить унификацию.
Вначале сопоставляются первый предикат и подцель:
parent(рюрик, игорь) и parent(X, святослав),
Первый аргументрюрик сопоставляется с переменной X. Следует иметь в виду, что в Прологе различаются состояния переменных свободные (free) и связанные (bound).
Если обе переменные связаны, то при унификации происходит их сравнение. Если одна из них свободна, то происходит присвоение. Переприсвоение значений переменным не допускается.
Это существенно отличает Пролог от прочих языков.
Таким образом, переменной Х, которая пока является свободной, присваивается значение рюрик. После этого унифицируются вторые аргументы,
игорь и святослав. Поскольку это константы, и игорь ≠ святослав, то унификация предиката parent(рюрик, игорь) и подцели parent(X, святослав) заканчивается неудачей (fail).
Поскольку в базе знаний несколько экземпляров предиката parent, такой предикат называется неоднозначным (non-derministic). Если предикат один, то он называется однозначным (deterministic).
В случае неоднозначного предиката после неудачи выполняется откат - переход к следующему экземпляру предиката. При этом отменяется также присвоение значение переменным, если таковое имело место. Затем выполняется унификация предикатов
parent(ефанда, игорь) и parent(X, святослав).
Очевидно, что результат унификации будет тот же, неудача (fail). При откате на следующий предикат parent(ольга, святослав) картина будет иная: переменной X присвоится значение ольга (Х= ольга), а сопоставление вторых аргументов будет также выполнено: святослав = святослав. Таким образом, первая подцель окажется выполненной. Пролог запоминает, какой экземпляр предиката сработал и устанавливает на следующий предикат указатель отката,после чего перейдет ко второй подцели
parent(Y, X), где X = ольга, т.е.
Пролог ставит себе такую подцель:
parent(Y, ольга).
В поисках родителя Ольги Пролог снова начинает унифицировать этот предикат с начала базы знаний, начиная с parent(рюрик, игорь).
Нетрудно видеть, что на этот раз перебор всех предикатов закончится неудачей, т.е. подцель parent(Y, ольга) не дала положительного решения. В этом случае Пролог откатывается к предыдущей подцели (продвигается назад по списку подцелей) и пытается найти альтернативное решение для parent(X, святослав).При этом X опять становится свободной переменной, а Пролог возвращается к точке отката, то есть к предикату parent (игорь, святослав), сопоставляя его с подцелью parent(X, святослав).
Теперь X = игорь, святослав = святослав, первая цель истинна, указатель отката устанавливается на следующий предикат и опять выполняется переход ко второй подцели parent(Y, X), где X = игорь. Пролог снова начинает унификацию подцели parent(Y, игорь) c базой знаний, начиная с первого предиката. В первом предикате происходит унификация константы рюрик и свободной переменной Y.
Происходит присвоение Y= рюрик, затем сопоставляются вторые аргументы. Так как игорь = игорь, сопоставление завершается успешно.
Таким образом, одно решение найдено: Святослав является внуком Рюрика. Но Пролог продолжит поиск решений и сопоставляя подцель parent(Y, игорь) с предикатом parent(ефанда, игорь) найдет еще одно решение Y= ефанда.
Если необходимо найти только одно первое решение, то в Прологе используется восклицательный знак - отсечение (!) и цель выглядит следующим образом:
? parent(X, святослав), parent(Y, X), !.
Заметим, что неудача, которая постигла нас в поисках предков Святослава по материнской линии (Ольги), связана только с неполнотой базы знаний.
Итак, интерпретатор Пролога автоматически выполняет поиск решения. Механизм поиска реализован с помощью отката после неудачи.
Откат происходит на следующий экземпляр неоднозначного предиката. Выполнение программы на Прологе (резолюция цели) заключается в унификации цели с базой знаний.