Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Основы программирования на языке Turbo Prolog.doc
Скачиваний:
56
Добавлен:
09.11.2019
Размер:
563.2 Кб
Скачать

Глава 9. Динамическая база данных

1. Турбо-пролог и реляционные базы данных

Турбо-Пролог ориентирован на работу с реляционными БД. Можно указать следующее соответствие понятий:

База данных Турбо-Пролога

Реляционная база данных

предикат БД

Отношение

объект(аргумент)

Атрибут

отдельное утверждение

Элемент отношения

количество утверждений

Мощность

Пусть в разделе clauses имеется следующий факт:

member_party(”Вольфович”,50,100,”n”).

Предикат member_party имеет четыре аргумента: партийное имя, возраст, членский взнос (в рублях), отметка об уплате.

Поскольку введенная ранее терминология Турбо-Пролога прилагается к реляционным базам данных, то все понятия приобретают новое значение:

набор атрибутов Name,Age,Pay и Payment называется реляционной схемой отношения member_party, где арность отношения равна четырем и мощность отношения равна одному.

Совокупность утверждений предиката member_party составляет СТАТИЧЕСКУЮ БД, так как эти утверждения являются частью программного кода и не могут быть изменены во время выполнения программы. Также в Турбо-Прологе имеются специальные средства и для организации динамических баз данных, и для работы с внешними базами данных, расположенными на жестком диске. Рассмотрим подробно способы организации динамических БД.

2. Описание предикатов динамических бд

Раздел database в Турбо-Прологе предназначен для описания предикатов базы данных. Все различные утверждения этих предикатов составляют динамическую базу данных Турбо-Пролога.

database

dmember_party(name,age,pay,payment)

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

Все отличие предиката dmember_party по сравнению с member_party заключается лишь в одной лишней букве терма. Добавление латинской буквы d — обычный способ различать предикаты динамической и статической баз данных.

domains

name,payment=symbol

age,rubel=integer

pay=integer

database

dmember_party(name,age,pay,payment)

predicates

member_party(name,age,pay,payment)

В ДИНАМИЧЕСКОЙ БАЗЕ ДАННЫХ МОГУТ СОДЕРЖАТЬСЯ ТОЛЬКО ФАКТЫ (НЕ ПРАВИЛА).

В этом состоит отличие Турбо-Пролога от других реализаций языка Пролог.

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

Другая важная особенность динамической базы данных состоит в том, что такая база может быть записана на диск, а также считана с диска в оперативную память (встроенные предикаты save и consult).

3. Встроенные предикаты asserta, assertz, retract, retractall, save, consult

В Турбо-Прологе имеются специальные встроенные предикаты для работы с динамической базой данных. Таковыми являются asserta, assertz, retract, retracrall, save, consult.

Предикаты asserta, assertz и retract позволяют занести факт в заданное место динамической БД и удалить из нее уже имеющийся факт.

Предикат asserta заносит новый факт в базу данных, располагающуюся в оперативной памяти компьютера (резидентная БД). Новый факт помещается перед всеми уже внесенными утверждениями данного предиката. Этот предикат имеет такой синтаксис:

asserta(Clause)

Таким образом, чтобы поместить в БД утверждение о новом члене партии перед уже имеющимся там утверждением (стоящим в настоящий момент в базе данных на первом месте), необходимо следующее предикатное выражение:

asserta(member_party(”Кузьмич”,65,10,”y”))

Предикат assertz так же, как и asserta, заносит новые утверждения в базу данных. Однако он помещает новое утверждение за всеми уже имеющимися в базе утверждениями того же предиката. Синтаксис предиката столь же прост:

assertz(Clause)

Предикат retract удаляет утверждение из динамической БД. Его синтаксис таков:

retract(Existing_clause)

Если в базе данных НЕТ УТВЕРЖДЕНИЯ, которое вы пытаетесь удалить, то retract ОКОНЧИТСЯ НЕУДАЧЕЙ.

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

retract(member_party(”Кузьмич”, 65,10,”y”))

Если вы хотите удалить из БД всех членов, не уплативших взносы, то можно воспользоваться предикатом:

retractall(member_party(_,_,_,”n”))

Предикат retractall ВСЕГДА УСПЕШЕН, даже при попытке удалить что-то из абсолютно пустой БД.

Предикат retract имеет важную особенность — он ПЕРЕДОКАЗЫВАЕТСЯ ПРИ ВОЗВРАТАХ (в отличие от asserta, assertz и retractall). Поэтому при применении предиката retract существует опасность непредсказуемого изменения программы. В дальнейшем будут рассмотрены приемы, позволяющие решить эту проблему.

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

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

assert_database :-

member_party(Name,Age,Pay,Payment),

assertz(dmember_party(Name,Age,Pay,Payment)),

fail.

assert_database :- !.

Первое правило с помощью возврата после неудачи перебирает все утверждения предиката member_party, второе обеспечивает успешное завершение цели.

Процедура очистки динамической БД перед выходом из программы:

clear_database:-

retractall(dmember_party(_,_,_,_)).

Содержимое динамической БД можно и сохранить в файле на диске, и загрузить из файла.

Предикат save сохраняет находящуюся в оперативной памяти базу данных в текстовом файле. Синтаксис этого предиката:

save(DOS_file_name)

Здесь DOS_file_name есть произвольное допустимое в MS DOS имя файла.

Для того чтобы сохранить содержимое БД в файле текущего каталога с именем party.dba, требуется предикат:

save("party.dba")

Если файл с таким именем уже имелся на диске, то этот старый файл будет затерт, если такого файла не было, будет образован новый.

Файл с динамической БД представляет собой обычный текстовый файл, в котором утверждения сгруппированы по шаблону (если в БД имеется несколько разных предикатов), и каждое утверждение находится на отдельной строчке.

Файл БД может быть считан в память при помощи предиката consult, систаксис которого таков:

consult(DOS_file_name)

Для загрузки файла партийной БД требуется выражение consult("party.dba").

Следует помнить, что предикат consult неуспешен, если файл с указанным именем отсутствует на диске, или этот файл содержит ошибки, как, например, в случае несоответствия синтаксиса предиката из файла описаниям из раздела программы database, или если содержимое файла невозможно разместить в памяти ввиду отсутствия места.

Кроме того, при указании пути для любых предикатов, работающих с файлами обратный слэш \ следует заменять его кодом \92:

save(”a:\92dbs\92party.dba”)

Предикат findall позволяет собрать все имеющиеся в базе данные в список, который может быть полезен при дальнейшей работе. (Предикат findall был описан в гл. 7.) Так, findall можно использовать для получения списка имен всех членов партии. После того, как успешным будет предикат

findall(Name,dmember_party(Name,_,_,_),Name_list)

переменная Name_list будет содержать список всех имен.