Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Метод_Пролог_Етап2_10.doc
Скачиваний:
14
Добавлен:
23.03.2015
Размер:
1.57 Mб
Скачать

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

Як було зазначено в попередніх пунктах, динамічна БД знаходиться в розділі програми 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.

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

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

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

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

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

На нульовому кроці деталізації просто позначимо виконання поставленого завдання через предикат 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.