- •Руководство пользователя турбо пролог 2.0.
- •Часть 1: Введение в Турбо Пролог 2.0 18
- •Часть 2. Изучение турбо пролога 2.0 44
- •Глава 3. Основы пролога 44
- •Глава 4. Программы турбо пролога 65
- •Глава 5. Унификация и поиск с возвратом. 84
- •Глава 6. Простые и составные объекты 116
- •Глава 7. Повтор и рекурсия 132
- •Глава 8. Списки и рекурсия 160
- •Глава 9. Внутренняя база данных турбо пролога 180
- •Глава 10. Трассировка и отладка 189
- •Часть 3. Описание турбо пролога 2.0 203
- •Глава 11. Арифметические вычисления и сравнения 203
- •Глава 12. Запись, чтение и файлы 215
- •Глава 13. Обработка строк в турбо прологе 240
- •Глава 14. Окна в ваших программах 249
- •Глава 15. Система внешних баз данных 269
- •Глава 16. Программирование на системном уровне 298
- •Глава 17. Графический интерфейс borland 309
- •Глава 18. Примеры программ 347
- •Глава 19. Сложные приемы программирования 365
- •Введение
- •О Прологе
- •Для чего может быть использован Турбо Пролог?
- •Чем Турбо Пролог отличается от других языков?
- •Минимальные требования к системе
- •Поддерживаемое оборудование
- •О руководствах по Турбо Пролог 2.0
- •Том I: Руководство пользователя
- •Рекомендуемая литература
- •Используемые шрифты
- •Торговые марки.
- •Как связаться с фирмой Borland.
- •Часть 1 введение в турбо пролог 2.0 глава 1. Установка турбо пролога 2.0
- •Что хранится на ваших дисках
- •Теперь сделаем резервные копии
- •Установка Турбо Пролога на вашу систему
- •Установка на систему с гибкими магнитными дисками
- •Установка на жесткий диск
- •Использование данного руководства
- •Глава 2. Начало
- •Загрузка Турбо Пролога
- •Краткое руководство по меню и "горячим" клавишам.
- •Главное меню
- •Спускающиеся меню
- •"Горячие" клавиши и командные клавиши
- •"Горячие" клавиши главного меню
- •Командные клавиши редактора
- •Командные клавиши компиляции
- •Стирание текста
- •Манипулирование текстовыми блоками
- •Ваша первая программа на Турбо Прологе
- •Ввод вашей программы в редактор
- •Корректирование ввода
- •Просмотр в редакторе
- •Запуск вашей программы
- •Что происходит, когда вы делаете синтаксическую ошибку
- •Сохранение вашей программы на диске
- •Просмотр файлов на диске
- •Трассирование вашей программы
- •Пользователям с гибкими магнитными дисками: создание автономных программ.
- •Контроль установки системы
- •Часть 2. Изучение турбо пролога 2.0 глава 3. Основы пролога
- •ПрОграммирование в лоГике
- •Предложения: Факты и Правила.
- •Факты: То что известно
- •Правила: То что вы можете получить из заданных фактов
- •Запросы
- •Совместное задание фактов, правил и запросов
- •Переменные: основные положения
- •Упражнения
- •Из естественного языка в программы на Прологе
- •Упражнения
- •Предикаты (связи)
- •Переменные (обобщенные предложения)
- •Как переменные получают свои значения
- •Анонимные переменные
- •Цели (запросы)
- •Составные цели: Конъюнкция и Дизъюнкция
- •Комментарии
- •Что такое Сопоставление?
- •Глава 4. Программы турбо пролога
- •Основные секции программы на Турбо Прологе
- •Секция предложений
- •Секция предикатов
- •Как объявить предикат пользователя
- •Имена предикатов
- •Аргументы предикатов
- •Секция доменов
- •Примеры.
- •Секция цели
- •Подробнее о декларациях и правилах
- •Задание типов аргументов при декларации предикатов
- •Упражнения
- •Арность (размерность)
- •Синтаксис правил
- •Ключевое слово Пролога "if" и "if" в других языках
- •Автоматическое преобразование типов
- •Другие секции программы
- •Секция базы данных
- •Секция констант
- •Глобальные секции
- •Директивы компилятора
- •Директива include
- •Директивы trace и shorttrace
- •Глава 10 подробно объясняет трассирование, однако еще до того, как
- •Глава 5. Унификация и поиск с возвратом.
- •Сопоставление и унификация
- •Поиск с возвратом.
- •Поиск всех решений
- •Упражнение на поиск с возвратом.
- •Детальный обзор поиска с возвратом.
- •Четыре основных принципа поиска с возвратом.
- •Поиск с возвратом для внутреннего целевого утверждения
- •Управление поиском решений.
- •Использование предиката fail.
- •Упражнения.
- •Прерывание поиска с возвратом: отсечение.
- •Как использовать отсечение.
- •Предотвращение поиска с возвратом к предыдущей подцели в правиле.
- •Предотвращение поиска с возвратом к следующему предложению.
- •Детерминизм и отсечение.
- •Пример, использующий отсечение
- •Предикат not.
- •Упражнения.
- •Пролог с процедурной точки зрения.
- •Как представлять факты и правила в качестве процедур
- •Использование правил для условного ветвления (case).
- •Представление проверки в правиле.
- •Отсечение как goto.
- •Возврат вычисленного значения.
- •Глава 6. Простые и составные объекты
- •Простые объекты данных.
- •Переменные как объекты данных.
- •Константы как объекты данных.
- •Литеры.
- •Составные объекты данных и функторы
- •Унификация составных объектов.
- •Использование знака равенства для унификации составных объектов.
- •Рассмотрение нескольких значений как единое целое.
- •Примеры использования функторов.
- •Пример использования составных объектов.
- •Упражнение.
- •Объявление доменов составных объектов.
- •Запись определений доменов: Обзор.
- •Многоуровневые составные объекты.
- •Пример, иллюстрирующий структуру предложения.
- •Упражнения.
- •Определения составных смешанных доменов.
- •Аргументы множественных типов.
- •Сравнение составных объектов.
- •Глава 7. Повтор и рекурсия
- •Процесс повторения
- •Снова поиск с возвратом
- •Упражнение
- •Предварительные и последующие операции
- •Упражнение
- •Использование поиска с возвратом в замкнутых системах
- •Упражнения
- •Рекурсивные процедуры
- •Что же все-таки делает компьютер?
- •Преимущества рекурсии
- •Оптимизация хвостовой рекурсии
- •Как задать хвостовую рекурсию
- •Упражение
- •Как избежать хвостовой рекурсии
- •На помощь приходит команда "cut"
- •Использование аргументов в качестве переменных цикла
- •Упражнения
- •Рекурсивные структуры данных
- •Деревья - как типы данных
- •Обход дерева
- •Создание дерева
- •Бинарные поисковые деревья
- •Сортировка на основе дерева
- •Упражнения
- •Глава 8. Списки и рекурсия
- •Что такое списки?
- •Объявление списков
- •Голова и хвост списка
- •Работа со списками
- •Использование списков
- •Печать списков
- •Упражнение
- •Подсчет элементов списка
- •Упражнение
- •Хвостовая рекурсия
- •Упражнение
- •Другой пример - изменения в списках
- •Снова о хвостовой рекурсии
- •Еще об изменении списков
- •Принадлежность к списку
- •Упражнение
- •Объединение одного списка с другим: декларативное и процедурное программирование
- •Рекурсии с процедурной точки зрения
- •Упражнение
- •Один предикат может иметь несколько вариантов использования
- •Упражнение
- •Немедленный поиск всех решений
- •Составные списки
- •Упражнение
- •Грамматический разбор списков
- •Заключение
- •Глава 9. Внутренняя база данных турбо пролога
- •Использование внутренней базы данных
- •Объявление внутренней базы данных
- •Обновление внутренней базы данных
- •Занесение фактов во время исполнения
- •Удаление фактов во время выполнения программы
- •Удаление нескольких фактов сразу
- •Считывание новых фактов из файла во время выполнения программы
- •Сохранение базы данных с фактами во время работы программы
- •Примеры
- •Глава 10. Трассировка и отладка
- •Синтаксическая проверка
- •Трассировка
- •Директива трассировки
- •Пример использования директивы trace
- •Трассировка в режиме оптимизации: shorttrace
- •Трассировка указанных предикатов
- •Пример использования директивы shorttrace
- •Сохранение результатов трассировки
- •Предикат trace
- •Пример использования предиката trace
- •Диалоговое управление трассировкой
- •Состояние ( Status )
- •Окно Трассировки ( Trace Window )
- •Окно Редактора ( Edit Window )
- •Предикаты, с особым значением в режиме трассировки
- •Упражнение по трассировке
- •Директивы компилятора, используемые для отладки
- •Директивы check_determ и nondeterm
- •Упражнение
- •Директива diagnostics
- •Директива nowarnings
- •Собщения об ошибках во время выполнения программы
- •Опции компилятора из меню
- •Integer Overflow Check (Проверка целого)
- •Stack Check (Проверка стека)
- •Часть 3. Описание турбо пролога 2.0 глава 11. Арифметические вычисления и сравнения
- •Арифметические выражения
- •Операции
- •Порядок вычислений
- •Функции и предикаты
- •Генератор случайных чисел
- •Предикат random/1
- •Предикат random/2
- •Целочисленная и вещественная арифметика
- •Равенство и предикат равенства
- •Упражнения
- •Сравнение символов, строк и идентификаторов
- •Символы
- •Идентификаторы
- •Примеры, демонстрирующие предикат write
- •Упражнение
- •Предикат writef/*
- •Турбо Пролог распознает следующие спецификаторы формата поля f:
- •Примеры форматного вывода
- •Предикат readln/1
- •Предикаты readint/1, readreal/1 и readchar/1
- •Предикат readterm/2
- •Предикат file_str/2
- •Предикат inkey/1
- •Предикат keypressed/0
- •Предикат unreadchar/1
- •Примеры
- •Упражнение
- •Открытие и закрытие файлов
- •Предикат openread/2
- •Предикат readdevice/1
- •Предикат writedevice/1
- •Примеры
- •Работа с файлами
- •Примеры
- •Предикат eof/1
- •Предикат flush/1
- •Предикат existfile/1
- •Предикат deletefile/1
- •Предикат renamefile/2
- •Предикат disk/1
- •Расширение базы данных с помощью файлов
- •Работа с фактами, как с термами
- •Примеры
- •Глава 13. Обработка строк в турбо прологе
- •Обработка строк
- •Основные предикаты управления строкой
- •Frontchar/3
- •Fronttoken/3
- •Frontstr/4
- •Concat/3
- •Str_lеn/2
- •Str_char/2
- •Str_int/2
- •Str_real/2
- •Upper_lower/2
- •Примеры.
- •Глава 14. Окна в ваших программах
- •Основные операторы управления окном.
- •Задание атрибутов экрана дисплея.
- •Черно-белый дисплей.
- •Цветной дисплей.
- •Makewindow/8
- •Пример.
- •Shiftwindow/1
- •Clearwindow/0
- •Removewindow/0
- •Cursor/2
- •Пример.
- •Игра в угадывание слов с использованием окон.
- •Усовершенствованные предикаты обработки окон.
- •Textmode/2
- •Makewindow/11
- •Existwindow/1
- •Gotowindow/1
- •Removewindow/2
- •Resizewindow/0
- •Resizewindow/4
- •Пример.
- •Framewindow/1
- •Framewindow/4
- •Colorsetup/1
- •Scr_char/3
- •Scr_attr/3
- •Field_str/4
- •Field_attr/4
- •Window_str/1
- •Window_attr/1
- •Простая игра.
- •Использование редактора и dir из программы.
- •Editmsg/8
- •Edit/2 и edit/13
- •Аргументы предиката edit.
- •Display/1
- •Пример доступа к редактору и каталогу.
- •Заключение.
- •Глава 15. Система внешних баз данных
- •Внешние базы данных в Турбо Прологе.
- •Обзор: что такое внешние базы данных?
- •Соглашения об именовании.
- •Селекторы внешних баз данных.
- •Домены, связанные с внешними базами данных.
- •Указатели базы данных.
- •Домен ref.
- •Обработка целых баз.
- •Db_create/3
- •Db_open/3
- •Db_copy/3
- •Db_openinvalid/3
- •Db_flush/1
- •Db_close/1
- •Db_delete/1
- •Db_garbagecollect/1
- •Db_btrees/2
- •Db_chains/2
- •Db_statistics/5
- •Обработка цепочек.
- •Chain_inserta/5 и chain_insertz/5
- •Chain_insertafter/5
- •Term_replace/4
- •Term_delete/3
- •Ref_term/4
- •Пример полной программы.
- •B-деревья.
- •Страницы, порядок и длина ключа.
- •Двойные ключи.
- •Множественный просмотр.
- •Стандартные предикаты для b-деревьев
- •Bt_create/5
- •Bt_open/3
- •Bt_clost/2 и bt_delete/2
- •Bt_statistics/8
- •Key_insert/4 и key_delete/4
- •Key_first/3, key_last/3 и key_search/4
- •Key_next/3 и key_prev/3
- •Key_current/4
- •Пример: Доступ к базе данных через b-деревья
- •Программирование внешних баз данных
- •Просмотр базы данных
- •Вывод содержания базы данных
- •Создание защищенной базы данных
- •Обновление базы данных
- •Использование внутреннего указателя b-дерева.
- •Использование key-search с дублируемыми ключами
- •Изменение структуры базы данных.
- •Глава 16. Программирование на системном уровне
- •Доступ к операционной системе
- •System/1
- •System/3
- •Пример:
- •Envsymbol/2
- •Date/3 и time/4
- •Пример.
- •Comline/1
- •Операции на уровне бит
- •Bitnot/2
- •Bitand/3
- •Bitor/3
- •Bitxor/3
- •Bitleft/3
- •Bitright/3
- •Упражнение:
- •Доступ к аппаратуре: поддержка низкого уровня.
- •Bios/3 и bios/4
- •Ptr_dword/3
- •Membyte/3 и memword/3
- •Port_byte/2
- •Примеры:
- •Глава 17. Графический интерфейс borland
- •Что такое bgi?
- •Несколько слов о видео режимах.
- •Несколько слов о полях вывода (графических окнах).
- •Файл grapdecl.Pro
- •Как начинать
- •Инициализация и выключение системы bgi
- •Предикаты
- •Initgraph/5
- •Detectgraph/2
- •Getgraphmode/1
- •Getmaxmode/1
- •Graphdefaults/0
- •Closegraph/0
- •Restorecrtmode/0
- •Текущая позиция (тп)
- •Getlinesettings/3
- •Окружности
- •Circle/3
- •Getarccoords/6
- •Прямоугольники, многоугольники и полосы.
- •Rectangle/4
- •Bar3d/6
- •Drawpoly/1
- •Fillpoly/1
- •Setfillpattern/2
- •Getfillpattern
- •Floodfill/3
- •Пример заполнения области.
- •Управление цветом.
- •Палитра
- •Цвет фона и цвет рисования.
- •Управление цветом в cga.
- •Низкое разрешение cga.
- •Высокое разрешение cga.
- •Предикаты палитры cga.
- •Управление цветом в ega.
- •Управление цветом в дисплеях системы rgb.
- •Предикаты
- •Шрифты: загружать или компоновать
- •Предикаты
- •Settstyle/3
- •Setusercharsize/4
- •Пример использования различных видов текста
- •Экраны и поля вывода.
- •Предикаты.
- •Setviewport/5
- •Getviesettings/5
- •Управление пикселами и образами
- •Предикаты
- •Ограничения на использование драйвера 8514.
- •Использование bgi
- •Графические драйверы и символьные шрифты.
- •Программа, загружающая драйверы
- •Построение и запуск загружаемых .Exe файлов
- •Сообщения bgi об ошибках
- •Новые драйверы bgi
- •Задача выбора кратчайшего пути
- •Приключения в опасной пещере
- •Моделирование элементов аппаратуры
- •Ханойские башни.
- •Деление слов на слоги
- •Проблема расстановки n ферзей
- •Использование клавиатуры.
- •Чтение и распознавание клавиш
- •Простой редактор полей
- •Применение предиката inkey
- •Глава 19. Сложные приемы программирования
- •Ошибки, исключительные ситуации и прерывания
- •Обработка исключительных ситуаций, связанных с ошибками
- •Exit/o и exit/1
- •Errorsg/4
- •Обработка ошибок при чтении термов
- •Consulterror/3
- •Readtermerror/2
- •Управление режимом break
- •Break/1
- •Breakpressed/0
- •Углубленный контроль ошибок в .Exe файлах
- •Criticalerror/4
- •Fileerror/2
- •Анализ потока параметров
- •Контроль потока параметров
- •Ссылочные типы
- •Объявление ссылочных типов
- •Ссылочные типы и массив trail
- •Применение ссылочного типа
- •Динамическое отсечение
- •Примеры
- •Применение ссылочных типов при реализации бинарных деревьев
- •Сортировка с помощью ссылочных типов
- •Стиль программирования
- •Определение1
- •Определение 2
- •Определение 3.
- •Использование предиката fail
- •Детерминизм и отсечение
Рассмотрение нескольких значений как единое целое.
Составные объекты могут рассматриваться в педложениях Пролога, как
единые объекты, что сильно упрощает написание программ. Рассмотрим, нап-
ример факт:
имеет(джон,книга("Отсюда в Вечность","Джеймс Джонс")).
в котором утверждается, что у Джона есть книга "Отсюда в Вечность", напи-
санная Деймсом Джонсом. Аналогично можно записать:
имеет(джон,лошадь(блеки)).
что означает: у Джона есть лошадь Блеки.
Составными объектами в этих двух примерах являются
книга("Отсюда в Вечность","Джеймс Джонс")
и лошадь(блеки)
Если вы вместо этого описали бы два факта :
имеет(джон,"Отсюда в Вечность").
имеет(джон,блеки).
Вы не смогли бы определить, является ли Блеки названием книги или
именем лошади. С другой стороны, вы можете использовать первый компонент
составного объекта - функтор для распознавания различных объектов. Этот
пример использует функторы книга и лошадь для указания разницы между объ-
ектами.
Запомните: Составные объекты состоят из функтора и объектов принад-
лежащих функтору, как показано:
функтор(объект1,объект2, ... ,объектN)
Примеры использования функторов.
Не только аргументы, но также и функторы могут нести полезную инфор-
мацию, если вы определите домен с несколькими альтернативными функторами.
Рассмотрим реальную программную задачу, такую как передвижение курсора.
Вы можете считать что у нее два аргумента: направление и расстояние пе-
редвижения. Вы, конечно правы, но для Пролога эти аргументы могут быть
одним объектом.
Программа CH06EX02.PRO показывает как это сделать. Она использует
встроенный предикат cursor(Row,Column) который служит двум целям: он оп-
ределяет где находится курсор, если его аргументы свободны, и помещает
курсор в заданные ряд и колонку, если аргументы связаны.
/* программа CH06EX02.PRO -использование функтора */
domains
row,column,step = integer
movement = up(step); down(step); left(step); right(step)
predisates
move_cursor(row,column,movement)
clauses
move_cursor(R,C, up(Step) :-
cursor(R,C), R1=R-Step, cursor(R1,C) .
move_cursor(R,C, down(Step) :-
cursor(R,C), R1=R+Step, cursor(R1,C) .
move_cursor(R,C, left(Step) :-
cursor(R,C), C1=C-Step, cursor(R,C1) .
move_cursor(R,C, right(Step) :-
cursor(R,C), C1=C+Step, cursor(R,C1) .
Загрузите программу CH06EX02.PRO , нажмите Alt-R для ее запуска и
затем задайте следующие цели (по одной за раз) по приглашению Goal для
того, чтобы посмотреть, как вызывается move_cursor
move_cursor(4,9,up(2)).
move_cursor(6,12,down(2)).
move_cursor(13,15,left1(2)).
move_cursor(14,8,right(5)).
Вы можете добавить альтернативный функтор для пустого движения. Это
будет эаписано, как move_cursor(R,C, no). Заметьте, что функтор no важен
для представления отсуствия движения, он не требует аргументов.
Пример использования составных объектов.
Другая важная особенность составных объектов это то, что они позво-
ляют легко передавать группы величин, как один аргумент. Рассмотрим слу-
чай поддержания телефонной базы данных. Пусть вы желаете включить в базу
данных дни рождения ваших друзей и родственников. Здесь приведена часть
программы, которую вы бы написали:
predicates
phone_list(symbol,symbol,symbol,symbol,integer,integer)
/* имя фамилия телефон месяц день год */
clauses
phone_list(ed,willis,422-0208,aug,3,1955).
phone_list(chris,grahm,433-9906,may,12,1962).
Просмотрев данные, обратите что в факте phone_list шесть аргументов,
пять из них могут быть разбиты на два составных объекта, как здесь:
person birthday
/ \ / | \
FirstName LastName Month Day Year
Может оказаться более полезным представлять факты так, чтобы они от-
ражали эти составные объекты данных. Вернувшись на шаг назад, видно, что
person(лицо) - это отношение, а имя и фамилия - объекты. Также,
birthday(день рождения) - это отношение между тремя аргументами: месяцем,
днем и годом. В представлении Пролога они могут быть записаны:
person(First_name,Last_name)
birthday(Month,Day,Year)
Вы можете теперь переписать свою маленькую базу данных с включением
этих составных объектов как части Вашей базы данных.
domains
name=person(symbol,symbol) /* Имя Фамилия */
birthday=b_date(symbol,integer,integer) /* месяц день год */
ph_num=symbol
predicates
phone_list(name,ph_list,birthday)
clauses
phone_list(person(ed,willis),422-0208,b_date(aug,3,1955)).
phone_list(person(chris,grahm),433-9906,b_date(may,12,1962)).
В эту программу введены два определения составных доменов. Мы расс-
мотрим некоторые подробности этих составных структур данных далее в этой
главе. А сейчас мы сосредоточимся на применении таких составных объектов.
Предикат phone_list теперь содержит три аргумента, что отличается от
шести предыдущих. Иногда разбиение данных в составном объекте проясняет
программу и может помочь в обработке данных.
А теперь добавим несколько правил в вашу маленькую программу. Допус-
тим, вы хотите создать список людей, у которых день рождения в этом меся-
це. Здесь приведена программа, которая решает эту задачу, эта программа
использует встроенный предикат date для получения даты из внутреннего ка-
лендаря компьютера. Предикат date будет описан позднее в главе 6. Сейчас
же необходимо знать, что он возвращает текущие год, месяц и день с кален-
даря компьютера.
/* программа CH06EX03.PRO Телефонная книжка и Дни рождения*/
domains
name=person(symbol,symbol) /* Имя Фамилия */
birthday=b_date(symbol,integer,integer) /* месяц день год */
ph_num=symbol /* номер телефона */
predicates
phone_list(name,ph_list,birthday)
get_months_birthdays
convert_month(symbol,integer)
check_birthday_month(integer,birthday)
write_person(name)
clauses
get_month_birthdays :-
makewindow(1,7,7,"Список родившихся в этом месяце",0,0,25,80),
write("Имя\t Фамилия\n"),
date(_,This_month,_),
phone_list(Person,_,Date),
check_birthday_month(This_month,Date),
write_person(Person),fail.
get_month_birthdays :-
write("\n\n Нажмите пробел"),
readchar(_).
write_person(person(First_name,Last_name)) :-
write(" ",First_name,"\t\t ",Last_name), nl.
check_birthday_month(Mon,b_date(Month,_,_)) :-
convert_month(Month,Month1),
Mon=Month1 .
phone_list(person(ed,willis),422-0208,b_date(aug,3,1955)).
phone_list(person(chris,grahm),433-9906,b_date(may,12,1962)).
phone_list(person(benjamin,thomas),555-4565,b_date(mar,3,1935)).
phone_list(person(ray,william),438-8400,b_date(feb,5,1985)).
phone_list(person(thomas,alfred),767-2223,b_date(apr,29,1951)).
phone_list(person(chris,gram),555-1212,b_date(may,12,1962)).
phone_list(person(dustin,robert),438-8400,b_date(jun,17,1980)).
convert_month(jan,1).
convert_month(feb,2).
convert_month(mar,3).
convert_month(apr,4).
convert_month(may,5).
convert_month(jun,6).
convert_month(jul,7).
convert_month(aug,8).
convert_month(sep,9).
convert_month(oct,10).
convert_month(nov,11).
convert_month(dec,12).
Загрузите и запустите эту программу, а затем введите
get_month_birthdays по приглашению Goal:
Чем помогают составные объекты в этой программе ? Это легко увидеть,
если посмотреть текст программы. Большая часть обработки заключена в пре-
дикате get_month_birthdays.
1. Во-первых, программа использует окно для вывода результата
2. Кроме того, она помещает в окне заголовок, помогающий понять ре-
зультат
3. Далее, программа использует в предикате get_month_birthdays вст-
роенный предикат date
4. Кроме того, программа производит поиск в базе данных и печатает
список людей, родившихся в текущем месяце. Сначала ищется первый че-
ловек в базе данных. Вызов phone_list(Person, _,Date) помещает имя и
фамилию человека в переменную Person, а день рождения в переменную
Date.
Заметьте, что необходима только одна переменная для хранения полного
имени человека, и одна переменная для хранения дня рождения. Это
достигается за счет использования составных объектов.
5. Ваша программа может теперь передавать день рождения человека
просто путем передачи переменной Date. Это происходит в следующей
подцели, где программа передает текущий месяц(представленный целым)
и день рождения в предикат check_birthday_month.
6. Посмотрите внимательно, что при этом происходит. Турбо Пролог вы-
зывает предикат check_birthday_month с двумя переменными: первая пе-
ременная связана с целым, а второй с функтором, плюс три его аргу-
мента. В заголовке правила, которое определяет check_birthday_month,
первый аргумент: This_month сравнивается с переменной Mon. Второй
аргумент, Date сопоставляется с b_date(Month,_,_). Это проходит, так
как это тот же объект данных, что и величина, переданная вами. Так
как все это связано с днем рождения человека, используются анонимные
переменные для даты и года рождения.
7. Предикат check_birtday_month сначала превращает символ месяца в
целое число. После того, как это сделано, Турбо Пролог может срав-
нить значение текущего месяца с месяцем рождения человека. Если это
сравнение удачно, подцель check_birthday_month завершается успешно и
обработка продолжается. Если сравнение неуспешно (человек родился в
другом месяце), Турбо Пролог возвращается для другого решения зада-
чи.
8. Следующая подцель, которую нужно обработать - write_person Лицо,
которое нужно обработать, имеет день рождения в этом месяце, и поэ-
тому в отчет попадают только правильные данные. После распечатки ин-
формации предложение терпит неуспех, что вызывает поиск с возвратом.
9. Поиск с возвратом всегда возвращается к последнему неопределенно-
му вызову и пытается удоволетворить этот вызов. В данной программе
последний неудоволетворенный вызов - phone_list. И поэтому программа
будет искать другое лицо, которое может быть обработано. Если в базе
данных нет больше людей, текущее предложение терпит неудачу, Турбо
Пролог пытается доказать этот вызов, просматривая базу данных даль-
ше. Так как есть еще предложение get_month_birthday, Турбо Пролог
пытается доказать этот вызов, доказав подцели этого другого предло-
жения.