Розширення бази даних у файли

Розглянутий підхід до запису і зчитування динамічних БД, з використанням save і consult, забезпечує добрі результати при невеликих розмірах БД. Пов’язано це з тим, що факти динамічної БД є частиною Пролог-програми і, отже, обмежуються розміром вільної оперативної пам'яті. Для збільшення об’єму інформації, що зберігається, можна організувати базу даних, яка зберігається не в оперативній пам’яті, а у файлах на диску.

Це розширює можливість баз даних, оскільки при їх розміщенні у файлах єдиним обмеженням є розмір вільного дискового простору. Це означає, що бази даних Прологу можуть досягати значних розмірів.

Предикат readterm забезпечує доступ до фактів в файлі та має наступний вигляд:

readterm(DomainName, TermRecord),

де DomainName – це ім’я області типів даних, TermRecord – це терм, який зв’язується з заданим об’єктом, за умови узгодження його з описом домену.

Факти, які описують предикати бази даних, можуть бути оброблені так, ніби вони були термами. Це можливо завдяки домену dbasedom, який автоматично декларується системою Пролог і утворює ОДНУ альтернативу для кожного предиката бази даних. Він описує кожен предикат бази даних функтором і доменами аргументів даного предиката. Наприклад, нехай в Пролог-програмі є такі описи бази даних:

database

реrson(name, age, sex)

address(firm, street, house, grоup)

У цьому випадку система Пролог автоматично створить відповідний цим описам домен dbasedom:

domains

dbasedom = реrson(name, age, sex); address(firm, street, house, grоup),

який може бути використаний, як і будь-який інший оголошений домен Пролог- програми.

Розглянемо простий приклад організації бази даних з використанням файлу на диску. За основу приймемо спрощений варіант програми 6_2, в якому база даних address() розміщується у файлі послідовного доступу „adres.dba”.

Даному прикладу відповідає програма 6_3, в якій інтерфейс з явною БД забезпечується з використанням предиката рlасе(), структура якого аналогічна програмі 6_2. Проте процедура, його визначення, відрізняється тим, що в цих правилах передбачено звернення до фактів дискової БД.

/* Програма 6_3 */

/* запитальна система, що навчається, для БД „adres.dba” */

domains

firm, street, group = symbol

house = integer

file = file_bd

database

address(firm, street, house, group)

predicates

place(firm, street, house, group)

my_read(dbasedom)

my_append(dbasedom)

next_rec(file)

clauses

my_read(Record):- openread(file_bd, “adres.dba”), readdevice(file_bd), next_rec(file_bd), readterm(dbasedom, Record).

my_append(Record):- openappend( file_bd, “adres.dba), writedevice(file_bd), write(Record), nl, closefile(file_bd).

next_rec(_).

next_rec(File):- not(eof(File)), next_rec(File).

place(F, S, N, G):- bound(F), my_read(R), R=address(F, S, N, G),!.

place(F, S, N, G):- free(F), my_read(R), R=address(F, S, N, G).

place(F, S, N, G):- bound(F), free(S), free(N), readdevice(key board), write(„введіть для ”, F), nl, write(„назву вулиці: ”), readln(S), write(„номер будинку: ”), readreal(N), write(„групу: ”), readln(G), closefile(file_bd), my_append(address(F, S, N, G)).

Для використання в програмі файлів, слід ввести файловий домен, де визначається логічне ім’я файлу. У нашій програмі таким логічним ім’ям є file_bd. Це ім’я предикатами програми зв’язується з ім’ям файлу БД.

У програмі 6_3 визначені два предикати для читання і додавання фактів у файл БД. Це предикати my_read і my_append. Предикат next_rec по структурі схожий на предикат repeat і служить для переходу від одного запису файлу до іншого, поки не буде знайдено кінець файлу.

У процедурі place() два перші правила, в якості другої підцілі викликають предикат my_read(R), який зв’язує терм R з поточним записом файлу БД.

Третя підмета вказаних правил уніфікує поточний запис з структурою address(F, S, N, G). Якщо уніфікація неможлива, відбувається відкат до предиката my_read(R), який зв’язує змінну R з наступним записом файлу. І так продовжуватиметься до тих пір, поки уніфікація не буде успішною, або поки не буде досягнуто кінець файлу.

Якщо уніфікація завершиться успішно, то змінні F, S, N, G матимуть ті ж значення, що і поля поточного запису БД, а все правило, як і процедура в цілому, буде успішно доведеним. Якщо уніфікація як першого, так і другого правила завершилася невдачею при досягненні кінця файлу, то система перейде до доведення третього правила процедури place().

У процедурі my read() перша підмета зв’язує логічне ім’я file_db з дисковим файлом „adres.dba” і відкриває його для читання.

Друга підмета об’являє файл з логічним ім’ям file_db стандартним пристроєм вводу. Це означає, що всі предикати типу read, що описані в програмі, виконуватимуть ввід даних з файлу, а не з клавіатури, яка за замовчуванням, є стандартним пристроєм вводу.

Третя підмета служить для організації повторного виконання, наступних підзадач при відкатах. Слід зазначити, що предикат next_rec() істинний завжди, якщо не досягнуто кінця (eof()) записів у файлі на диску.

Оскільки стандартним пристроєм вводу попереднім предикатом встановлено дисковий файл, то саме з нього четверта підмета прочитує в змінну Record терм, структура якого відповідає структурі домена бази даних. Інакше кажучи, виконується читання в змінну Record вмісту поточного запису файлу, структура якого повинна відповідати описаній в програмі структурі БД.

У процедурі my арpend() перша підмета зв’язує логічне ім’я file_db з дисковим файлом „adres.dba” і відкриває його для запису.

Друга підмета призначає файл з логічним ім’ям file_db стандартним пристроєм виводу. Це означає, що всі предикати типу write, що зустрічаються далі, виконуватимуть вивід даних у файл, а не на екран дисплея, який є стандартним пристроєм виводу за замовчуванням.

Третя підмета виводить (додає в кінець файлу) новий запис, значення якого вводиться в дану процедуру через змінну Record.

Після виконання цих дій четверта підмета закриває відкритий для запису файл.

Основним режимом роботи даної програми є режим відповідей на запити, який вимагає постійного доступу до файлу на диску. При цьому за пристрій вводу програма назначає файл БД. Проте за відсутності в БД потрібних даних, програма переходить в режим навчання і вимагає від користувача введення з клавіатури нових даних.

У третьому правилі процедури place() для того, щоб забезпечити можливість вводу даних з клавіатури, використовується предикат readdevice(keyboard) який встановлює як стандартний пристрій вводу клавіатуру. Після цього виконується запит на ввід нових даних. Закривається робочий файл, який був відкритий для читання та виконується додавання нового запису в кінець дискового файлу.

Слід зазначити, що в даному прикладі розглянутий простий випадок доступу до файлових даних. Він приведений з метою ілюстрації принципу побудови динамічних БД і їх розширення у файлові структури.

Наши рекомендации