- •Часть 1
- •1. Введение
- •2. Теоретические основы логического программирования.
- •2.1 Основные определения логики предикатов первого порядка
- •2.2 Стандартные формы представления формул исчисления предикатов.
- •3. Синтаксис языка программирования Пролог.
- •3.1. Основные элементы языка Пролог.
- •3.2. Представление клауз Хорна на языке Пролог. Факты. Правила. Вопросы.
- •3.2.1. Представление фактов в Пролог—программах.
- •3.2.2. Вопросы.
- •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.
- •Список литературы.
Унификация списков.
Списки представляют собой частный случай составных термов, и их унификация выполняется по общим правилам унификации составных термов. Списки успешно унифицируются, если они имеют одинаковую длину и соответствующие элементы этих списков попарно успешно сопоставимы.
Примеры унификации списков. 1) ? [a]=[]. No Списки имеют разную длину, унификация невозможна, так как [a] является списком из одного элемента, а [] пустой список.
? [L]=[a]. L=a yes
Списки имеют одинаковую длину, переменная L и терм а успешно унифицируются, и переменная L конкретизируется значением а.
? [L]=[a, b, с]. No
Списки имеют разную длину, переменная L обозначает один элемент списка, а другой операнд операции сопоставления является списком из трех элементов.
? [a|L]=[a, b, с]. L=[b,c]
Yes
Унификация успешна, списки имеют одинаковые первые элементы, переменная L, обозначающая хвост первого списка, успешно сопоставляется и конкретизируется значением [b,c], списком, который является хвостом второго списка.
Предикат list.
Предикат list(X) во многих версиях языка Пролог является предопределенным предикатом и предназначен для распознавания, является ли терм X списком или нет.
Декларативное описание этого отношения имеет следующий вид: Для любого X предикат list(X) будет истинен, если X пустой список или выделенный из Х хвост является списком.
Для того, чтобы проверить, является ли X списком, нужно разделить Х на голову и хвост и убедится, что хвост является списком. Процедура list(X) рекурсивна. При каждом рекурсивном обращении к процедуре list длина списка уменьшается, успешное завершение рекурсии наступит тогда, когда хвост очередного списка станет пустым. Правило для пустого списка является условием завершения рекурсии, так как пустой список есть список.
Процедура list имеет вид:
list(L):[]. list(L):L=[H|T],list(T). Переменная H во втором правиле может быть заменена анонимной переменной, так как ее значение не используется. Более компактная запись процедуры list имеет вид:
list([]). list([H|T]): list(T).
Рассмотрим пример запроса к процедуре list.
? list([1,2,3]).
ТР: list([1,2,3]).
Шаг 1: ТЦ: list([1,2,3]).
Пр1: []=[1,2,3]. неуспех
Пр2: [1|[2,3]]=[_|T1] T1=[2,3]
ТР: list([2,3]).
Шаг 2: ТЦ: list([2,3]).
Пр1: []=[2,3]. неуспех
Пр2: [2|[3]]=[_|T1] T1=[3]
ТР: list([3]).
Шаг 3: ТЦ: list([3]).
Пр1: []=[3]. неуспех
Пр2: [3|[]]=[_|T1] T1=[]
ТР: list([]).
Шаг 4: ТЦ: list([]).
Пр1: []=[]. успех
Переход на шаг 3. Истинность ТЦ на шаге 4 влечет истинность цели на шаге 3 list([3]).
Переход на шаг 2. Истинность ТЦ на шаге 3 влечет истинность цели на шаге 2 list([2,3]).
Переход на шаг 1. Истинность ТЦ на шаге 2 влечет истинность цели на шаге 1 list([1,2,3]).
ТР: успех.
Результат вычисления запроса list([1,2,3]. успех.
Типовые процедуры обработки списков на языке Пролог.
Предикат length.
Предикат определения длины списка length(L,N) является предопределенным предикатом во многих системах программирования на языке Пролог. Схема отношения этого предиката имеет вид:
length(<список>,<длина списка>).
Декларативное описание предиката length(L,N) формулируется следующим образом:
Предикат length(X, 0) будет истинным, если X пустой список, т.е. длина пустого списка равна нулю. Если список можно разделить на голову и хвост, то длина списка равна длине хвоста списка плюс 1.
Процедура length(L,N) состоит из двух правил:
length([],0).
length([_|T],N):length(T,N1),N is N1+1.
Рассмотрим пример запроса к процедуре length.
? length([1,2,3], N).
ТР: length([1,2,3], N).
Шаг 1: ТЦ: length([1,2,3], N).
Пр1: []=[1,2,3]. неуспех
Пр2: [1|[2,3]]=[_|T11] T11=[2,3]
ТР: length([2, 3], N11),N is N11+1.
Шаг 2: ТЦ: length([2, 3], N11).
Пр1: []=[2,3]. неуспех
Пр2: [2|[3]]=[_|T12] T12=[3]
ТР: length([3], N12),N11 is N12+1,N is N11+1.
Шаг 3: ТЦ: length([3]).
Пр1: []=[3]. неуспех
Пр2: [3|[]]=[_|T13] T13=[]
ТР: length([], N13),N12 is N13+ 1,N11 is N12+1,N is N11+1.
Шаг 3: ТЦ: length([], N13).
Пр1: []=[]. успех
{N13=0}
ТР: N12 is N13+ 1,N11 is N12+1,N is N11+1.
Шаг 4: ТЦ: N12 is 0+ 1.
{N12=1}
ТР: N11 is N12+1,N is N11+1.
Шаг 4: ТЦ: N11 is 1+ 1.
{N11=2}
ТР: N is N11+1.
Шаг 4: ТЦ: N is 2+ 1.
{N=2}
ТР: .
Успех.
Ответ: {N=2}