- •Логічне програмування
- •Логічне програмування
- •7.080403 - “Програмне забезпечення автоматизованих систем”
- •Лабораторна робота № 1. Пролог - мова логічного програмування.
- •1.1.Загальний огляд мови Пролог.
- •1.2.Переваги і недоліки мови Пролог.
- •1.3.Числення предикатів - математична основа мови.
- •1.4.Побудова теорії деякої області знань.
- •1.5.Від формальної логіки до логічного програмування.
- •1.6.Механізм логічного виведення і керування пошуком.
- •Лабораторна робота №2 основні концепції прологу
- •2.1.Факти та правила.
- •2.2.Як змінні отримують свої значення.
- •2.3.Анонімні змінні.
- •2.4.Складні цілі: кон`юнкція та диз`юнкція.
- •2.5.Способи Співставлення.
- •Лабораторна робота № 3 структура програми pdc прологу
- •3.1.Основні розділи програми.
- •3.2 Стандартні домени.
- •3.3.Синтаксис правила.
- •3.4.Директиви комп`ютеру.
- •3.5.Бектрекінг.
- •3.5.1.Бектрекінг з внутрішньою ціллю.
- •Лабораторна робота № 4 контроль пошуку рішень
- •4.1.Використання предикату fail.
- •4.2.Відміна бектрекінгу.
- •1.Коли ви знаєте попередньо, що певні варіанти ніколи не дадуть поштовху в знаходженні розв'язку, тоді використання cut(зелений cut) відкидає перегляд альтернативних шляхів.
- •2.Коли логіка програми потребує використання cut для відкидання перегляду альтернативних підцілей, тоді його називають червоним відтинанням.
- •4.3.Предикат not - заперечення як неуспіх.
- •4.4.Труднощі у використанні відтинання і заперечення.
- •4.5.Засоби керування.
- •4.6.Узагальнення.
- •Лабораторна робота №5. Прості та складні об'єкти.
- •5.1 Прості дані.
- •5.1.1. Константи як об'єкти даних.
- •5.2.Складні об'єкти даних і функтори.
- •5.2.1.Уніфікація складних об`єктів.
- •5.2.2.Приклад застосування функторів.
- •5.3.Приклад використання складних об'зктів.
- •5.4.Опис доменів складних об'єктів.
- •5.5.Багаторівневі складні об'єкти.
- •5.6.Приклад, який ілюструє задання структури речення англійської мови.
- •5.7.Опис змішаних складних об'єктів.
- •5.7.1.Аргументи, які можуть мати різний тип.
- •5.7.2 Cписковий тип.
- •5.8.Порівняння складних об`єктів.
- •5.9.Узагальнення.
- •Лабораторна робота №6. Ітерація і рекурсія.
- •6.1.Реалізація ітераційного процесу за допомогою бектрекінгу.
- •6.2.Дії типу до і після.
- •6.3.Застосування бектрекінгу для реалізації циклів.
- •6.4.Рекурсивні процедури.
- •6.5.Використання аргументів в якості параметрів циклу.
- •Лабораторна робота №7 рекурсивні структури даних
- •7.1.Структура даних типу дерева.
- •7.2.Обходи дерева.
- •7.3.Створення дерева.
- •7.4.Бінарний пошук на дереві.
- •7.5. Сортування по дереву.
- •7.5.1 Програмна реалізація лексикографічного впорядкування при символьному вхідному потоці.
- •Лабораторна робота № 8 робота з списками в пролозі
- •8.1.Рекурсивна сутність списку.
- •8.2.Обробка списків.
- •8.2.1.Друк списків.
- •8.2.2.Підрахунок кількості елементів.
- •8.2.3.Іще один варіант підрахунку довжини списку.
- •8.2.4.Модифікація списку.
- •8.2.5.Належність елемента списку.
- •8.3.Використання одного й того ж предикату для вирішення різних задач.
- •8.4. Знаходження зразу всіх розв`язків.
- •8.5.Складні списки.
- •8.6.Реалізація синтаксичного аналізу за допомогою списків.
- •Лабораторна робота №9 техніка програмування в пролозі
- •9.1.Принципи побудови експертної системи.
- •9.2. Макетування: задача маршрутизації.
- •9.3.Пригоди в дивних печерах.
- •9.4. Моделювання апаратних засобів.
- •9.5.Задача про ханойські башні.
- •9.6.Ділення слів на склади.
- •9.7. Задача про n королев.
- •Лабораторна робота №10 особливі технічні прийоми для професіоналів
- •10.1.Потоковий аналіз.
- •10.2.Керування потоковим аналізом.
- •10.3. Стиль програмування.
8.4. Знаходження зразу всіх розв`язків.
Як ми вже зазначали раніше, для задання ітераційних процесів в Пролозі, використовується бектрекінг, або ж рекурсія. Рекурсія - більш потужніший засіб. Вона, використовуючи апарат формальних аргументів, може передавати інформацію від одного виклику до іншого. Іншими словами, рекурсія дозволяє відсліджувати часткові результати, аналізувати лічильники.
Але іноді виникає проблема, яку важко вирішити і за допомогою рекурсії. Нехай вам потрібно знайти зразу всі розв`язки задоволення цілі, як частини єдиної складної структури даних. Пролог вирішує дану проблему за допомогою предикату findall, який приймає ціль як один із своїх аргументів, збираючи всі розв'язки цієї цілі в один список.
Предикат findall має три аргументи:
- Перший аргумент VarName визначає який з аргументів в зазначеному предикаті потрібно відібрати в список;
- Другий, Мypredicate, визначає предикат, з якого будуть збиратись значення;
- Третій аргумент, ListParam, з змінною, якою позначається список значень, зібраних через перебір з поверненнями.
Зазначимо, що попередньо повинна бути визначена область, до якої повинні належати значення ListParam.
Наступна програма використовує findall, для визначення середнього віку групи людей.
domains
name, address = string
age = integer
list = age*
predicates
person(name, address, age)
sumlist(list, age, integer)
goal
findall(Age, person(_, _, Age), L),
sumlist(L, Sum, N),
Ave = Sum/N,
write("Average =", Ave), nl.
clauses
sumlist([], 0, 0).
sumlist([H|T], Sum, N) :- sumlist(T, S1, N1), Sum=H+S1,
N=1+N1.
person("Sherlock Holmes", "22B Baker Street", 42).
person("Pete Spiers", "Apt. 22, 21st Street", 36).
person("Mary Darrow", "Suite 2, Omega Home", 51).
В цій програмі фраза findall створює список L, який містить числа, які відповідають віку всіх людей з предикату person. Якщо ви бажаєте зробити список людей вік яких 42 роки, тоді ви можете написати ціль
findall(Who, person(Who,_,42), List).
8.5.Складні списки.
Часто вам потрібно зберігати комбинацію різних типів елементів всередині одного списку, як наприклад
[2,3,5,12,[food,"goo"], "new"]
Складними будемо називати списки, які містять більше одного типу аргументів. Нам будуть потрібні спеціальні декларації, щоб обробити списки багатотипних елементів, тому що Пролог вимагає, щоб всі елементи списку належали одній області. Для опису різнотипних списків потрібно використовувати функтори.
Наступний приклад декларації області для списку, який може мати символ, ціле число, літеру, стрічку або ж список із них. Декларація списку повинна мати функтор, а потім повинна бути декларована рекурсивно. Так, попередній список повинен бути описаний:
domains
llist = l(list); s(symbol); i(integer); c(char); t(string)
list = llist *
І буде задаватись в Пролозі:
[i(2),і(3),i(5),i(12), [c(food),s(“goo”)],s(“new”)]
Наступний приклад з предикатом append показує як використовувати такий опис:
domains
llist = l(list); s(symbol); i(integer); c(char); t(string)
list = llist *
predicates
append(list, list, list)
goal
makewindow(1,7,7, "answer",15,0,8,80),
/*Note how you can use the same code but need functors *
* append([likes,[bill,mary]],[bill,sue],Ans) */
append([s(likes),l([s(bill),s(mary)])],[s(bill),s(sue)],Ans), */
write("First List:", Ans), nl,nl,
/*The trick is to write the list first, than add the functors *
* append([apple,[[[47], '\1']], [[["This is a string",b,7, *
* 'w']],bee], ['c'], Ans2) */
*
append([l[s("This"), s("is",s("a"),s("list"))]), s(bee)],
[c('c')], Ans2),
write("Second List :", Ans2), nl.
clauses
/* Concatenate two lists */
append([], L, L).
append([X|L1], L2, [X|L3]) :- append(L1, L2, L3).
