Распечатать страницу

Лабораторна робота №18, Внутрішня база фактів

« Назад

Код роботи: 1126

Вид роботи: Лабораторна робота

Предмет: Технологія створення програмних та інтелектуальних систем

Тема: №18, Внутрішня база фактів

Кількість сторінок: 22

Дата виконання: 2016

Мова написання: українська

Ціна: 250 грн

Мета: Ознайомитися з поняттям «база фактів» у мові пролог і навчитися методам взаємодії з «базою фактів».

Хід роботи

Внутрішня база фактів Visual Prolog. У даній лабораторній роботі буде розглянуто, як потрібно оголошувати розділи внутрішніх баз фактів Прологу (internal fact databases) і як можна змінити зміст вашої внутрішньої бази фактів.

Внутрішня     база   фактів    складається   з   фактів,    які   ви    можете безпосередньо додавати і видаляти з вашої програми на Visual Prolog під час її виконання. Ви можете оголошувати предикати, що описують внутрішню базу даних у розділі class facts програми і застосовувати ці предикати таким же чином, як використовуються предикати, описані в розділі class predicates. Для додавання нових фактів до бази даних в Visual Prolog використовуються предикати assert, asserta, assertz, а предикати retract и retractall служать для видалення існуючих фактів. Можна змінити вміст бази фактів, спочатку видаливши факт, а потім вставивши нову версію цього факту (або зовсім інший факт).

Предикати consult/l і consult/2 зчитують факти з файлу і додають їх до внутрішньої бази даних, a save/l і save/2 зберігають вміст внутрішньої бази фактів у файлі.

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

Оголошення внутрішньої бази фактів

Ключове слово class facts (це синонім застарілого слова database) означає початок оголошення розділу class facts. Розділ class facts складається з послідовності оголошень предикатів, що описують відповідну внутрішню базу фактів. Під час виконання можна за допомогою предикатів asserta і assertz додавати факти (але не правила) в базу фактів. Або, викликавши стандартний предикат consult, можна витягти факти з файлу на диску. Розділ class facts може виглядати так, як показано на прикладі:

Б1126, 1

Б1126, 2

У цьому прикладі можна використовувати предикат person таким же чином, як використовуються інші предикати (male). Єдина відмінність полягає в тому, що ви можете додавати і видаляти факти для предиката person під час роботи програми.

Слід відзначити наступні два обмеження на предикати, оголошені в розділі фактів:

- Дозволяється додавати в базу даних тільки факти, але не правила;

- Факти бази не можуть містити вільні змінні.

Допускається наявність декількох розділів class facts, але для цього потрібно явно вказати ім'я кожного розділу class facts.

Б1126, 3

Опис розділу class facts з іменем mydatabase створює базу даних фактів з ім'ям mydatabase. Якщо не давати імені внутрішній базі фактів, то за замовчуванням їй присвоюється стандартне ім'я dbasedom. Програма також може містити локальні безіменні розділи фактів, тільки якщо вона складається з єдиного модуля, який не оголошений як частина проекту. Імена предикатів бази фактів мають бути унікальними в модулі (вихідному файлі); в двох різних розділах class facts не можна застосовувати однакові імена предикатів. Аналогічно, не можна використовувати однакові імена предикатів в розділах class facts і class predicates. Однак імена предикатів, визначених у локальних class facts - розділах, є локальними для модуля, де вони оголошені, і не конфліктують з локальними іменами предикатів/фактів, оголошених в інших модулях.

Використання внутрішніх баз фактів

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

Доступ до внутрішньої базі фактів

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

Приклад 1. Доступ до внутрішньої бази фактів

Програма в даному прикладі знаходить всіх жінок.

Лістинг програми

Б1126, 4

Б1126, 5

Б1126, 6

Рис. 1. Результат виконання програми з прикладу 1

Оновлення внутрішньої бази фактів

Факти для предикатів бази фактів можуть бути визначені під час компіляції в розділі clauses, як це показано в останньому прикладі. Під час виконання факти можуть бути додані і видалені, використовуючи описані нижче предикати. Зверніть увагу, що факти, визначені під час компіляції в розділі clauses, також можуть бути видалені, вони нічим не відрізняються від фактів, доданих під час виконання. Стандартні предикати Visual Prolog для роботи з фактами: assert, asserta, assertz, retract, retractall, consult і save — можуть мати один або два аргументи. Необов'язковий другий аргумент являє собою ім'я внутрішньої бази фактів.

Позначення /1 і /2 після кожного імені предиката вказує необхідну кількість аргументів для даної версії предиката. Коментарі (такі як /* (i) */ і /* (о, i) */) показують потік (і) параметрів для цього предиката.

 

Занесення фактів під час виконання програми

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

Існує три предиката для додавання одного факту під час виконання:

Б1126, 7

Предикат asserta вставляє новий факт до бази даних фактів перед наявними фактами для даного предиката, a assertz вставляє факти після наявних фактів даного предиката. Використання предиката assert дає результат, аналогічний виконанню assertz.

Оскільки імена предикатів бази фактів унікальні для модуля, для предикатів asserta і assertz завжди відомо, в яку базу даних фактів потрібно додавати факт. Однак для того, щоб забезпечити роботу з необхідною базою даних фактів, з метою перевірки типу можна використовувати необов'язковий другий аргумент.

Перший предикат наступного прикладу вставить факт про Suzanne, описаний предикатом person, після всіх фактів person, що зберігаються на поточний момент в пам'яті. Другий - факт про Michael перед всіма фактами предиката person. Третій — факт про John після всіх інших факторів likes в базі даних фактів likesDatabase, а четвертий вставить факт про Shannon в ту ж базу даних фактів перед всіма іншими фактами likes.


Після виклику цих предикатів база фактів буде виглядати так, як ніби ви почали роботу з наступними фактами: %Внутрішня база фактів — dbasedom person("Michael","New York",26).

Б1126, 9

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

Приклад 2. Додавання нових фактів в базу фактів

В наступному прикладі факт додається до бази, тільки якщо він є унікальним.

Лістинг програми

Б1126, 10

Б1126, 11 

Б1126, 12

Б1126, 13

Рис. 2. Результат виконання програми із прикладу 2

Считування фактів з файлу

Предикат consult зчитує з файлу fileName факти, описані в розділі class facts, і вставляє їх у вашу програму в кінець відповідної бази фактів. Перед використанням предиката consult необхідно підключити file наступним чином:

Б1126, 14

Однак на відміну від assertz, якщо ви викличте consult тільки з одним аргументом (без імені бази фактів), то будуть прочитані лише факти, які були описані в розділі без імені (за замовчуванням dbasedom) .

Якщо викликати consult з двома аргументами (ім'я файлу і ім'я бази фактів), то будуть перевірені тільки факти з вказаною базою фактів. Якщо файл містить ще що-небудь , окрім фактів зазначеної бази, то предикат consult, коли він дійде до цього рядка, поверне помилку.

Слід звернути увагу, що предикат consult зчитує по одному факту. Якщо файл містить десять фактів, а у сьомому факті є яка-небудь синтаксична помилка, consult занесе шість перших фактів в базу даних фактів, після чого видасть повідомлення про помилку.

Зазначимо, що предикат consult може зчитувати файли тільки в тому форматі, який створює save.

Файли не повинні містити:

- Символів верхнього регістру, за винятком тих, що містяться всередині рядків у подвійних лапках;

- Прогалин, за винятком тих, що містяться всередині рядків у подвійних лапках;

- Коментарів;

- Порожніх рядків;

- Ідентифікаторів (symbol) без подвійних лапок.

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

Видалення фактів під час виконання програми

Предикат retract уніфікує факти і видаляє їх з внутрішньої бази фактів.

Він має наступний формат:

retract(<the fact>) %(i)

Предикат retract видаляє перший факт з вашої бази даних, який збігається з фактом <the fact>, пов'язуючи вільні змінні <the fact> під час виконання програми. Видалення фактів з внутрішньої бази фактів еквівалентно процесу доступу до них з побічним ефектом видалення уніфікованих фактів.

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

Приклад 3. Видалення фактів під час виконання програми

У наступній програмі буде видалено перший факт person is Fred з бази фактів personDataBase.

Лістинг програми implement main

Б1126, 15

Б1126, 16

Б1126, 17

Б1126, 18

Рис. 3. Результат виконання програми з прикладу 3

Знищення декількох фактів відразу

Предикат retractall видаляє з вашої бази фактів всі факти, що збігаються із зразком <the fact>. Предикат retractall має наступний формат:

Б1126, 19

але значно швидше нього.

Предикат retractall завжди закінчується успішно. Із retractall вихідні значення отримати не можна. Це означає, що, як і у випадку not, потрібно використовувати символ підкреслення для вільних змінних.

Як у випадку предиката retract, якщо при викликанні retractall використовується символ підкреслення, то із зазначеного розділу class facts можна знищити усі факти.

Наступна ціль видаляє всі факти про чоловіків з бази фактів з фактами person:

retractall(person(_,’M’)).

Збереження бази фактів під час роботи програми

Предикат save зберігає факти з вказаної бази фактів (розділу class facts) у файлі. Перед використанням предиката consult необхідно підключити file наступним чином: open core,file

Цей предикат має один або два аргументи:

file::save(fileName) %(i)

file::save(fileName,databaseName) %(i,i)

При викликанні предиката save тільки з одним аргументом (без імені бази фактів), у файлі fileName будуть збережені факти з бази фактів dbasedom, що використовуються за замовчуванням.

При викликанні предиката save з двома аргументами (ім'я файлу і ім'я бази фактів), у вказаному файлі будуть збережені факти з розділу class facts бази фактів і іменем databaseName.

Приклад 4. Використання внутрішньої бази фактів

Програма в даному прикладі знищує із бази фактів факт

Б1126, 20

Б1126, 21

Лістинг програми implement main

Б1126, 22

Б1126, 23

Б1126, 24

Б1126, 25

Рис. 4. Результат виконання програми з прикладу 4

Завдання

Б1126, 26

Б1126, 27

На підставі лістингу виконати одне з наступних завдань в консольному додатку:

1. Видалити з «бази фактів» всі автомобілі. що мають забарвлення кольору «Red», які належать «Marlin» і є автомобілями виробництва «BMW». Додати в початок бази фактів автомобіль «Mercedes» моделі «240D» 1995 року випуску кольору «Green», власником якого є «Tom». Вивести дані з «бази фактів».

2. Видалити з «бази фактів» перший факт. який зустрінеться і задовольняє умові: бренд автомобіля «Mercedes», рік автомобіля 1974. Додати в кінець бази фактів автомобіль «BMW» моделі «E30» 1995 року випуску кольору «Green», власником якого є «Bill». Вивести дані з «бази фактів».

3. Видалити з «бази фактів» всі автомобілі моделі «E39» бренду «BMW» і належать «Marlin». Додати в кінець бази фактів автомобіль «Mercedes» моделі «240D» 1995 року випуску кольору «Blue», власником якого є «Jane». Вивести дані з «бази фактів».

Контрольні питання

1. Які предикати служать для додавання і видалення фактів?

2. Де зберігається вміст бази фактів при використанні предикатів save / 1, save / 2?

3. Перерахуйте обмеження на предикати, оголошені в розділі фактів.

4. Як називається внутрішня база фактів?

5. У чому відмінність між предикатами asserta, assertz, assert?

6. Які синтаксичні особливості існують для файлів з базою фактів?

7. Для чого використовуються предикати retract і retractall, і яка між ними відмінність?

8. Який предикат використовується для читання бази фактів з файлу?