Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Використання динамічної бази даних

Поиск

 

Як було зазначено в попередніх пунктах, динамічна БД знаходиться в розділі програми database (або facts). У ній розміщено факти, які можна змінювати, видаляти чи додавати до БД під час виконання програми.

Найбільш поширені такі вбудовані предикати для роботи з динамічною БД:

· assert(<facts_domain> Fact) – вставляє факт Fact у кінець динамічної БД, в якій зберігаються подібні факти;

· asserta(<facts_domain> Fact) – вставляє факт Fact на початок динамічної БД, у якій зберігаються подібні факти;

· assertz(<facts_domain> Fact) – аналог assert(<facts_domain> Fact);

· consult(STRING OSFileName) – зчитує факти з текстового файлу OSFileName в неіменовану динамічну БД;

· nondeterm retract(<facts_domain> Fact) – видаляє факт Fact із динамічної БД;

· determ retractall(<facts_domain> Fact) – видаляє всі факти Fact із динамічної БД;

· save(STRING OSFileName) – зберігає вміст неіменованої динамічної БД в текстовий файл OSFileName.

Повний список вбудованих предикатів для роботи з динамічною БД наведено в довідці з Visual Prolog у розділі Internal Facts Sections standard predicates.

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

 

Domains

dom_tovar = tovar(symbol,real,integer)

Database

Tovar(symbol tovar,real price,integer quantity)

Predicates

Start

Greeting

nondeterm input_tovar

nondeterm output_tovar

Clauses

Tovar(milk, 2.5, 100).

Tovar(butter, 10.5, 50).

Start:-

greeting, input_tovar, output_tovar,!.

Greeting:-

write("Введіть назви товарів, ціну, вартість у базу даних, наприклад tovar(\"tea\", 3.4, 100).",'\n',

"Назву товару введіть у лапках.","Для закінчення введення введіть крапку."), nl.

input_tovar:-

readchar(X),X='.',!.

input_tovar:-

readterm(dom_tovar, tovar(X,Y,Z)), assert(tovar(X,Y,Z)), input_tovar.

output_tovar:-

tovar(X,Y,Z), write(X," ",Y," ",Z), nl, fail.

Goal

Start.

Рекомендації щодо створення програм мовою Пролог

 

Для того щоб написання програми проходило якомога легше й швидше, необхідно спочатку продумати задачу, яку треба розв'язати. Часта помилка – намагання написати програму навіть до того, як стала повністю зрозуміла докладна постановка задачі. На цьому етапі знаходять загальний спосіб розв’язання задачі.

Відповідно до рекомендацій знаного фахівця І. Братка трансформацію знайденого загального способу розв’язання задачі в програму можна здійснити, застосовуючи принцип покрокової деталізації. Загальний спосіб розв’язання задачі І. Братко розглядає як розв’язання верхнього рівня, а остаточну програму – як розв’язання найнижчого рівня.

Остаточну програму одержують після серії деталізацій розв’язання. На кожному кроці деталізації розв’язання стає все більш і більш детальним, поняття – більш повними, а їх подання наближається до мови програмування. У випадку мови Пролог можна говорити про покрокову деталізацію відношень (або предикатів).

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

На нульовому кроці деталізації просто позначимо виконання поставленого завдання через предикат start. Очевидно, що ця програма повинна забезпечувати принаймні дві дії – введення користувачем інформації про новий товар у БД і виведення БД на екран. Можна також забезпечити і початкове привітання програмою користувача. Отже, на першому кроці деталізації закріпимо кожну з цих трьох дій за їх власними предикатами, наприклад: greeting, input_tovar, output_tovar. Таким чином, предикат start ми деталізували до трьох предикатів.

На другому кроці деталізуємо кожен із цих предикатів. Нехай предикат greeting виводить пояснювальний напис до програми, що можна реалізувати за допомогою вбудованого предиката виведення write().

Предикат input_tovar повинен забезпечувати введення з клавіатури певних даних, у яких міститься інформація про товар, і занесення їх у БД. Нехай дані про товар будуть знаходитися в структурі tovar(symbol tovar,real price,integer quantity), де першим аргументом буде назва товару, другим – ціна, третім – кількість товару. Отже, предикат input_tovar уможливлюватиме введення з клавіатури довільної кількості структур типу tovar, невідомої заздалегідь. Таким чином, цей предикат треба реалізувати як циклічний процес, наприклад, через рекурсивну процедуру (див. розд. 2.7).

Рекурсивна процедура зазвичай складається з двох правил – першого, нерекурсивного, і другого, рекурсивного. Нехай вихід із рекурсії буде відбуватися після введення крапки. Тоді перше правило можна буде записати так:

input_tovar:-

readchar(X),X='.',!.

У другому, рекурсивному, правилі треба спочатку ввести терм tovar з клавіатури, потім вставити цей факт у БД і знову викликати предикат input_tovar. Отже, друге правило зможемо записати таким чином:

input_tovar:-

readterm(dom_tovar, tovar(X,Y,Z)), assert(tovar(X,Y,Z)), input_tovar.

Предикат output_tovar повинен знаходити всі факти tovar у БД і виводити їх на екран, тобто це також циклічний процес. Реалізуємо його за допомогою предиката fail:

output_tovar:-

tovar(X,Y,Z), write(X," ",Y," ",Z), nl, fail.

 

Завдання 2

Розв'язати задачі, аналогічні поданим у завданні 1 (див. розд. 2.5), з урахуванням того, що родинне дерево з фактами повинне знаходитися в динамічній БД. Користувач має сам заповнити цю БД під час виконання програми, а потім записати її у файл. Треба забезпечити можливість у подальшому зчитувати її з файлу. Програма повинна мати меню, яке дозволяє виконувати команди користувача, наприклад:

1) заповнити БД;

2) записати БД у файл;

3) зчитати БД із файлу;

4) знайти прадіда;

5) закрити програму.

 

Рекурсивні структури даних

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

Найчастіше вживана рекурсивна структура – список, але ми його розглянемо пізніше. У цьому розділі ми зосередимо свою увагу на структурі даних типу дерево і на її використанні.

 

Структура даних типу дерево

 

Серед структур даних типу дерево можна виділити спеціальний клас найчастіше використовуваних дерев – бінарні дерева. Можна дати рекурсивне визначення бінарного дерева:

1) порожнє дерево – бінарне дерево;

2) кожний вузол бінарного дерева має не більше одного лівого бінарного піддерева і не більше одного правого бінарного піддерева.

Таку структуру даних у мові Пролог можна визначити за допомогою двох предикатів: treetype = tree(string,treetype,treetype) та empty. Останній використовують для позначення порожнього дерева. Тому структуру даних для задання бінарного дерева можна описати таким чином:

Domains

treetype= tree(string, treetype,treetype);

Empty

Наприклад, дерево зображене на рис. 8, можна описати так:

 

tree("Перро",tree("Грімм",tree("Гауф",empty, empty),

tree("Лондон",empty, empty)),

tree("Кіплінг", tree("Уайльд",empty, empty),

tree("Лагерлеф",empty, empty)))

 

 

Рис. 8. Приклад дерева

 

Зазначимо, що це не є прологівська фраза; це тільки складна структура даних.

 

Обходи дерева

 

Існує багато правил обходу дерев: прямий, зворотний, кінцевий і т. д. Розглянемо, наприклад, алгоритм прямого обходу.

1. Якщо дерево порожнє, тоді нічого не робити.

2. У противному разі обробити поточний вузол, потім обійти ліве піддерево обробленого вузла, а потім обійти праве піддерево обробленого вузла.

У мові Пролог цей алгоритм реалізують за допомогою двох фраз:

Traverse(empty).



Поделиться:


Последнее изменение этой страницы: 2016-04-08; просмотров: 386; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.225.54.199 (0.006 с.)