Ноу Інти, лекція, внутрішні (динамічні) бази даних
У цій лекції ми почнемо вивчати роботу з базами даних в Пролозі.
З одного боку, Пролог-програми не дарма називають базами знань. На Пролозі легко реалізуються реляційні бази даних. найбільш поширені в даний час. Будь-яка таблиця реляційної бази даних може бути описана відповідним набором фактів, де кожного запису вихідної таблиці буде відповідати один факт. Кожному полю буде відповідати аргумент предиката, що реалізує таблицю. Багато дистрибутиви Прологу містять в якості прикладу реалізацію базової частини мови SQL. Можна сказати, що структура реляційних баз даних включається в структуру Пролог-програм.
З іншого боку, Турбо Пролог. на який ми все-таки орієнтуємося в нашому курсі, має вбудовані засоби для роботи з двома типами баз даних: внутрішніми і зовнішніми. Внутрішні бази даних так називаються тому, що вони обробляються виключно в оперативній пам'яті комп'ютера, на відміну від зовнішніх баз даних. які можуть оброблятися на диску або в пам'яті. Так як внутрішні бази даних розміщуються в оперативній пам'яті комп'ютера, звичайно, працювати з ними значно швидше, ніж із зовнішніми. З іншого боку, ємність оперативної пам'яті, як правило, набагато менше, ніж ємність зовнішньої пам'яті. Звідси випливає, що обсяг зовнішньої бази даних може бути істотно більше обсягу внутрішньої бази даних. І якщо передбачається, що база може виявитися досить великий, то слід використовувати саме зовнішні бази даних.
Вивчення зовнішніх баз даних виходить за рамки даного курсу.
У цій лекції ми займемося вивченням внутрішніх або, як їх ще називають, динамічних баз даних.
Внутрішня база даних складається з фактів, які можна динамічно, в процесі виконання програми, додавати в базу даних і видаляти з неї, зберігати в файлі, завантажувати факти з файлу в базу даних. Ці факти можуть використовувати тільки предикати, описані в розділі опису предикатів бази даних.
Якщо розділ опису предикатів бази даних в програмі тільки один, то він може не мати імені. У цьому випадку він автоматично отримує стандартне ім'я dbasedom. У разі наявності в програмі кількох розділів опису предикатів бази даних тільки один з них може бути безіменним. Всі інші повинні мати унікальне ім'я, яке вказується після назви розділу DATABASE і тире. Коли оголошено розділ опису предикатів бази даних. компілятор внутрішньо оголошує відповідний домен з таким же ім'ям, як у цього розділу; це дозволяє спеціальним предикатам обробляти факти як терми.
Опис предикатів бази даних збігається з їх описом в розділі опису предикатів PREDICATES. Однак ці предикати можна задіяти в якості параметрів вбудованих предикатів, з якими ми познайомимося трохи пізніше. Крім того, факти, які використовують ці предикати, можуть додаватися і віддалятися під час виконання програми.
Зверніть увагу на те, що в базі даних можуть міститися тільки факти, а не правила виведення, причому факти бази даних не можуть містити вільних змінних. Це ще одна істотна відмінність Турбо Прологу від класичного Прологу, в якому під час роботи програми можна додавати і видаляти не тільки факти, а й правила. Зауважимо, що в Visual Prolog, який є спадкоємцем Турбо Прологу, в назві розділу опису предикатів внутрішньої бази даних слово DATABASE замінено синонімом FACTS. що ще більше підкреслює, що у внутрішній базі даних можуть зберігатися тільки факти, а не правила.
Давайте познайомимося з вбудованими предикатами Турбо Прологу, призначеними для роботи з внутрішньою базою даних. Всі розглянуті далі предикати можуть використовуватися в варіанті з одним або двома аргументами. Причому одноаргументний варіант використовується, якщо внутрішня база даних не має імені. Якщо ж база пойменована, то потрібно використовувати двухаргументний предикат. в якому другий аргумент - це ім'я бази.
Почнемо з предикатів, за допомогою яких під час роботи програми можна додавати або видаляти факти бази даних.
Для додавання фактів до внутрішньої бази даних може використовуватися один з трьох предикатів assert. asserta або assertz. Різниця між цими предикатами полягає в тому, що предикат asserta додає факт перед іншими фактами (в початок внутрішньої бази даних), а предикат assertz додає факт після інших фактів (в кінець бази даних). Предикат assert доданий для сумісності з іншими версіями Прологу і працює точно так само, як і assertz. В якості першого параметра у цих предикатів вказується додається факт, в якості другого, необов'язкового - ім'я внутрішньої бази даних. в яку додається факт. Можна сказати, що предикати assert і assertz працюють з сукупністю фактів, як з чергою, а предикат asserta - як зі стеком.
Для видалення фактів з бази даних служать предикати retract і retractall. Предикат retract видаляє з внутрішньої бази даних перший з початку факт, який може бути ототожнений з його першим параметром. Другим необов'язковим параметром цього предиката є ім'я внутрішньої бази даних.
Для видалення всіх предикатів, відповідних його першому аргументу, служить предикат retractall. Для видалення всіх фактів з деякою внутрішньої бази даних слід викликати цей предикат. вказавши йому в якості першого параметра анонімну змінну. Так як анонімна змінна зіставляється з будь-яким об'єктом, а предикат retractall видаляє всі факти, які можуть бути ототожнені з його першим аргументом, всі факти будуть видалені з внутрішньої бази даних. Якщо другим аргументом цього предиката вказано ім'я бази даних. то факти видаляються з вказаною бази даних. Якщо другий аргумент не вказано, факти видаляються з єдиною неіменованого бази даних. Зауважимо, що предикат retractall може бути замінений комбінацією предикатів retract і fail наступним чином:
Для збереження динамічної бази на диску служить предикат save. Він зберігає її в текстовий файл з ім'ям, яке було зазначено в якості першого параметра предиката. Якщо другий необов'язковий параметр був опущений, відбувається збереження фактів з єдиною неіменованого внутрішньої бази даних. Якщо було вказано ім'я внутрішньої бази даних. в файл будуть збережені факти саме цієї бази даних.
Факти, збережені в текстовому файлі на диску, можуть бути завантажені в оперативну пам'ять командою consult. Першим параметром цього предиката вказується ім'я текстового файлу, з якого потрібно завантажити факти. Якщо другий параметр опущений, факти будуть завантажені в єдину неіменованого внутрішню базу даних. Якщо другий параметр вказаний, факти будуть завантажені в ту внутрішню базу даних. чиє ім'я було поміщено в другій параметр предиката. Предикат буде неуспешен, якщо для зчитуваного файлу недостатньо вільного місця в оперативній пам'яті або якщо вказаний файл не знайдений на диску, або якщо він містить помилки (нижче буде роз'яснено трохи докладніше, якими вони бувають).