 
        
        - •У.Клоксин, к.Меллиш программирование на языке пролог Для программистов и пользователей эвм. Предисловие редакторов перевода
- •Предисловие ко второму изданию
- •Предисловие к первому изданию
- •Глава 1 введение
- •1.1. Факты
- •1.2. Вопросы
- •1.3. Переменные
- •1.4. Конъюнкции
- •1.5. Правила
- •1.6. Заключение и упражнения
- •Глава 2 более детальное описание
- •2.1. Синтаксические правила
- •2.1.1. Константы
- •2.1.2. Переменные
- •2.1.3. Структуры
- •2.2. Литеры
- •2.3. Операторы
- •2.4. Равенство и установление соответствия
- •2.5. Арифметика
- •2.6. Общая схема согласования целевых утверждений
- •2.6.1. Успешное доказательство конъюнкции целевых утверждений
- •2.6.2. Рассмотрение целевых утверждений при использовании механизма возврата
- •2.6.3. Установление соответствия
- •Глава 3. Использование структур данных
- •3.1. Структуры и деревья
- •3.2. Списки
- •3.3. Принадлежность элементов списку
- •3.4. Пример: преобразование предложений
- •3.5. Пример: упорядочение по алфавиту
- •3.6. Использование предиката присоединить и спецификация деталей
- •Глава 4. Возврат и отсечение
- •4.1. Порождение множественных решений
- •4.2. Отсечение
- •4.3. Общие случаи использования отсечения
- •4.3.1. Подтверждение правильности выбора правила
- •4.3.2. Комбинация «отсечение-fail»
- •4.4. Проблемы, связанные с использованием отсечения
- •Глава 5 ввод и вывод
- •5.1. Ввод и вывод термов
- •5.1.1. Вывод термов
- •5.1.2. Ввод термов
- •5.2. Ввод и вывод литер
- •5.2.1. Вывод литер
- •5.2.2. Ввод литер
- •5.3. Ввод предложений
- •5.4. Чтение файлов и запись в файлы
- •5.4.1. Запись в файлы
- •5.4.2. Чтение файлов
- •5.4.3. Ввод программ
- •5.5. Объявление операторов
- •Глава 6. Встроенные предикаты
- •6.1. Ввод новых утверждений
- •Списковая форма записи
- •6.2. Выполнение и невыполнение целевого утверждения
- •6.3. Классификация термов
- •6.4. Работа с утверждениями как с термами
- •6.5. Создание структур и работа с компонентами структур
- •6.6. Воздействие на процесс возврата
- •Отсечение
- •6.7. Формирование составных целевых утверждений
- •Конъюнкция целей
- •Дизъюнкция целей
- •6.8. Равенство
- •6.9. Ввод и вывод данных
- •6.10. Обработка файлов
- •6.11. Вычисление арифметических выражений
- •6.12. Сравнение чисел
- •6.13. Наблюдение за выполнением программы на Прологе
- •Глава 7. Еще несколько примеров программ
- •7.1. Словарь в виде упорядоченного дерева
- •7.2. Поиск в лабиринте
- •7.3. Ханойские башни
- •7.4. Справочник комплектующих деталей
- •7.5. Обработка списков
- •7.6. Представление и обработка множеств
- •7.7. Сортировка
- •7.8. Использование базы данных: random, генатом, найтивсе
- •Генератор случайных чисел (random)
- •Генератор имен (генатом)
- •Генератор списков структур (найтивсе)
- •7.9. Поиск по графу
- •7.10. Просеивай Двойки, Просеивай Тройки
- •7.11. Символьное дифференцирование
- •7.12. Отображение структур и преобразование деревьев
- •7.13. Применение предикатов clause и retract
- •Глава 8. Отладка пролог-программ
- •8.1. Расположение текстов программ
- •8.2. Типичные ошибки
- •8.3. Модель трассировки
- •8.4. Трассировка и контрольные точки
- •Выдача информации о цели
- •Выдача информации о предшественниках
- •Изменение уровня трассировки
- •Вмешательство в процесс согласования цели
- •Другие команды
- •Заключение
- •8.5. Фиксация ошибок
- •Глава 9. Использование грамматических правил в прологе
- •9.1. Проблема синтаксического анализа
- •9.2. Описание синтаксического анализа на языке Пролог
- •9.3. Запись грамматических правил в Прологе
- •9.4. Присоединение дополнительных аргументов
- •9.5. Введение дополнительных условий
- •9.6. Заключение
- •Глава 10. Пролог и математическая логика
- •10.1. Краткое введение в исчисление предикатов
- •10.2. Приведение формул к стандартной форме
- •Этап 1 - исключение импликаций и зквивалентностей
- •Этап 2 - перенос отрицания внутрь формулы
- •Этап 3 - сколемизация
- •Этап 4 - вынесение кванторов общности в начало формулы
- •Этап 5 - использование дистрибутивных законов для & и #
- •Этап 6 - выделение множества дизъюнктов
- •10.3. Форма записи дизъюнктов
- •10.4. Принцип резолюций и доказательство теорем
- •10.5. Хорновские дизъюнкты
- •10.6. Пролог
- •10.7. Пролог и логическое программирование
- •Глава 11. Программные проекты на прологе
- •11.1. Простые проекты
- •11.2. Более сложные проекты
- •Приложение а. Ответы к некоторым упражнениям
- •Приложение в. Программа приведения формул исчисления предикатов к стандартной форме
- •Этап 1 - исключение импликаций
- •Этап 2 - перенос отрицания внутрь формулы
- •Этап 3 - сколемизация
- •Этап 4 - вынесение кванторов общности в начало формулы
- •Этап 5 - использование дистрибутивных законов для. & и #
- •Этап 6 - выделение множества дизъюнктов
- •Печать утверждений
- •Приложение с. Различные версии языка пролог
- •Синтаксис
- •Различные ограничения
- •Возможности окружения
- •Компиляция
- •Специальные встроенные предикаты
- •Средства отладки
- •Приложение d. Пролог для эвм dec system-10
- •Пример сеанса работы
- •Синтаксис
- •Различные ограничения
- •Возможности окружения
- •Компиляция
- •Различия во встроенных предикатах
- •Дополнительные встроенные предикаты
- •Средства отладки
- •Литература
- •Приложение е. Микро-пролог
- •Пример сеанса работы
- •Синтаксис
- •Различные ограничения
- •Возможности окружения
- •Специальные встроенные предикаты
- •Средства отладки
- •Литература
- •Приложение f. Система мпролог[19]
- •Пример сеанса работы
- •Синтаксис
- •Модульность
- •Компоненты системы мПролог
- •Различные ограничения
- •Дополнительные встроенные предикаты
- •Средства отладки
- •Литература
- •Примечания
Этап 5 - использование дистрибутивных законов для. & и #
Реальная программа для преобразования формулы в конъюнктивную нормальную форму является значительно более сложной по сравнению с последней программой. При обработке формулы вида (Р # Q), где Р и Q – произвольные формулы, прежде всего, необходимо преобразовать Р и Q в конъюнктивную нормальную
форму, скажем P1 и Q1. И только после этого можно применять одно из преобразований, дающих эквивалентную формулу. Процесс обработки должен происходить именно в таком порядке, так как может оказаться, что ни Р ни Q не содержат& на верхнем уровне, а Р1 и Q1 содержат. Программа имеет вид:
conjn((P # Q),R):-!, conjn(P,P1), conjn(Q,Q1), conjn1((P1 # Q1),R).
conjn((P& Q),(P1& Q1)):-!, conjn(P,P1), conjn(Q,Q1).
conjn(P,P).
conjn1(((P & Q) # R), (P1 & Q1)):- !, conjn((P # Q), P1), conjn((Q # R), Q1).
conjn1((P # (Q & R)),(P1 & Q1)):-!, conjn((P # Q), P1), conjn((P # R), Q1).
conjn1(P,P).
Этап 6 - выделение множества дизъюнктов
Здесь представлена последняя часть программы приведения формулы к стандартной форме. Прежде всего, определим предикат clausify, который осуществляет построение внутреннего представления совокупности дизъюнктов. Эта совокупность представлена в виде списка, каждый элемент которого является структурой вида cl(A, В). В этой структуре А – это список литералов без отрицания, а В – список литералов с отрицанием (знак отрицания ~ явно не содержится). Предикат clausify имеет три аргумента. Первый аргумент для формулы, передаваемой с пятого этапа обработки, Второй и третий аргументы используются для представления списков дизъюнктов. Предикат clausify создает список, заканчивающийся переменной, а не пустым списком ([]) как обычно, и возвращает эту переменную посредством третьего аргумента. Это позволяет другим правилам добавлять элементы в конец этого списка, конкретизируя соответствующим образом указанную переменную. В программе выполняется проверка с целью выявления ситуаций, когда одна и та же атомарная формула входит в дизъюнкт как с отрицанием, так и без него. Если такая ситуация имеет место, то соответствующий дизъюнкт не добавляется к списку, так как подобные дизъюнкты являются тривиально истинными и не дают ничего нового. Выполняется также проверка неоднократного вхождения литерала в дизъюнкт.
clausify((P& Q),C1,C2):-!, clausify(P,C1,C3), clausify(Q,C3,C2).
clausify(P,[cl(A,B)|Cs],Cs):- inclause(P,A,[],B,[]),!.
clausify(_,C,C).
inclause((P # Q), A, A1, B, B1):-!, inclause(P,A2,A1,B2,B1),inclause(Q,A,A2,B,B2).
inclause((~P),A,A,B1,B):-!, notin(P,A), putin(P,B,B1).
inclause(P,A1,A,B,B):- notin(P,B), putin(P,A,A1).
notin(X,[X|_]):-!, fail.
notin(X,[_|L]):-!, notin(X,L).
notin(X,[]).
putin(X,[],[X]):-!.
putin(X,[X|L],L):-!.
putin(X,[Y|L], [Y|L1]):- putin(X,L,L1).
Печать утверждений
Теперь будет определен предикат pclauses печатающий формулу, представленную указанным способом, в соответствии с принятой формой записи.
pclauses([]):-!, nl, nl.
pclauses([cl(A,B)|Cs]):- pclause(A,B), nl, pclauses(Cs).
pclause(L,[]):-!, pdisj(L), write('.').
pclause([],L):-!, write(':-'), pconj(L), write('.').
pclause(L1,L2):- pdisj(L1), write(':-'), pconj(L2), write('.').
pdisj([L]):-!, write(L).
pdisj([L|Ls]):- write(L), write(';'), pdisj(Ls).
pconj([Lj):-!, write(L).
pconj([L|Ls]):- write(L), write(','), pconj(Ls).
