Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции ФЛП.doc
Скачиваний:
18
Добавлен:
27.05.2015
Размер:
632.83 Кб
Скачать

Лекция 5

1.10 Динамические базы данных

В Турбо-Прологе имеются специальные средства для организации реляционных баз данных (БД). Предикаты базы данных описываются в разделе database, который должен располагаться в программе перед разделом predicates. Все утверждения с предикатами, описанными в разделе database, составляют динамическую БД, которая, в отличие от неизменяемой статической БД, являющейся частью кода программы, в процессе работы программы может меняться, т.е. из нее можно удалять любые содержащиеся в ней утверждения, а также добавлять новые.

Предикаты, объявленные в разделе database могут используются аналогично тому, как используются предикаты из раздела predicates.

Допускается наличие нескольких разделов database, но для этого нужно явно указать имя каждого раздела database.

database - mydatabase

myFirstRelation(integer)

mySecondRelation(real,string)

myThirdRelation(string)

В ТП для добавления в БД новых фактов применяются предикаты asserta и assertz, а для изъятия фактов – предикаты retract и retractall. Модификацию содержимого БД возможно провести сначала путем изъятия факта, а потом добавления новой версии факта (или другого факта).

Чтение фактов из файлов и включение их во ВБД проводится с помощью предиката consult, сохранение содержимого ВБД с помощью предиката save. В программе допускается несколько разделов database, но в этом случае им должны быть присвоены имена.

Есть три основных способа внесения в программу фактов:

– как часть раздела clauses;

– при выполнении программы с помощью предикатов asserta и assertz:

– путем загрузки файла с помощью предиката consult.

У всех стандартных предикатов ТП может быть один или два аргумента. Необязательный второй аргумент – это имя ВБД. Предикат asserta обеспечивает добавление нового факта в БД перед существующими фактам для соответствующих предикатов, а assertz – после существующих. Эти предикаты имеют следующие форматы

asserta(<факт>, имя ВБД.), assertz (<факт>, имя ВБД) и

asserta(<факт>), assertz (<факт>).

Предикат retract имеет тот формат, который и asserta и assertz. Он является недетерминированным предикатом. В процессе поиска с возвращением retract возвращает альтернативные решения и изымает все факты, с которыми устанавливается соответствие, до тех пор пока таких фактов не останется вообще. Все факты, которые отвечают заданному шаблону, изымаются из БД с помощью retractall. Как и в случае retract, когда он вызывается с подчеркиванием в виде аргумента, можно из данного раздела database изъять все факты.

Предикат consult имеет следующий формат

consult (имя файла, имя ВБД) и consult(имя файла).

В отличие от assertz, когда мы вызываем его с одним аргументом (без имени ВБД), будут читаться только факты, объявленные в разделе database, что именуется по умолчанию dbasedom. При вызове consult с двумя аргументами, факты вынимаются только согласно указанному имени БД. Если файл содержит еще что-то отличное от фактов заданной БД, то случится ошибка.

Consult может читать только в том формате, в котором был сформирован с помощью save. При этом в тексте не должно быть:

– заглавных букв;

– пробелов вне строк, размещенных в двойных кавычках;

– комментариев;

– пустых строк;

– символьных значений без двойных кавычек.

Рассмотрим построение базы данных некоторой продукции и предоставим ей имя b_prod. Основные блоки программы будут иметь следующий вид.

/*Объявление логических имен файлов для ввода и сохранения */

domains

file=f_in;

file=f_out

/*Объявление базы данных */

database b_prod(string, integer,….,real).

predicates

print_one(string, integer,….,real)

print_all

in_base

in_base_file

delet_one

delet_one

save_file

clausues

/*Формирование факта БД в процессе выполнения программы */

in_base :-write(“ Вид продукції -”), readln(X1),

………………………………………………..

write(“ План, шт. -”), readln(Xn), assrtz(b_prod(X1, X2, X3, ...,Xn).

/*Загрузка БД из указанного файла */

in_base_file:- write(“ Ім’я файлу”), readln(N_f), openread(f_in,N_f),

readdevice((f_in), consult ((N_f), closfile(f_in).

/*Изъятие отдельного факта БД по аргументу, который вводится с клавиатуры */

delet_one:-write(“ Вид продукції -”), readln(N), retract(b_prod(N, _, _, _,).

/*Сохранение БД в указанный файл*/

save_file:-write(“ Ім’я файлу*), readln(n_F), openwrite(f_out, N_F), writedevice(f_out), save((N_f), closfile(f_out).

/*Вывод отдельного факта на экран БД */

print_one(X1, X2 ,…,Xn):- b_prod(X1, X2 ,…,Xn),.

write(“Вид продукції -”X1,),nl,

write(“План, шт. -”, Xn), nl.

readchar(_).

/*Просмотр всех фактов БД */

print_all:- print_one(_, _ ,…,_), fail.

В последнем правиле было применено два предиката, которые раньше не встречались. Предикат nl переводит вывод на новую строку. Предикат fail (возражение) формально относится к средствам управления программой. Он имеет постоянное значение false и его действие противоположно действию предиката cut. Т.е., если отсечение запрещает поиск с возвращением, возражение его возобновляет. Как правило, его применения ограничивается рассмотренным случаем.

В Турбо-Прологе имеются специальные средства для организации реляционных баз данных (БД). Предикаты базы данных описываются в разделе database, который должен располагаться в программе перед разделом predicates. Все утверждения с предикатами, описанными в разделе database, составляют динамическую БД, которая, в отличие от неизменяемой статической БД, являющейся частью кода программы, в процессе работы программы может меняться, т.е. из нее можно удалять любые содержащиеся в ней утверждения, а также добавлять новые.

Например, в динамической БД содержатся сведения об игроках-футболистах с предикатом dplayer, тогда требуется следующее описание:

database

dplayer(name,team,number),

где name, team, number – типы данных, описанные в domains.

Для работы с динамической БД могут использоваться встроенные предикаты:

asserta и assertz – занесение нового факта соответственно в начало и конец БД, располагающейся в оперативной памяти (резидентная БД);

retract – удаление утверждения из динамической БД;

save – запись на диск динамической БД;

consult – добавление текстового файла к динамической базе данных.

Кроме того, для работы с БД в целом используются предикаты:

readterm – чтение из файла объектов, относящихся к определенному в программе домену;

findall – сбор указанных объектов БД в список.

Иногда бывает предпочтительно иметь часть информации БД в виде утверждений статической БД. Сразу после активизации программы эти данные заносятся в динамическую БД (с помощью предикатов asserta и assertz). В общем предикаты статической БД имеют другое имя, но ту же форму представления данных, что и предикаты динамической БД.

Предикат статической БД, соответствующий предикату dplayer динамической БД, есть

predicates

player(name,team,number)

clauses

player(“Адамов”,”Динамо”,4).

. . .

Правилом для занесения в динамическую БД информации из статической БД является:

assert_database:- player(Name,Team,Number), assertz(dplayer(Name,Team,Number)), fail.

assert_database:- !.

Используемый в этом правиле предикат fail позволяет перебрать все утверждения предиката player.

Подобным образом можно записать правило для очистки динамической БД:

clear_database:- retract(dplayer(_,_,_)),fail.

clear_database:- !.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]