- •Часть 1
- •1. Введение
- •2. Теоретические основы логического программирования.
- •2.1 Основные определения логики предикатов первого порядка
- •2.2 Стандартные формы представления формул исчисления предикатов.
- •3. Синтаксис языка программирования Пролог.
- •3.1. Основные элементы языка Пролог.
- •3.2.2. Вопросы.
- •3.2. Представление клауз Хорна на языке Пролог. Факты. Правила. Вопросы.
- •3.2.1. Представление фактов в Пролог—программах.
- •3.2.3. Правила.
- •3.2.4. Подстановки и примеры утверждений.
- •3.2.5. Пример Прологпрограммы.
- •4. Семантика языка программирования Пролог.
- •4.1 Декларативная и процедурная семантика программ на языке Пролог.
- •4.2. Вычислительная модель логической программы.
- •4.2.1. Унификация термов.
- •4.2.2. Общая схема согласования целевых утверждений.
- •4.2.3 Механизм поиска с возвратом.
- •5. Рекурсивное программирование на языке Пролог.
- •5.1 Рекурсивные правила.
- •5.2 Схема поиска решений в рекурсивных программах.
- •5.3. Списки и их представление на Прологе.
- •Основные определения.
- •Унификация списков.
- •Предикат list.
- •Типовые процедуры обработки списков на языке Пролог.
- •Предикат length.
- •5.4.2. Предикат member.
- •Предикат first.
- •Предикат last.
- •Предикат next.
- •Предикат append.
- •Предикат add.
- •Предикаты revers1 и revers2.
- •Предикат delete.
- •5.4.10. Предикат number_list.
- •5.4.11. Предикат sumlist.
- •5.4.12. Предикат delrepeat.
- •5.5 Множества и их представление на языке Пролог. Простые программы обработки множеств.
- •Основные определения.
- •Предикат unionset.
- •Пересечение множеств.
- •Разность множеств.
- •Определение подмножества.
- •5.5.6. Декартово произведение множеств.
- •Прологпрограммы сортировки списков.
- •Метод прямого выбора.
- •Метод вставки.
- •5.6.3. Метод перестановок.
- •6. Стандартные предикаты языка Пролог.
- •Арифметические предикаты.
- •6.2. Предикаты сравнения арифметических выражений и символьных термов.
- •6.3. Предикаты определения типов термов.
- •6.4. Примеры программ с использованием арифметических предикатов.
- •6.5. Предикаты вводавывода термов и символов.
- •6.5.1. Ввод/вывод термов.
- •6.5.2. Ввод/вывод символов.
- •6.6. Стандартные предикаты управления логическим выводом.
- •6.7. Стандартные предикаты обработки списков.
- •6.8. Стандартные предикаты обработки строк.
- •7. Система программирования Arity Prolog 5.0.
- •Описание среды программирования Arity Prolog 5.0.
- •Методические указания по лабораторным работам.
- •7.2.1. Лабораторная работа № 1. Простейшая программа на языке Пролог.
- •7.2.2. Лабораторная работа № 2. Использование арифметических операций и унификации арифметических выражений.
- •7.2.3. Лабораторная работа 3.1. Создание базы данных “Cессия” и запросов к этой базе данных на языке Пролог с использованием стандартного предиката fail.
- •Приложение 2. Варианты заданий по лабораторной работе 4.
- •Приложение 3. Варианты заданий по лабораторной работе 5.
- •Список литературы.
Предикаты revers1 и revers2.
Предикаты revers1 и revers2 являются предикатами обращения списков и определяют одно и то же отношение различными способами. Схема отношения этого предиката имеет вид:
revers(<список>,<список>).
Предикат revers(X,Y) истинен, если список Y содержит все элементы списка Х, которые записаны в списке Y в обратном порядке. Перестановку элементов списка в обратном порядке можно произвести путем многократного выполнения процедуры append.
Процедура revers определяется двумя способами:
простым обращением;
обращением с накоплением.
Простое обращение выполняется процедурой revers1, которая использует процедуру append (см. 5.4.5) и состоит из двух предложений:
revers1([],[]).
revers1([H|Xs],Zs):revers1(Xs,Ys), append(Ys,[H],Zs).
Декларативное определение предиката revers1 формулируется следующим образом:
обращенный пустой список есть пустой список;
если список Х можно разделить на голову Н и хвост Xs, то Zs есть обращенный список, если Ys обращенный хвост списка X, Zs получен путем присоединения к Ys головы Н списка X.
Рассмотрим пример запроса к процедуре revers1(X,Y).
? revers1([1,2,3],Zs).
ТР: revers1([1,2,3],Zs).
Шаг 1: ТЦ: revers1([1,2,3],Y).
Пр1: [1,2,3] не сопоставим [] неуспех
Пр2: revers1([1|[2,3]],Zs): revers1(Xs1,Ys1),append(Ys1,[1],Zs).
Xs1=[2,3]
ТР: revers1([2,3],Ys1),append(Ys1,[1],Zs).
Шаг 2: ТЦ: revers1([2,3],Ys1).
Пр1: [2,3] не сопоставим [] неуспех
Пр2: revers1([2|[3]],Ys1): revers1(Xs2,Ys2),append(Ys2,[2],Ys1).
где Xs2=[3].
ТР: revers1([3],Ys2),append(Ys2,[2],Zs).
Шаг 3: ТЦ: revers1([3],Ys2).
Пр1: [3] не сопоставим [] неуспех
Пр2: revers1([3|[]],Ys2):revers1(Xs3,Ys3),append(Ys3,[3],Ys2).
где Xs3=[].
ТР: revers1([],Ys3),append(Ys3,[3],Ys2).
Шаг 4: ТЦ: revers1([],Ys3).
Пр1: [] сопоставим [] успех
Получается подстановка {Ys3=[]}.
ТР: append(Ys3,[3],Ys2).
Шаг 5: ТЦ: append(Ys3,[3],Ys2).
Получается подстановка {Ys2=[3]}.
ТР: append(Ys2,[2],Ys1).
Шаг 6: ТЦ: append(Ys2,[2],Ys1).
Получается подстановка {Ys1=[3,2]}.
ТР: append(Ys1,[1],Zs).
Шаг 6: ТЦ: append(Ys1,[1],Zs).
Получается подстановка {Zs=[3,2,1]}.
ТР: .
Результат вычисления запроса: revers1([1,2,3],Zs). успех
при подстановке {Zs=[3,2,1]}.
Обращение списка с накоплением выполняется процедурой revers2, состоящей из трех предложений и содержит дополнительный предикат rev:
revers2(X,Y):rev(X,[],Y).
rev([],Y,Y).
rev([H|Xs],L,Y):rev(Xs,[H|L],Y).
В процедуре revers2 введен дополнительный предикат rev с тремя аргументамисписками, где первый аргумент исходный список, второй аргумент накапливающийся список, а третий аргумент результирующий, обращенный список.
Декларативное определение предиката rev формулируется следующим образом:
если первый аргумент есть пустой список, то второй и третий аргументы представляют собой один и тот же список;
первый аргумент непустой список [H|Хs], и его можно разделить на голову Н и хвост Xs; в этом случае применение предиката rev к списку [H|Хs] и накапливающемуся списку L равносильно применению предиката rev к хвосту списка Xs и списку [H|L]; при этом получается обращенный список Y.
Рассмотрим пример запроса к процедуре revers2(X,Y).
? revers2([1,2,3],Y).
ТР: revers2([1,2,3],Zs).
Шаг 1: ТЦ: revers2([1,2,3],Y).
Пр1: revers2([1,2,3],Y):rev([1,2,3],[],Y) успех
ТР: rev([1,2,3],[],Y).
Шаг 2: ТЦ: rev([1,2,3],[],Y).
Пр2: [1,2,3] не сопоставим [] неуспех
Пр3: rev([1|[2,3]],[],Y): rev(Xs2,[1|[]],Y).
где Xs2=[2,3].
ТР: rev([2,3],[1]],Y).
Шаг 3: ТЦ: rev([2,3],[1]],Y).
Пр2: [2,3] не сопоставим [] неуспех
Пр3: rev([2|[3]],[],Y): rev(Xs3,[2|[1]],Y).
где Xs3=[3].
ТР: rev([3],[2,1],Y).
Шаг 4: ТЦ: rev([3],[2,1],Y).
Пр2: [3] не сопоставим [] неуспех
Пр3: rev([3|[]],[2,1],Y): rev(Xs4,[3|[2,1]],Y).
где Xs4=[].
ТР: rev([],[3,2,1] ,Y).
Пр2: [] сопоставим [] успех
Получается подстановка {Y=[3,2,1]}
ТР: .
Истинность ТЦ на шаге 4 влечет истинность цели на шаге 3.
Истинность ТЦ на шаге 3 влечет истинность цели на шаге 2.
Истинность ТЦ на шаге 2 влечет истинность цели на шаге 1.
Результат вычисления запроса: revers2([1,2,3],Zs) успех при подстановке {Zs=[3,2,1]}.
