Внутренняя база данных

При программировании часто возникает необходимость хранения ин­­фор­ма­ции. В процедурных языках это реализуется с помощью гло­баль­ных пере­мен­ных. В 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.

Контрольные вопросы и задания

  1. Как описывается база данных в Visual Prolog?
  2. Чем отличается предикат, описанный в секции predicates, от факта, описанного в секции database?
  3. Какие предикаты служат для добавления фактов в базу данных?
  4. Каким образом удалить конкретный факт из базы данных?
  5. Смоделируйте предикат rectractall через retract.
  6. Выполните как пролог-машина предложенный пример.
  7. Поясните выполнение предиката read_stack, описанного в примере.
  8. Поясните назначение предикатов free и bound в примере.
  9. Напишите, используя базу данных, программу вычисления чисел Фибоначчи.
  10. Напишите, используя базу данных, программу вычисления факториала.
  11. Для чего предназначена внутренняя база данных?
  12. Почему рекомендуется переименовывать секцию database в facts?