- •Практическое занятие 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
- •Задачи повышенной сложности
Практикум 4-3
|
В программе из Практикума 4-1, посчитать количество увлечений у каждого студента |
Проверка принадлежности элемента списку
Создадим предикат, позволяющий проверить принадлежность элемента списку. Предикат будет иметь два аргумента: первый — искомое значение, второй — список, в котором производится поиск.
Построим данный предикат, опираясь на тот факт, что объект принадлежит списку, если он либо является первым элементом списка, либо элементом хвоста. Это может быть записано в виде двух предложений:
Рис. 4.6. Проверка вхождения элемента в список
Первое правило описывает ситуацию, когда элемент Х совпадает с головой списка.
Второе правило используется при неуспехе первого правила и описывает новый вызов первого правила, но уже с усеченным списком, в котором нет первого элемента и т.д. Если в списке заканчиваются элементы, остается пустой список, то второе правило оказывается неуспешным и процесс поиска заканчивается с результатом «ложь» (элемент не является членом списка).
Практикум 4-4
|
Добавьте в задачу об увлечениях студентов из Практикума 4-1 факты. Используя предикаты member и findall, получите список студентов, увлекающихся лыжами |
Слияние двух списков
Пусть L1 и L2 – две переменные, представляющие входные списки. L3 – выходной список, получаемый слиянием L1 и L2.
Рис. 4.7. Программа слияния двух списков
Первое правило этой процедуры выполняется, когда первый список пустой, второе работает в остальных случаях.
Рассмотрим использование этого предиката при следующем вызове:
conc ([1,2,3], [4,5],_).
Здесь первое правило сначала не работает, так как первый список не пустой.
Начинает работать второе правило, так как третий список пустой, к нему не применима операция деления на голову и хвост. Что касается первого списка, то он в процессе рекурсивных вызовов претерпевает деления на голову и хвост, и в конце концов становится пустым (его элементы попадают в стек)
conc ([ ],[4,5],_).
После этого срабатывает первое правило, и третий список инициализируется вторым:
conc ([ ],[4,5], [4,5]).
И, наконец, чтобы завершить рекурсивные вызовы, Пролог извлекает из стека (в обратном порядке) элементы первого списка и возвращает их, в соответствии с описанием второго варианта правила, в списки 1 и 3:
conc ([1,2,3], [4,5],[1,2,3,4,5]).
Программу для conc можно применить "в обратном направлении" - для разбиения списка на две части. Например, для цели:
Goal
conc(L1,L2,[a,b,c]).
получим результаты:
L1=[]
L2=[a,b,c]
L1=[a]
L2=[b,c]
L1=[a,b]
L2=[c]
L1=[a,b,c]
L2=[]
Практикум 4-5
|
1.Проверьте работу приведенной выше программы слияния двух списков с целями: а) conc ([1,2,3], [4,5], X). б) conc (X, [4,5], [1,2,3,4,5]).
2.Напишите программу, удаляющую из списка последние два элемента и формирующую новый список. Воспользуйтесь предикатом conc . 3.Напишите программу, удаляющую из списка первый и последний элемент.
|
Используя conc можно определить отношение принадлежности member следующим эквивалентным способом:
member (X,L) :- conc (_,[X|_],L).