
- •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. Програмна реалізація лексикографічного впорядкування при символьному вхідному потоці.
- •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. Стиль програмування.
9.2. Макетування: задача маршрутизації.
Ця програма ілюструє особливості Прологу, які роблять його корисним при вирішенні задач макетування. Припустимо , ми хочемо створити систему, яка б допомогала вибрати маршрут при поїздці із одного міста в інше.
Початкову програму будемо використовувати для подальшого аналізу вирішення поставленої задачі.
Нас будуть цікавити питання типу:
* Чи існує пряма дорога з одного міста в інше?
* Які з міст знаходяться на віддалі меншій 10 км від конкретного міста?
Нехай ми будемо реалізовувати карту прототипу, зображену на мал.9.2.
KansasCity
O---------------
Gordon
O--------- O Houston --------O Tampa
Мал.9.2. Карта прототипу.
Наступна програма є класичним прикладом використання бектрекінгу і рекурсії для вирішення задачі планування маршруту.
domains
town = symbol
distance = integer
predicates
road(town, town, distance)
route(town, town, distance)
clauses
road(tampa, houston, 200).
road(gordon, tampa, 300).
road(houston, gordon, 100).
road(houston, kansas_city, 120).
road(gordon, kansas_city, 130).
route(Town1, Town2, Distance) :-
road(Town1, Town2, Distance).
route(Town1, Town2, Distance) :-
road(Town1, X, Dist1),
route(X, Town2, Dist2),
Distance=Dist1+Dist2, !.
Кожна фраза для предикату road є фактом, який описує дорогу із одного міста в інше, довжина якої визначається в кілометрах. Фрази route характеризують те, чи можна створити маршрут із одного міста в інше через декілька проміжних пунктів. Третій параметр визначає пройдену відстань між містами.
Предикат route визначається рекурсивно; маршрут може просто складатись із одного проміжку дороги ( перша фраза). В цьому випадку віддаль буде довжиною дороги. Ми також можемо сконструювати маршрут із Town1 в Town2, використовуючи проміжний пункт Х. Загальна віддаль буде тоді сумою віддалей між Town1 і Х а також із Х в Town 2, що й показано в другій фразі route.
При подальшому аналізі задачі на складнішій структурі міст приходимо до необхідності вирішення наступних проблем:
1.Пролог система не повинна вибирати маршрут, який приводить до відвідин одного міста двічі.
2.Попередження переміщень по колу, яке дасть впевненість в тому, що програма не прийде до нескінченного циклу. Ці проблеми досить просто можна вирішити, якщо ми в програмі створимо і будемо заповнювати, а потім аналізувати список міст, які вже були відвідані при прокладенні маршруту. Приклад реалізації такого списку приводиться далі.
9.3.Пригоди в дивних печерах.
Розв'яжемо модифіковану задачу пошуку шляху в лабіринті. Нехай ми маємо печеру з скарбами. Печера є лабіринтом галлерей, які з'єднують кімнати з монстрами та грабіжниками. В одній з кімнат знаходяться скарби. Будемо вважати, що вам треба зайти в печеру, забрать скарби і вийти живим з лабіринту. Розглянемо наступну карту печери:
Мал. 20.2. Лабіринт галлерей.
domains
room = symbol
roomlist = room*
predicates
gallery(room, room) /* існує коридор */
/* між двома кімнатами */
neighborroom(room, room) /* Визначення */
/* сусідських */
/* кімнат */
avoid(roomlist)
go(room, room)
route(room, room, roomlist) /* Тут roomlist */
/* містить кімнати */
/* відвідані */
member(room, roomlist)
clauses
gallery(entry, monsters).
gallery(entry,fountain).
gallery(fountain, hell).
gallery(fountain, food).
gallery(exit, gold_treasure).
gallery(fountain, mermaid).
gallery(robbers, gold_treasure).
gallery(fountain, robbers).
gallery(food, gold_treasure).
gallery(mermaid, exit).
gallery(monsters, gold_treasure).
gallery(gold_treasure,exit).
neighborroom(X, Y) :- gallery(X, Y).
neighborroom(X, Y) :- gallery(Y, X).
avoid([monsters, robbers]).
go(Here, There) :- route(Here, There, [Here]).
go(_, _).
route(Room, Room, VisitedRooms) :-
member(gold_treasure, 6 0VisitedRooms),
write(VisitedRooms), nl.
route(Room, Way_out, VisitedRooms):-
neighborroom(Room, Nextroom),
avoid(DangerousRooms),
not(member(NextRoom, DangerousRooms)),
not(member(NextRoom, VisitedRooms)),
route(NextRoom, Way_out, [NextRoom|VisitedRooms]).
member(X, [X|_]).
member(X, [_|H]) :- member (X, H).
Кожна печера описана фактом. Предикати go і route задають правила. Задавши програмі ціль go(entry,exit), отримаємо відповідь. Вона буде містити список кімнат, які ми повинні пройти, щоб забрати скарби і повернутись. Як ми і говорили, в попередньому розділі для усунення вад минулої програми використовується список уже пройдених кімнат. Ця дія виконується в рекурсивному предикаті route третім аргументом. Тому, якщо ви знаходитесь в кімнаті виходу, і цей список містить кімнату gold_treasure , тоді ви досягли поставленої мети.
Звернемо вашу увагу на наступне. Враховуючи нашу побудову предикату route, якщо задача може мати і декілька розв'язків, програма буде завжди видавати тільки один розв'язок. Для видачі всіх можливих розв'язків нам потрібно організувати бектрекінг за допомогою предикату fail в першому правилі визначення route:
route(Room,Room,VisitedRooms):-
member(gold_treasure, VisitedRooms),
write(VisitedRooms), nl, fail.