При программировании часто возникает необходимость хранения информации. В процедурных языках это реализуется с помощью глобальных переменных. В Prolog (Turbo, PDC, Visual) подобное моделируется с помощью внутренней базы данных.
Во время исполнения программы в базе данных можно хранить (добавлять, удалять) только факты, описанные в секции database (в Visual Prolog аналогично используется секция facts). Факты не должны содержать несвязанных переменных. Базе данных можно задать внутреннее имя описанием database – name.
Приведем предикаты для работы с фактами.
Таблица 12.1 – Назначение предикатов для работы с внутренней базой данных
Предикат |
Назначение |
asserta(<the fact>) /* (i) */ asserta(<the fact>, facts_sectionName) /* (i, i) */ |
Добавление факта в начало базы данных. |
assertz(<the fact>) /* (i) */ assertz(<the fact>, facts_sectionName) /* (i, i) */ |
Добавление факта в конец базы данных. |
assert(<the fact>) /* (i) */ assert(<the fact>, facts_sectionName) /* (i, i) */ |
Добавление факта в конец базы данных, аналогичен assertz. |
retract(<the fact>[, databaseName]) /* (i, i) */ |
Удаление факта из базы данных. Предикат является передоказуемым на бэктрекинге. |
retractall(<the fact>[, databaseName]) |
Удаление всех фактов из базы данных. |
Пример 1. Программа, моделирующая стек.
domains element=integer database stack(element) predicates pusto % стек пуст? add_stack(element) % добавить в стек del_stack(element) % удалить из стека read_stack(element) % просмотр стека без изменения write_stack % распечатать все элементы стека clear_stack % очистить стек clauses pusto :- stack(_),!,fail. pusto. del_stack(X):- free(X), retract(stack(X)),!. add_stack(X):-bound(X), asserta(stack(X)),!. read_stack(X):-free(X), retract(stack(X)), asserta(stack(X)),!. write_stack:-stack(X),write(X),nl,fail. write_stack. clear_stack:-retract(stack(_)),fail. clear_stack. goal add_stack(1),add_stack(2), write_stack, write("-------------"),nl, read_stack(X), write (X),nl.
Факты базы данных можно сохранять и загружать в процессе исполнения программы с помощью следующих предикатов.
Таблица 7 – Назначение встроенных предикатов сохранения и загрузки внутренней базы данных
Предикат |
Назначение |
save(fileName) /* (i) */ save(fileName, databaseName)/*(i, i) */ |
Сохранение базы данных |
consult(fileName) /* (i) */ consult(fileName, databaseName) /*(i, i) */ |
Загрузка базы данных |
Предикат consult выполняет загрузку в память фактов аналогично assertz.
Контрольные вопросы и задания
- Как описывается база данных в Visual Prolog?
- Чем отличается предикат, описанный в секции predicates, от факта, описанного в секции database?
- Какие предикаты служат для добавления фактов в базу данных?
- Каким образом удалить конкретный факт из базы данных?
- Смоделируйте предикат rectractall через retract.
- Выполните как пролог-машина предложенный пример.
- Поясните выполнение предиката read_stack, описанного в примере.
- Поясните назначение предикатов free и bound в примере.
- Напишите, используя базу данных, программу вычисления чисел Фибоначчи.
- Напишите, используя базу данных, программу вычисления факториала.
- Для чего предназначена внутренняя база данных?
- Почему рекомендуется переименовывать секцию database в facts?