Лабораторна робота №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 може виглядати так, як показано на прикладі:
У цьому прикладі можна використовувати предикат person таким же чином, як використовуються інші предикати (male). Єдина відмінність полягає в тому, що ви можете додавати і видаляти факти для предиката person під час роботи програми.
Слід відзначити наступні два обмеження на предикати, оголошені в розділі фактів:
- Дозволяється додавати в базу даних тільки факти, але не правила;
- Факти бази не можуть містити вільні змінні.
Допускається наявність декількох розділів class facts, але для цього потрібно явно вказати ім'я кожного розділу class facts.
Опис розділу class facts з іменем mydatabase створює базу даних фактів з ім'ям mydatabase. Якщо не давати імені внутрішній базі фактів, то за замовчуванням їй присвоюється стандартне ім'я dbasedom. Програма також може містити локальні безіменні розділи фактів, тільки якщо вона складається з єдиного модуля, який не оголошений як частина проекту. Імена предикатів бази фактів мають бути унікальними в модулі (вихідному файлі); в двох різних розділах class facts не можна застосовувати однакові імена предикатів. Аналогічно, не можна використовувати однакові імена предикатів в розділах class facts і class predicates. Однак імена предикатів, визначених у локальних class facts - розділах, є локальними для модуля, де вони оголошені, і не конфліктують з локальними іменами предикатів/фактів, оголошених в інших модулях.
Використання внутрішніх баз фактів
Оскільки Visual Prolog представляє реляційну базу даних як колекцію фактів, можна використовувати його в якості потужної мови запитів до внутрішніх баз фактів. Алгоритм уніфікації Visual Prolog автоматично вибирає факти з правильними значеннями для відомих аргументів і привласнює значення невідомим аргументам, поки його алгоритм пошуку з поверненням видає всі рішення для заданого запиту.
Доступ до внутрішньої базі фактів
Предикати, належать внутрішній базі фактів, доступні точно так само, як і інші предикати. Єдина видима відмінність полягає в тому, що оголошення таких предикатів розташовані в розділі class facts замість розділу class predicates.
Приклад 1. Доступ до внутрішньої бази фактів
Програма в даному прикладі знаходить всіх жінок.
Лістинг програми
Рис. 1. Результат виконання програми з прикладу 1
Оновлення внутрішньої бази фактів
Факти для предикатів бази фактів можуть бути визначені під час компіляції в розділі clauses, як це показано в останньому прикладі. Під час виконання факти можуть бути додані і видалені, використовуючи описані нижче предикати. Зверніть увагу, що факти, визначені під час компіляції в розділі clauses, також можуть бути видалені, вони нічим не відрізняються від фактів, доданих під час виконання. Стандартні предикати Visual Prolog для роботи з фактами: assert, asserta, assertz, retract, retractall, consult і save — можуть мати один або два аргументи. Необов'язковий другий аргумент являє собою ім'я внутрішньої бази фактів.
Позначення /1 і /2 після кожного імені предиката вказує необхідну кількість аргументів для даної версії предиката. Коментарі (такі як /* (i) */ і /* (о, i) */) показують потік (і) параметрів для цього предиката.
Занесення фактів під час виконання програми
Під час виконання факти можуть бути додані до внутрішньої бази даних фактів за допомогою предикатів: assert, asserta і assertz, або шляхом завантаження фактів з файлу за допомогою consult.
Існує три предиката для додавання одного факту під час виконання:
Предикат asserta вставляє новий факт до бази даних фактів перед наявними фактами для даного предиката, a assertz вставляє факти після наявних фактів даного предиката. Використання предиката assert дає результат, аналогічний виконанню assertz.
Оскільки імена предикатів бази фактів унікальні для модуля, для предикатів asserta і assertz завжди відомо, в яку базу даних фактів потрібно додавати факт. Однак для того, щоб забезпечити роботу з необхідною базою даних фактів, з метою перевірки типу можна використовувати необов'язковий другий аргумент.
Перший предикат наступного прикладу вставить факт про Suzanne, описаний предикатом person, після всіх фактів person, що зберігаються на поточний момент в пам'яті. Другий - факт про Michael перед всіма фактами предиката person. Третій — факт про John після всіх інших факторів likes в базі даних фактів likesDatabase, а четвертий вставить факт про Shannon в ту ж базу даних фактів перед всіма іншими фактами likes.
Після виклику цих предикатів база фактів буде виглядати так, як ніби ви почали роботу з наступними фактами: %Внутрішня база фактів — dbasedom person("Michael","New York",26).
Слід остерігатися випадково написаного коду, який стверджує один і той же факт двічі. Внутрішні бази фактів не передбачають ніякої унікальності, тому один і той же факт може з'являтися у внутрішній базі даних фактів багато разів. Однак версію assert з перевіркою на унікальність написати дуже просто.
Приклад 2. Додавання нових фактів в базу фактів
В наступному прикладі факт додається до бази, тільки якщо він є унікальним.
Лістинг програми
Рис. 2. Результат виконання програми із прикладу 2
Считування фактів з файлу
Предикат consult зчитує з файлу fileName факти, описані в розділі class facts, і вставляє їх у вашу програму в кінець відповідної бази фактів. Перед використанням предиката consult необхідно підключити file наступним чином:
Однак на відміну від 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
Рис. 3. Результат виконання програми з прикладу 3
Знищення декількох фактів відразу
Предикат retractall видаляє з вашої бази фактів всі факти, що збігаються із зразком <the fact>. Предикат retractall має наступний формат:
але значно швидше нього.
Предикат 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. Використання внутрішньої бази фактів
Програма в даному прикладі знищує із бази фактів факт
Лістинг програми implement main
Рис. 4. Результат виконання програми з прикладу 4
Завдання
На підставі лістингу виконати одне з наступних завдань в консольному додатку:
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. Який предикат використовується для читання бази фактів з файлу?