
- •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. Стиль програмування.
10.Особливі технічні прийоми для професіоналів.
10.1.Потоковий аналіз.
Нагадаємо, що ми домовлялись вхідні (відомі) аргументи предикату позначати типом вводу (і) - input, а вихідні (невідомі) аргументи позначати типом (o) - output. Зразок вхідних і вихідних аргументів в предикаті будемо називати потоковим зразком (flow pattern). Наприклад, якщо предикат викликається з двома аргументами, тоді існує чотири можливості для потокового зразку: (i,i) (i,o) (o,i) (o,o)
При компіляції програми, Пролог виконує глобальний потоковий аналіз предикатів. Він починається з основної цілі. Потім він виконує псевдорозвиток всієї програми, під час якого прив'язує потокові зразки до всіх предикатних викликів в програмі.
Потоковий аналіз досить простий; фактично ми його виконуємо при написанні програми. Ось декілька прикладів:
goal: - curcor(R,C),
R1 = R + 1,
curcor(R1,C).
В першому виклику предикату cursor дві змінні R і C - вільні; що означає - предикат cursor буде викликатися потоковим зразком cursor (o,o). Змінні вільні, бо зустрічаються вперше. Аналізатор потоку взнає також, що, якщо змінна не використовується в голові фрази, тоді ця змінна буде вихідним аргументом в першому предикатному виклику в тілі фрази.
У виразі R1=R+1 аналізатор потоку встановлює, що змінна R прив'язана, тому що з'являється з предикату cursor. Якщо б вона була вільною, тоді б видавалось повідомлення про помилку. R1 стане після цього виклику відомим аргументом.
В останньому виклику cursor змінні R1 і С зустрічались попередньо, тому вони обробляються як аргументи входу, а виклик буде мати зразок потоку cursor (i,i).
Коли викликається предикат, визначений користувачем, тоді він обробляється аналогічно стандартному предикату. Наприклад,
predicates
changeattribute(Integer, Integer)
clauses
changeattribute(NewAttrib, OldAttrib):-
attribute(OldAttrib), attribute(NewAttrib).
goal
changeattribute(112, Old), write("Hello"),
attribute(Old), write("there").
В розділі goal перший виклик предикату changeattrib зроблено потоковим зразком типу changeattrib(i,o) (тому що перший аргумент відомий - 112, а другий Old - ні). Звідки, в фразі для changeattrib змінна NewAttrib буде аргументом входу, а OldAttrib - аргументом виходу. Але, якщо потоковий аналізатор зустрічає першу підціль attribute(OldAttrib), тоді предикат attribute буде викликатись потоковим зразком attribute (o), а другий виклик attribute буде мати потоковий зразок attribute(i). Кінцевий виклик attribute в goal будет мати потоковий зразок входу, тому що Old з'являється із changeattrib.
10.2.Керування потоковим аналізом.
Якщо потоковий аналізатор взнає, що стандартний предикат викликається не існуючим потоковим зразком, тоді видається повідомлення про помилку. Це може допомогти ідентифікувати нісенітні потокові зразки при створенні предикатів користувача, які використовують стандартні предикати. Наприклад, якщо ви використовуєте предикат
Z = X + Y
де змінна Х або Y не зв'язана, тоді потоковий анализатор видасть повідомлення про помилку: не існує потокового зразка для цього предикату. Для керування такою ситуацією ми можемо використовувати стандартні предикати free і bound.
Припустимо, ми хочемо написати предикат plus для реалізації дії додавання при любих можливих потокових зразках. Програма зображена на малюнку 10.1 реалізує такий предикат.
predicates
plus(integer, integer, integer)
num(integer)
clauses
plus(X,Y,Z) :- bound(X), bound(Y), Z=X+Y. /* (i,i,o) */
plus(X,Y,Z) :- bound(Y), bound(Z), X=Z-Y. /* (o,i,i) */
plus(X,Y,Z) :- bound(X), bound(Z), Y=Z-X. /* (i,o,i) */
plus(X,Y,Z) :- free(X), free(Y),
bound(Z), num(X), Y=Z-X. /* (o,o,i) */
plus(X,Y,Z) :- free(X), free(Z),
bound(Y), num(X), Z=X+Y. /* (o,i,o) */
plus(X,Y,Z) :- free(Y), free(Z),
bound(X), num(Y), Z=X+Y. /* (i,o,o) */
plus(X,Y,Z) :- free(X), free(Y),free(Z),
num(X), num(Y),Z=X+Y. /* (o,o,o) */
/* Генератор чисел, які починаються з нуля */
num(0).
num(X) :- num(A), X = A+1.
Мал.10.1.