
- •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. Стиль програмування.
5.2.2.Приклад застосування функторів.
Не тільки аргументи, а також функтор може нести корисну інформацію, якщо ви визначаєте домейн з декількома альтернативними функторами. Розглянемо типічну задачу зсуву курсора на екрані терміналу. Ви можете заключити, що предикат повинен мати два аргументи: напрямок зсуву і відстань зсуву. В Пролозі ці аргументи можуть бути простими об'єктами. Програма, зображена на малюнку 5.1, демонструє як це можна зробити. Вона використовує предикат cursor(Row,Column), який робить дві речі:
1)інформує де знаходиться курсор, коли аргументи його вільні;
2)розміщує курсор у відповідну стрічку і стовбець екрану згідно значень аргументів.
domains
row, column, step = integer
movement = up(step);
down(step);
left(step);
right(step)
predicates
move_cursor(row, column, movement)
clauses
move_cursor(R, C, up(Step)) :- cursor(R, C),
R1=R-Step, cursor(R1, C).
move_cursor(R, C, down(Step)) :- cursor(R, C), R1=R+Step,
cursor(R1, C).
move_cursor(R, C, left(Step)) :- cursor(R, C), C1=C-Step,
cursor(R, C1).
move_cursor(R, C, right(Step)) :- cursor(R, C), C1=C+Step,
cursor(R, C1).
мал.5.1.
5.3.Приклад використання складних об'зктів.
Інша важлива властивість складного об'єкту дозволяє просто розглядати групу значень як один аргумент. Припустимо, що ви створюєте телефонний довідник у вигляді бази даних. В нього ви хочете занести номера телефонів друзів з датою їх народження. Для цього достатньо розглянути секцію:
predicates
birthday
Month Day Year
clauses
phone( concretic values).
phone( concretic values).
Перші 5 аргументів предикату можуть бути представлені у вигляді двох складних об'єктів типу:
person
/ \
First name Last name
Які ми можемо реалізувати у вигляді відношeнь:
person(First_name,Last_name)
birthday(Month,Day,Year)
Тоді ми можемо написати програму, яка дуже легко читається.
domains
name= person(sym,sym)
birthday=b_data(sym,integer,integer)
ph_numb = sym
predicates
phone_list(name,ph_numb,birth_day)
clauses
phone_list(person(ed,willas),''422-324'',b_data(...)).
phone .....
Вона також зручна для модификації. Наприклад, додавши до нашої програми кілька правил, ми можемо створювати список людей, день народження яких належить поточному місяцю (стандартний предикат data бере з комп'ютерного годинника поточну дату).
domains
name = person(symbol, symbol) /* (First, Last) */
birthday=b_date(symbol,integer,integer) /*(Month, Day,Year)*/
ph_num = symbol /* Phone_number */
predicates
phone_list(name, symbol, birthday)
get_months_birthdays
convert_month(symbol, integer)
check_birthday_month(integer, birthday)
write_person(name)
clauses
get_months_birthdays:- makewindow(1,7,7, " This Month's
Birthday List ", 0, 0, 25, 80),
write(" First name\t Last Name\n"),
date(_, This_month, _),
phone_list(Person, _, Date),
check_birthday_month(This_month, Date),
write_person(Person),
fail.
get_months_birthdays :- write("\n\n Press any key to
continue: "),
readchar(_).
write_person(person(First_name, Last_name)):-
write(" ",First_name, "\t\t ", Last_name), nl.
check_birthday_month(Mon, b_date(Month, _, _)) :-
convert_month(Month, Month1),
Mon = Month1.
phone_list(person(ed, willis), "767-8463", b_date(jan, 3,
1955)).
phone_list(person(benjamin, thomas), "438-8400",
b_date(feb, 5, 1985)).
phone_list(person(ray, william),"555-5653", b_date(mar,
3,1935)).
phone_list(person(thomas, alfred), "767-2223",
b_date(apr, 29, 1951)).
phone_list(person(chris, grahm),
"555-1212", b_date(may, 12, 1962)).
phone_list(person(dustin, robert), "438-8400", b_date(jun,
17, 1980)).
phone_list(person(anna, friend), "767-8463",
b_date(jun, 20, 1986)).
phone_list(person(brandy, rae),"555-5653", b_date(jul, 16,
1981)).
phone_list(person(naomi, friend), "767-2223", b_date(aug,
10, 1981)).
phone_list(person(christina, lynn), "438-8400",
b_date(sep, 25, 1981)).
phone_list(person(kathy, ann),
"438-8400", b_date(oct, 20, 1952)).
phone_list(person(elizabeth, ann), "555-1212", b_date(nov,
9, 1984)).
phone_list(person(aaron, friend), "767-2223",
b_date(nov, 15, 1987)).
phone_list(person(jennifer, caitlin), "438-8400",
b_date(dec, 31, 1981)).
convert_month(jan, 1).
convert_month(feb, 2).
convert_month(mar, 3).
convert_month(apr, 4).
convert_month(may, 5).
convert_month(jun, 6).
convert_month(jul, 7).
convert_month(aug, 8).
convert_month(sep, 9).
convert_month(oct, 10).
convert_month(nov, 11).
convert_month(dec, 12).
Як працює програма?
1. Спочатку, програма робить вікно на екрані дисплею для відображення результату.
2. Після, вона друкує заголовок у вікно, для полегшення інтерпретації результату.
3. Далі, в предикаті get_month_birthday за допомогою вмонтованого предикату date отримуємо значення поточного місяця.
4. Після, програма робить пошук по базі даних списку людей, які народилися в поточному місяці.
Знаходиться перша особа в базі даних. Виклик предикату phone_list(Person,_,Date) зв'язує ім'я і прізвище цієї особи з змінною Pеrson для співставлення функтору person з змінною Person. Виклик також зв'язує день народження цієї особи з змінною Date.
Відмітимо, що вам досить використання однієї змінної для запам'ятовування повного імені особи і однієї змінної для запам'ятовування повної дати дня народження. Це результат використання складних об'єктів.
5. Зараз програма може обробляти день народження особи, використовуючи змінну Date. Така обробка починається в наступній підцілі, де програма обробляє поточний місяць, який заданий числом і день народження особи в предикаті check_birthday_month.
6. Звернемо увагу на те, як цей процес проходить. Пролог викликає предикат check_birthday_month з двома змінними: перша змінна зв'язана з цілим, а друга - з функтором і його трьома аргументами. В голові правила, де визначається предикат check_birthday_month перший аргумент This_month зрівнюється з змінною Моn. Другий аргумент Date співставляється з b_date(Month,_,_). Це добре, оскільки він є тим же значенням об'єкту даних, яке ви обробляєте.
Оскільки всі наші дії пов'язані тільки з місяцем народження особи, в якості дня і року народження можуть виступати анонімні змінні.
7. Предикат check_birthday_month спочатку конвертує символьне позначення місяця в числове значення. Після, Пролог може порівняти значення поточного місяця з значенням місяця народження особи. Якщо порівняння задовольнилось, обробка може закінчуватись. Тому далі стоїть підціль fail. В іншому випадку Пролог-система починає бектрекінг для пошуку іншого розв'язку.
8.Наступна підціль write_person друкує повне ім'я особи до списку осіб, день народження яких належить поточному місяцю, підціль fail форсує бектрекінг.