
- •1. Вступ в логічне програмування
- •1.1. Виникнення логічного програмування
- •1.2. Сучасний стан логічного програмування
- •Опис задачі на пролозі. Факти і правила
- •2.1. Опис задачі на пролозі
- •2.2. Факти
- •Цільове твердження
- •Умовні твердження
- •Приклад програми на пролозі
- •2.6. Виконання програми на пролозі
- •2.7. Статична та динамічна бази даних
- •2.8. Підготовка фактів для внутрішньої бази даних
- •2.9. Опис фактів внутрішньої бази даних
- •2.10. Предикати роботи з внутрішньою базою даних
- •2.11. Приклади використання внутрішньої бази даних
- •3. Основні поняття visual-prolog
- •3.1. Загальні відомості
- •3.3. Домени елементарних об’єктів
- •3.4. Терми
- •3.4.1. Константа
- •Анонімна змінна
- •3.4.3. Структури
- •3.5. Програма на пролозі
- •4. Механізми прологу
- •Механізм узгодження цілі з базою даних
- •4.2. Механізм звороту
- •4.3. Механізм звороту і відсік
- •4.4. Рекурсія
- •4.4.1. Рекурсивний метод розв’язку задач
- •Рекурсивні методи 2-х доменів:
- •Застосуємо висхідний метод рекурсії до розв’язку задачі:
- •Висхідна рекурсія
- •4.4.4. Предикат repeат
- •Міркування про те, як треба писати програму
- •5. Обробка рядків
- •5.1. Загальні відомості
- •1.1 Стандартні предикати обробки рядків
- •5.3. Лексиграфічне порівняння рядків
- •2Низхідна рекурсія
- •6.1. Метод низхідної рекурсії
- •6.2. Загальна характеристика рекурсивних методів
- •6.3. Низхідна та висхідна рекурсії
- •7. Робота зі списками
- •7.1. Списки. Оголошення списків
- •7.2. Увід-вивід списків
- •7.3. Основна операція на списках
- •7.4. Формування списків стандартним предикатом
- •Процедура з’єднує два списки.
- •Процедура розділяє список на два за вказаним елементом.
- •2.1 Сортування списків на пролозі
- •Сортування методом пухирця
- •7.8. Складені списки
- •8. Предикати вводу-вивіду
- •8.1. Предикати вводу
- •8.2. Предикати виводу
- •9. Файли
- •9.1. Символічне ім’я файлу
- •9.2. Вхідний і вихідний потоки
- •9.3. Організація файлу та методи доступу до файлу
- •9.4. Робота з файлами різними методами доступу
- •9.5. Закриття файлу
- •9.6. Предикати роботи з каталогами
- •9.7. Предикати, що працюють з атрибутами файлів
- •Література
Процедура з’єднує два списки.
Ціль: Перші два аргументи конкретизовані списки, третій аргумент вільна змінна.
Приклад :
Domains
List = integer*
Predicates
pr (list, list, list)
Clauses
pr ([ ], L, L),
pr ([Н | L1], L2, [Н | L3]): - pr (L1, L2, L3).
Goal pr([1,2], [4,5], L).
Робота процедури
Ціль не може бути зіставлена з фактом, тому що перший аргумент факту порожній список.
Ціль зіставляється з головою правила. Змінні Н першого і третього аргументу конкретизуються 1, а L1 конкретизується списком [2]. L2 конкретизується списком [4,5]. Змінна L3 третього аргументу невизначена, тому відбувається зчеплення вільної змінної L з цілі з наполовину визначеною структурою [1 | L3] із голови правила.
Значення змінних передаються в тіло правила. Нова поточна ціль стане: pr([2],[4, 5],L3).
Таким чином, щоб з'єднати списки [1,2] і [4, 5] потрібно спочатку відкинути голову першого списку і з'єднати списки [2] і [4, 5].
Процедура рекурсивно викликається знову. В змінні Н першого і третього аргументів голови правила попадає 2, а в L1 – порожній список. Список [4, 5] як і раніше конкретизує змінну L2.
Значення змінних передаються в тіло правила. Нова поточна ціль стане: pr([],[4, 5],L3).
Одержаний рекурсивний виклик зіставляється з фактом, перший аргумент - []. Другий і перший аргумент факту мають однакові імена, тому L3 одержує значення список [4, 5].
Див. Схему співставлення:
p
r
( [] L L)
pr ( [] [4, 5] L3)
Після зіставлення з фактом починається зворотний процес. До значення змінної L3, конкретизованої значенням [4, 5], поступово додаються елементи Н зі стеку і підіймаються через зчепленні змінні до цілі.
Результат: L = [1, 2, 4, 5].
Процедура розділяє список на два за вказаним елементом.
Ціль: Перший аргумент вільна змінна, яку буде конкретизовано першим списком. Другий аргумент структура, голова якої елемент, що розбиває список на два підсписки, а хвіст структури вільна змінна, яка буде конкретизована другим списком. Третій аргумент цілі список.
Domains
List = integer*
Predicates
pr (list, list, list)
Clauses
pr ([ ], L, L),
pr ([Н | L1], L2, [Н | L3]): - pr (L1, L2, L3).
Goal Pr (Do, [ 2 | Pisl ],[1,2,3]).
Робота процедури
Процедура розіб’є список [1,2,3] на списки [1] та [2,3]. Другий аргумент цілі задається структурою [ 2 | Pisl], щоб приєднати „2” до другого списку.
Зіставлення цілі з фактом виявляється неможливим по такій причині. Другий і третій аргумент факту однакові змінні. В цілі голова списку другого аргументу 2, голова списку третього аргументу 1. Отже, списки другого і третього аргументів не однакові.
Відбувається зіставлення цілі з головою правила. Вільна змінна Do зчіплюється з структурою [H | L1], де Н та L1 вільні. Наполовину визначена структура [ 2 | Pisl ] зчіплюється з вільною змінною L2. Список [1,2,3] з третього аргументу цілі зіставляється зі структурою. В результаті змінна Н конкретизується 1, а хвіст L3 конкретизується [2,3].
Нова ціль у тілі правила буде: pr (L1, [2 | Pisl], [2,3]).
Така ціль зіставляється з фактом, бо другий і третій аргументи цілі можуть бути однаковими. В результаті L1 конкретизується порожнім списком, а змінна Pisl конкретизується хвостом цього списку [3]. Див. Схему:
p
r
( [] L L) факт
pr ( [] [2 [3]] [2,3]) ціль
Одержуємо: Do = [ 1 ]. Pisl = [3], [ 2 | Pisl ]= [ 2,3 ].
Процедура розділяє список на два підсписки, перебираючи всі можливі варіанти підсписків, елементи яких йдуть підряд. Для перебору, після використання одержаних підсписків, повинна стояти невірна умова.
Ціль: Перші два аргументи вільні змінні. Третій аргумент список.
Domains
List = integer*
Predicates
pr (list, list, list)
Clauses
pr ([ ], L, L),
pr ([Н | L1], L2, [Н | L3]): - pr (L1, L2, L3).
Goal pr (L1, L2, [1, 2, 3]), write(L1,L2), fail.
Робота процедури
Ціль зіставляється з фактом. Змінна L1 конкретизується []. Список [1, 2, 3] з цілі конкретизує третій і другий аргументи L з факту і тому L2 з цілі теж конкретизується цим списком.
Список [1,2,3] розбився на списки[ ] та [1, 2, 3] .
Після виводу списків предикат fail включає механізм звороту і звільнює аргументи L1 і L2.
Виконується зіставлення цілі з головою правила. У результаті H=1, L3=[2, 3]. Ціль в тілі правила стає: pr(L1, L2, [2,3])
Ціль зіставляється з фактом. Змінна L1 конкретизується [ ],
L2=[2, 3]. Аргументи предиката в голові правила стають: перший аргумент [1], другий аргумент [2,3].
Список [1,2,3] розбився на списки[ 1] та [ 2, 3] .
Далі процес повторюється. Список [1,2,3] розбивається на:
[1,2] та [3], [1,2,3] та [ ].
Процедуру використовують для знаходження певних підсписків. Ознака одержання певних підсписків буде працювати як fail, якщо підсписки не підходять. Наприклад, замість fail можна записати L2=[H| T],H>2. Тоді знайдуться такі підсписки [1,2] та [3].
Процедура "Вилучити" – вилучає вказаний елемент із списку. Процедура має два варіанти.
Процедура "вилучити1" – вилучає перший вказаний елемент, що зустрівся.
Goal
vuluch1(2, [1,2,2], L).
Clauses
vuluch1(_,[], []):-!. (1)
vuluch1(Х,[X|L1],L1):-!. (2)
vuluch1(Х,[Н|L1],[Н|L2]):- vuluch1(Х,L1,L2). (3)
Гранична умова (1) досягається, якщо елемент не знайдено. Результат співпадає з вхідним списком.
У граничній умові (2) вилучається знайдений елемент. Залишок списку переноситься у новий список.
Правило (3) переносить голову списку у новий список, якщо вона не співпадає з елементом, що вилучається. Після цього продовжується пошук елементу.
Процедура "вилучити2"- вилучає всі елементи списку, які співпадають з вказаним.
Goal
vuluch1(2, [1,2,2], L).
vuluch2(_,[],[]):-!. (1)
vuluch2(Х,[Х|L1],L2):- vuluch2(Х,L1,L2). (2)
vuluch2(Х,[Н|L1],[Н|L2]):- vuluch2(Х,L1,L2). (3)
Процедура ''вилучити2' відрізняється від процедури “вилучити1”, тим, що після того, як вилучено вказаний елемент, продовжує пошук вказаного елемента у хвості списку.