
- •Глава 1. Введение в пролог
- •1. Декларативные и процедурные языки программирования
- •2. Пролог и логика предикатов. Внешние цели
- •3. Управление программой. Подцели. Механизм сопоставления
- •4. Внутренние подпрограммы унификации
- •Глава 2. Внутренние цели. Механизм возврата
- •1. Структура пролог-программы
- •2. Использование внутренних целей
- •3. Встроенный предикат fail
- •4. Сокращенные варианты внутренних запросов
- •5. Использование в запросах анонимных переменных
- •6. Механизм возврата
- •Глава 3. Типы данных и арифметика Turbo Prolog
- •1. Стандартные типы данных
- •2. Структуры, простые и составные
- •3. Структурные диаграммы
- •4. Использование в запросах анонимных переменных
- •5. Использование альтернативных доменов
- •6. Арифметика в Turbo Prolog
- •Глава 4. Предикат отсечения (!). Программирование альтернатив. Правила повтора
- •1. Повторения и возвраты
- •2. Отсечение (!)
- •3. Программирование альтернатив
- •4. Правило повтора
- •Глава 5. Методы организации рекурсии
- •1. Простая рекурсия
- •2. Метод обобщенного правила рекурсии
- •3. Граничное условие рекурсии. Нисходящая и восходящая рекурсии
- •4. Программа о подсчете числа точек
- •Глава 6. Списки
- •1. Основные понятия
- •2. Списки и турбо-пролог
- •3. Атрибуты списка
- •4. Внутреннее представление списков
- •5. Применение списков в программе
- •6. Метод разделения списка на голову и хвост
- •7. Поиск элемента в списке
- •8. Присоединение списка
- •9. Добавление и удаление элемента
- •10. Подсписок
- •11. Перестановки списка
- •Глава 7. Сортировка списков
- •1. Разделение списка на два
- •2. Сортировка списков методом вставки
- •3. Быстрая сортировка
- •4. Быстрая сортировка_1
- •5. Компоновка данных в список
- •Глава 8. Программирование алгоритмов с возвратом. Представление графов в turbo prolog
- •1. Задача о весах
- •2. Представление графов в turbo prolog
- •3. Поиск пути на неориентированном графе
- •4. Поиск гамильтоновых циклов
- •5. Поиск пути минимальной стоимости
- •Глава 9. Динамическая база данных
- •1. Турбо-пролог и реляционные базы данных
- •2. Описание предикатов динамических бд
- •3. Встроенные предикаты asserta, assertz, retract, retractall, save, consult
- •4. Создание динамической базы данных
- •5. Обсуждение проекта базы данных
- •6. Создание базы данных
- •7. Написание программных модулей
- •Глава 10. Глобальные переменные в turbo prolog
- •1. Модификация базы данных
- •2. Накопление результатов с помощью вынуждаемого возврата
- •3. Подсчет членов парторганизации
- •4. Поиск пути минимальной стоимости от a до z
- •Библиографический список
- •Оглавление
4. Правило повтора
Попытаемся заставить правило show_point читать ряд значений координат точки. Организуем бесконечный цикл с именем repeat:
repeat.
repeat :- repeat.
Первый repeat является утверждением, объявляющим предикат repeat истинным. Однако, поскольку имеется еще один вариант для этого правила, то указатель возврата устанавливается на второй repeat. Второй repeat — это рекурсивное правило, которое вызывает само себя. Этот вызов вычисляется успешно, так как первый repeat удовлетворяет подцели repeat.
Следовательно, предикат repeat будет вычисляться успешно при каждой новой попытке его вызвать после возврата.
Вставим его в правило show_point:
show_point:-
repeat,
readreal(X),readreal(Y),
<.....................>,
fail.
Чтобы превратить этот бесконечный цикл в цикл с постусловием, поступим так:
show_point:-
repeat,
<................>,
< условие выхода >,
!.
Если < условие выхода > дает отказ, то происходит возврат к repeat; если же условие выхода успешно согласовывается, то отсечение не дает осуществить возврат к repeat, цель show_point дает отказ, и запросы прекращаются.
/* Программа 4.3 «Точки». Назначение: */
/* демонстрации использования правила повтора */
predicates
show_point
repeat
pos_point(real,real,real)
out_sqr(real,real,real)
in_circ(real,real,real)
goal
show_point.
clauses
show_point:-
write(" R? "), readreal(R),
repeat,
write(" X? "),readreal(X),
write(" Y? "),readreal(Y),
pos_point(X,Y,R), % условие выхода
!.
repeat. % бесконечный цикл
repeat:-repeat.
% выход из цикла для точки (0,0)
pos_point(0,0,_):-!.
pos_point(X,Y,R):-
out_sqr(X,Y,R),!,
write(" вне квадрата"), nl,
fail.
pos_point(X,Y,R):-
in_circ(X,Y,R),!,
write("внутри круга"), nl,
fail.
pos_point(_,_,_):-
!,
write("вне круга и внутри квадрата"),
nl, fail.
out_sqr(X,Y,R):- % условие вне квадрата
abs(X)>R;
abs(Y)>R.
in_circ(X,Y,R):- % условие внутри круга
X*X+Y*Y<R*R.
/* Конец программы */
Подсчитать число точек является делом более сложным, так как при возвратах переменные будут «забывать» накопленные значения, а глобальных переменных у нас нет.
Для того, чтобы решить эту задачу, не отказываясь от цикла repeat, нужно воспользоваться динамической базой данных, которая играет роль «глобальной переменной».
Работа с динамической базой данных будет рассмотрена позже, а пока отметим, что такой метод организации цикла наиболее эффективен при реализации доступа к данным в базе данных и файлах на диске, а также для организации меню.
Подобным же образом в правиле можно использовать более одного правила повтора. Ниже приведено правило, включающее два правила повтора:
do_two_things :-
repeat1,
<повторяемое тело>,
<условие выхода 1>,!,
repeat2,
<повторяемоу тело>,
<условие выхода 2>,!.
repeat1.
repeat1 :- repeat1.
repeat2.
repeat2 :- repeat2.
Упражнение 4.3.
На числовую прямую с тремя отмеченными областями (от — до —1, от —1 до 2 и от 2 до +). Показать, куда падает точка.
Упражнение 4.4.
Имеется база данных о результатах партий теннисного матча. Результаты представлены в программе в виде фактов типа:
win(tom,john).
Определить отношение class, которое будет распределять игроков по категориям:
profi — победитель всех сыгранных им матчей;
player —выигравший и проигравший хотя бы одну игру;
user — проигравший все матчи.
Если игрок отсутствует в базе, программа должна выдавать соответствующее сообщение.