- •Модуль 1. Приемы программирования на пролоГе.
- •Тема 1. Основные понятия и определения логического программирования.
- •Лекция 1
- •1. Язык логического программирования пролог.
- •1.1 Основные понятия и определения
- •Лекция 2
- •1.2 Создание консольного приложения. Структура файла main.Pro.
- •1.3 Примеры построения правил
- •Лекция 3
- •1.5 Согласование целевых утверждений. Поиск с возвратом
- •1.5 Рекурсия в пролоГе.
- •Лекция 4
- •1.6 Средства управления пролог-программой. Отладка пролог-программ.
- •1.7 Стандартные предикаты обработки строк
- •1.8 Средства ввода и вывода. Работа с файлами.
- •Лекция 4
- •1.9 Изображение и обработка списков
- •Лекция 5
- •1.10 Динамические базы данных
- •2. Язык функционального программирования лисп Введение
- •2.1 Объекты данных Лиспа
- •2.2 Основные функции лисПа
- •2.2.1 Функции назначения
- •2.2.2 Числовые функции
- •2.2.3 Базовые функции лисПа
- •2.3 Основы работы в среде mulisp-85
- •2.4 Трассировка функций в muLisp.
- •2.4 Определение функций в лисПе
- •2.6 Рекурсивные определения и вычисления
- •Задания для лабораторных работ
Лекция 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:- !.