- •Міністерство освіти і науки України Дніпропетровський національний університет
- •Програмування мовою пролог
- •Дніпропетровськ
- •1. Основи мови програмування пролог
- •1.1. Основні поняття
- •1.2. Синтаксис мови пролог
- •1.3. Класифікація даних у пролозі
- •1.4. Приклад доказу в пролозі
- •1.5. Подання задачі у вигляді і-або дерева
- •1.6. Структура програми в системі tp
- •1.7. Убудовані типи даних мови tp
- •1.8. Висновки
- •2. Підстави логічного програмування
- •2.1. Принцип резолюцій
- •2.3. Способи застосування принципу резолюцій
- •2.4. Диз’юнкти хорhа
- •3. Три семантичні моделі пролог-програми
- •4. Подання знань
- •4.1. Процес подання знань
- •4.2. Способи подання бази знань
- •4.2.1. Представлення цілісних інформаційних елементів у вигляді фактів
- •4.2.2. Подання атрибутів у вигляді фактів
- •4.2.3. Представлення знань у вигляді списку структур
- •4.2.4. Подання у вигляді рекурсивних структур
- •4.2.5. Подання у вигляді двійкового дерева
- •4.2.6. Порівняння різних виглядів подання бази даних
- •4.2.7. Компонування даних у список
- •4.3. Використання складених об'єктів
- •4.4. Використання альтернативних доменів
- •4.5. Засоби документування програми
- •4.6. Типи й властивості відношень предметної області
- •4.6.1. Обмеження, що забезпечують цілсність відношень
- •4.6.2. Властивості відношень бази знань і їхня підтримка в програмі на tp симетрія і асиметрія
- •Рефлексивность і нерефлексивность
- •Транзитивність
- •Симетричність і транзитивність
- •Спроба 1
- •Спроба 2.
- •Запам'ятовування списку відвіданих місць
- •4.7. Списки
- •4.7.1. Подання й зображення списків
- •4.7.2. Використання списків
- •4.7.3. Метод поділу списку на голову і хвіст (псгх)
- •4.7.4. Списки списків
- •Методи програмування
- •5.1. Повторення і відкіт (пв)
- •5.2. Метод відкоту після невдачі (впн)
- •5.3. Метод відсікання та відкоту (вв)
- •5.4. Повторення та рекурсія (пр)
- •5.5. Метод узагальненого правила рекурсії (упр)
- •5.6. Побудова рекурсивних структур методом прогресуючої підстановки (пп)
- •5.7. Предикат відсікання
- •5.8. Організація багаторазово виконуваних інтерактивних програм (бвіп)
- •5.9. Метод аналізу станів (ас)
- •5.10. Метод організації висхідних рекурсивних обчислень (вро)
- •5.11. Комбінація спадних і висхідних рекурсивных обчислень (ксвро)
- •5.12. Предикат fail-if (not)
- •5.13. Предикат true
- •5.14. Модифікація бази даних (мбд)
- •5.15. Керування базою даних (кбд)
- •5.16. Глобальні змінні (гз)
- •5.17. Накопичування результатів у базі даних за допомогою вимушеного відкоту і глобальної змінної (нрввгз)
- •5.18. Метапрограмування (мп)
- •Список рекомендованої літератури
- •1. Основи мови програмування пролог 4
- •2. Підстави логічного програмування 14
- •3. Три семантичні моделі пролог-програми 20
- •4. Подання знань 23
- •Програмування мовою пролог
5.17. Накопичування результатів у базі даних за допомогою вимушеного відкоту і глобальної змінної (нрввгз)
Вимушений відкот використовується для того, щоб ПРОЛОГ вичерпним чином видавав усі можливі варіанти узгодження та повторного узгодження цілі. Результати, які механізм відкотів повинний був би знищити, ми можемо накопичувати за допомогою побічного ефекту дії предикатів assert і retract. Це накопичування реалізується процедурою, що структурується за допомогою запропонованого вище методу.
Приклад. Необхідно скласти процедуру, що підраховує кількість членів деякої організації. Для такого підрахунку ми повинні змусити ПРОЛОГ видавати усі варіанти узгодження цілі:
член_установи(Прізвище, Вік, Дані_про_сплату)
Це реалізується вимушеними відкотами. Для фіксації кількості погоджень нашої цілі ми будемо застосовувати лічильник, що буде являти собою твердження, збережене в базі даних ПРОЛОГу.
Нагадаємо, що таке змінна. Змінна - це відношення, що зв'язує ІМ'Я_ЗМІННОЇ зі ЗНАЧЕННЯМ_ЗМІННОЇ і, можливо, для типізованих мов, з ТИПОМ_ЗМІННОЇ. Таке відношення легко реалізувати в ПРОЛОЗі за допомогою факту “змінна (Ім'я, Значення)”.
Зі змінною можна виконувати такі дії:
за іменем змінної взяти її значення;
установити потрібне значення зазначеної змінної;
розірвати зв'язок імені змінної з її значенням (знищити змінну).
Для нашої задачі нам потрібний цілочисловий лічильник як змінна. Його можна реалізувати за допомогою таких тверджень:
установити_лічильник(Ім'я, Початкове_значення) :-
retractall( лічильник(Ім'я,_)),
assert( лічильник(Ім'я, Початкове_значення) ).
збільшити_лічильник(Ім'я, Приріст) :-
retract( лічильник(Ім'я, Старе_значення) ),
Нове_значення = Старе_значення + Приріст,
assert( лічильник(Ім'я, Нове_значення) ),
!.
знищити_лічильник(Ім'я, Кінцеве_значення) :-
retract( лічильник(Ім'я, Кінцеве_значення) ).
Ім'я лічильника необхідне для того, щоб можна було мати кілька лічильників з різними іменами. Відсікання в другому твердженні потрібне для того, щоб його виклик не був узгоджений повторно, що викликало б миттєве вилучення лічильника, тільки що внесеного туди третьою підцілью цього твердження.
Тепер можна реалізувати нашу задачу. Нехай у нашій процедурі “підрахунок_членів” буде два аргументи: перший – структура, другий – ціле число (відповідь на поставлене питання):
підрахунок_членів( член_установи(Прізвище, Вік, Дані_про_сплату), _) :-
установити_лічильник(число_членів, 0),
член_установи(Прізвище, Вік, Дані_про_сплату),
збільшити_лічильник(число_членів, 1),
fail.
підрахунок_членів(_, Лічильник) :-
знищити_лічильник(число_членів).
У першому твердженні реалізується початкове встановлення нуля на нашому лічильнику, а також збільшення його значення на одиницю при кожному новому узгодженні другої підцілі. У кінцевому результаті дана ціль дає відмову, залишаючи на лічильнику останнє його значення. Це значення визначається за допомогою другого твердження даної процедури.
Слід звернути увагу, що ім'я лічильника “число_членів” пишеться з маленької літери (це атом, а не змінна).
Структура такої програми типова для даного методу. Етап, що відповідає збору результатів, слідує за етапом унесення їх у базу даних ПРОЛОГу. Істотно, що всі внесені твердження насправді будуть вилучені на другому етапі. У противному разі програма могла б себе змінити, і, хоча вона була б здатна дати правильні результати при першому її запуску, надалі її результати були б помилковими.