
- •127994, Москва, ул. Образцова, 15
- •2.Теоретические основы логическоого программирования
- •2.1.Логика высказываний и логика предикатов.
- •2.1.1.Формулы. Синтаксис и семантика формул.
- •2.1.2.Интерпретация формул в логике высказываний.
- •2.1.3.Интерпретация в логике предикатов первого порядка
- •2.1.4.Равносильность формул логики высказываний
- •2.1.5.Тождественная истинность формул логики высказываний
- •2.1.6.Равносильность формул логики первого порядка
- •2.1.7.Тождественная истинность, общезначимость, выполнимость, противоречивость формул логики предикатов
- •2.1.8.Рассуждения в логике высказываний (предикатов)
- •2.2.Метод резолюций
- •2.2.1.Метод резолюций в логике высказываний
- •2.2.2.Подстановка и унификация
- •2.2.3.Метод резолюций для логики первого порядка
- •2.2.4.Стратегии метода резолюций
- •2.3.Отношения и предикаты
- •3.Пролог- язык РекуРсивно-логического программирования
- •3.1.Пролог-история возникновения
- •3.2.Синтаксис языка пролог
- •3.3.Семантика языка пролог
- •3.4.Язык пролог и метод резолюций. Логическая интерпретация языка Пролог.
- •3.5.Работа в пролог-системе
- •3.6.Описание инфиксных операций
- •3.7.Списки в языке пролог
- •3.8.Арифметика в языке пролог
- •3.9.Отсечение и отрицание в языке пролог
- •3.10.Встроенные предикаты языка пролог
- •3.11.Работа с базой данных в языке пролог
- •3.12.Предикаты поиска
- •3.13.Решение головоломки на языке пролог(задача Эйнштейна)
- •4.Лабораторные работы по РекуРсивно-логическому программированию
- •4.1.Задание n1 Отношения между объектами. (на Прологе и Паскале)
- •4.1.1.Методические указания
- •4.1.2.Варианты
- •4.2.Задание n2. Работа со списками
- •4.2.1.Методические указания
- •4.2.2.Варианты
- •4.3.Задание n3. Разные задачи
- •4.3.1.Методические указания
- •4.3.2.Варианты
- •4.4.Содержание отчета
3.6.Описание инфиксных операций
Для записи арифметических операций в теории известны несколько форм представлений, а именно:
инфиксная (естественная, для некомпьютерных представлений) (например, (a+b)*c);
постфиксная (польская инверсная запись - ПОЛИЗ) (например, ab+c*), операция применяется к двум ближайшим предшествующим операндам;
префиксная (например, *+abc), операция применяется к двум ближайшим следующим операндам;
функциональная (например, *(+ (a,b),c)).
Разработаны алгоритмы для преобразований для различных систем из одной формы в другую. Нас будут далее интересовать инфиксная и функциональная формы записи. Первая – наиболее привычная для пользователя. Вторая - наиболее соответствует понятию «структура» в языке Пролог.
Инфиксная форма присуща не только арифметическим операциям. Так, например, можно определить атомы «имеет» и «поддерживает» в качестве инфиксных операторов, а затем записывать выражения вида: «питер имеет информацию» или «пол поддерживает стол», которые соответствуют следующим структурам: «имеет(питер, информацию)» и «поддерживает(пол, стол)». Далее мы увидим, что многие конструкции языка Пролог являются инфиксными формами некоторых структур.
Инфиксные выражения рассматриваются Прологом как еще один способ записи уже известных конструкций. Так, запись а + b, Пролог понимает, как +(а, b).
Для того, чтобы Пролог правильно воспринимал инфиксные операции программист должен их определить. Для этого служит особый вид предложений, которые иногда называют директивами. Определение операции должно появиться в программе раньше, чем выражение, ее использующее. Например, операцию «имеет» можно определить директивой, которая записывается как
:-ор(600, xfx, имеет).
Первый аргумент задает приоритет операции (600). Второй – «xfx» обозначает одну из разновидностей инфиксной операции. Общее правило использование приоритета состоит в том, что оператор с самым низким приоритетом расценивается как главный функтор (чем приоритет выше, тем его номер меньше). Если мы хотим, чтобы выражения, содержащие + и *, понимались в соответствии с обычными правилами, то + должен иметь более низкий приоритет, чем *.
Существуют три группы разновидностей операций, обозначаемые спецификаторами:
бинарные инфиксные операции трех типов: «xfx», «xfy», «yfx»,
унарные префиксные операции двух типов: «fx», «fy»,
унарные постфиксные операции двух типов: «хf», «yf».
Под «f» понимается инфиксная операция. Разницу между «x» и «y» поясним на примере. Выражение «а-b-с» для разных типов определения операции «-» понимается: для «xfx» - запись некорректна, для «xfy» - «а-(b-с)», для«yfx» - «(а-b)-с». Выражение «-- а» - для «fx» - запись некорректна, для «fy» - «-(- а)».
Определения операций не содержат описания каких-либо действий. Операции используются так же, как и функторы, только для объединения объектов в структуры и не вызывают действия над ними.
3.7.Списки в языке пролог
Список в Прологе- это последовательность, заключенная в квадратные скобки, составленная из произвольного числа элементов, разделенных запятыми например [a, b, c, d. e], [1, 15, 2, 101. 3], [энн, теннис, том, лыжи] и т.д.
Также как для арифметических выражений данное представление является внешним представлением стандартного прологовского объекта. Если список пустой, то он записывается как атом []. Если список не пустой, то он рассматривается как структура, состоящая из двух частей:
первый элемент, называемый головой списка;
остальная часть списка, называемая хвостом.
Например, для списка [a, b, c, d. e] a - это голова, а хвостом является список [b, c, d. e]. В общем случае, головой может быть любой прологовский объект; хвост же должен быть списком. Голова соединяется с хвостом при помощи специального функтора, который принято обозначать точкой «.».
Таким образом, список [a, b, c, d. e] может быть представлен как структура .(a, .(b, .(c, .(d, .(e, []))))).
Списки могут иметь неограниченный уровень вложенности. Например, список [[1, 2, 3], [b, [1, 3, 5], d], c, d] может быть представлен как структура .(.(1, .(2, .(3, []))), .(.(b, .(.(1, .(3, .(5, []))), .(d, []))), .(c, .(d, [])))).
В Прологе предусмотрено еще одно представления списка, а именно вертикальная черта "|", отделяющая голову от хвоста. Можно перечислить любое количество элементов списка, затем поставить символ "|", а после этого - список остальных элементов. Так, список [а, b, с] можно представить следующими различными способами: [а, b, с], [а | [b, с]], [a, b | [c]], [a, b, c | [ ]].
Пример 3.7.1. Принадлежность к списку
Отношение принадлежности «принадлежит( X, L)» (Х - объект, а L – список) формулируется словесно как «элемент Х встречается в L».
Определение предиката:
принадлежит(X, [X | Хвост ]).
принадлежит(X, [Голова | Хвост ]):-принадлежит(X, Хвост).
Словесная интерпретация:
Если элемент является головой списка, то он принадлежит списку.
Если элемент принадлежит хвосту списка, то он принадлежит списку.
Примеры применения:
?-принадлежит(b, [а, b, с])
Yes
?-принадлежит(b, [а, [b, с]])
No
?-принадлежит([b, с], [а, [b, с]])
Yes
?-принадлежит(X, [а, b, с])
X= а,
X= b,
X= с.
Пример 3.7.2. Сцепление (конкатенация)
Отношение конкатенации «конк(L1, L2, L3)» формулируется словесно как «список L3 является конкатенацией списков L2 и L3».
Определение предиката:
конк([], L, L).
конк([X | L1], L2, [X | L3]):-конк(L1, L2, L3).
Словесная интерпретация:
Любой список является конкатенацией пустого списка с самим собой.
Если L3 является конкатенацией списков L1 и L2, то это отношение сохранится после присоединения в качестве головы у спискам L1 и L2 одного и того же элемента.
Примеры применения:
Проверка отношения
?-конк( [а, b], [c, d], [a, b, c, d])
Yes
?-конк( [а, b], [c, d], [a, b, a, c, d] )
No
Операция конкатенации
?-конк( [a, b, с], [1, 2, 3], L ).
L = [a, b, c, 1, 2, 3]
Разбиение на подсписки
?- конк( L1, L2, [а, b, с] ).
L1 = [], L2 = [а, b, c];
L1 = [а], L2 = [b, с];
L1 = [а, b], L2 = [c];
L1 = [а, b, с], L2 = [ ].
Разбиение на подсписки до и после заданного элемента
?- конк( До, [май | После ], [янв, фев, март, апр, май, июнь, июль, авг, сент, окт, ноябрь, дек]).
До = [янв, фев, март, апр], После = [июнь, июль, авг, сент, окт, ноябрь, дек].
Нахождение элементов непосредственно предшествующих и следующих за заданным
?- конк(_, [М1, май, М2 | _], [янв, февр, март, апр, май, июнь, июль, авг, сент, окт, ноябрь, дек]).
М1 = апр, М2 = июнь.
?-L1 = [a, b, z, z, c, z, z, z, d, e], конк(L2, [z, z, z | _], L1).
L1 = [a, b, z, z, c, z, z, z, d, e], L2 = [a, b, z, z, c].
Использование в программах
Принадлежность к списку
принадлежит1(X, L):-конк(_, [X | _], L).
Подсписок
подсписок(S, L):- конк(_, L2, L), конк(S, _, L2).
Примеры применения:
?- подсписок(S, [а, b, с]).
S = [];
S = [a];
S = [а, b];
S = [а, b, с];
S = [b];
S = [b, с];
S = [с];
Упражнения 3.7.1.
Напишите предикат для вычеркивания из списка L его трех первых и трех последних элементов.
Упражнения 3.7.2.
Определите отношение последний(Элемент, Список) (последний элемент списка). (а) с использованием отношения конк, (b) без использования этого отношения.
Пример 3.7.3. Добавление элемента
Определение предиката:
добавить(X, L, [X | L]).
Словесная интерпретация:
Добавление элемента к списку в качестве головы.
Примеры применения:
Проверка отношения
?-добавить(a,[b, c, d], [a, b, c, d])
Yes
Добавление элемента
?-добавить(a,[b, c, d], L)
L=[a, b, c, d]
Разбиение на голову и хвост
?-добавить(X, L, [a, b, c, d])
X= a, L=[b, c, d]
Пример 3.7.4. Удаление элемента
Определение предиката:
удалить(X, [X | Хвост], Хвост).
удалить(X, [Y | Хвост], [Y | Хвост1]):- удалить(X, Хвост, Хвост1).
Словесная интерпретация:
Если элемент является головой списка, то удаляем голову.
Удаляем элемент из хвоста списка.
Примеры применения:
Удаление элемента всеми возможными способами
?- удалить(а, [а, b, а, а], L].
L = [b, а, а];
L = [а, b, а];
L = [а, b, а].
Проверка отношения
?- удалить(а, [а, b, а, а], [а, b, а]].
Yes
Добавление элемента всеми возможными способами
?- удалить(а, L, [1, 2, 3]).
L = [а, 1, 2, 3];
L = [1, а, 2, 3];
L = [1, 2, а, 3];
L = [1, 2, 3, а]
Разделение списка на элемент и остальной список
?- удалить(X,[a,b,c], L).
X =a, L= [b,c];
X =b, L= [a,c];
X =c, L= [a,b];
Использование в программах
Принадлежность к списку
принадлежит2(X, L):- удалить( X, L, _).
Пример 3.7.5. Перестановки
Определим отношение перестановка с двумя аргументами, один из которых является перестановкой другого.
Определение предиката:
перестановка([], []).
перестановка([X | L], Р):- перестановка(L, L1), удалить(X, Р, L1).
Словесная интерпретация:
Перестановка пустого списка есть пустой список.
Если список не пуст, то получим перестановки его хвоста, а затем вставим голову в полученные перестановки всеми возможными способами.
Примеры применения:
?- перестановка([а, b, с], Р).
Р = [а, b, с];
Р = [а, с, b];
Р = [b, а, с];
Р = [b, с, а];
Р = [с, а, b];
Р = [с, b, а]