
- •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.6.Ділення слів на склади.
На прикладі вирішення цієї задачі продемонструємо можливості Прологу при обробці текстової інформації в редакторах.
Для вирішення задачі ділення слів на склади, будемо використовувати простий алгоритм, який базується на впорядкуванні голосних і приголосних в слові. Наприклад, розглянемо дві послідовності:
1) приголосна - голосна - приголосна. В цьому випадку, слово ділится після першої голосної:
ruler ---> ru-ler
prolog ---> pro-log
2) голосна - приголосна - приголосна. В цьому випадку , слово ділиться між двома приголосними:
number ---> num-ber
panter ---> pan-ter
Ці два правила добре застосовуються для більшості слів, але не працюють для слів типу handbook и hungry, які не підходять до жодного правила. Такі слова програма повинна обробляти спеціальним чином, наприклад використовувати бібліотеку таких слів.
Напишимо програму. Вона повинна запрошувати ввести слово, яке потрібно розбити на склади. Для застосування нашого алгоритму нам спочатку потрібно розбити слово на символи. Тому нам необхідний наступний опис:
domains
letter = symbol
word =letter*
Нам потрібно мати предикат, який визначає тип букви: голосна чи приголосна. Для розпізнання голосних використаємо набір фактів типу: vocal(a), vocal(e),...,vocal(y). Приголосна визначається як буква, яка не є голосною:
consonant(L):- not(vocal(L)).
Нам також будуть потрібні ще два предикати. Перший, типу:
append(word,word,word) і другий для перетворення стрічки символів в список символів:
string_word(string,word)
Цей предикат буде використовувати стандартний предикат frontchar, який має три параметри. Перший параметр з стрічкою, яка розбивається на дві частини: перший символ стрічки (визначається другим аргументом) і залишок стрічки (третій аргумент). Вмонтовані предикати free і bound визначають чи змінна є вільною чи зв'язною.
Зараз ми вже готові до вирішення основної задачі: визначити предикат divide, який разділяє слово на склади. divide має чотири пареметри і носить рекурсивний характер. Перший і другий аргументи визначають початкове слово, а третій і четвертий параметри визначають уже розбите слово.
Наприклад , перше правило для divide реалізується
divide(Start,[T1,T2,T3 | Rest], D, [T2,T3 | Rest]):-
vocal(T1), consonant(T2), vocal(T3),
append(Start, [T1], D),
де Start - це список першої групи символів слова, яке ми ділимо. Наступні три символи в слові задаються Т1,Т2 і Т3, тоді в Rest зберігаються символи, що залишились. Наприклад, при розбитті слова prolog, це правило задовольниться викликом:
divide([p,r], [o,l,o,g], P1,P2) ,
який перетвориться в
divide([p,r], [o,l,o, | [g]], [p,r,o], [l, o ,g ]) ,
тому що предикат append конкатенує першу голосну до кінця початкових літер слова. P1 становится прив'язаною до [p,r,o], а P2 прив'язана до [l,o,g]. Друге правило для divide реалізується в повній програмі:
domains
letter = char
word = letter*
predicates
divide(word, word, word, word)
vocal(letter)
consonant(letter)
string_word(string, word)
append(word, word, word)
repeat
goal
clearwindow,
repeat,
write("Write a multi-syllable word: "),
readln(S),
string_word(S, Word),
divide([], Word, Part1, Part2),
string_word(Syllable1, Part1),
string_word(Syllable2, Part2),
write("Division: ",Syllable1,"-",Syllable2),nl,
fail.
clauses
divide(Start, [T1, T2, T3|Rest], D1, [T2, T3|Rest]):-
vocal(T1), consonant(T2), vocal(T3), append(Start,
[T1], D1).
divide(Start, [T1, T2, T3, T4|Rest], D1,[T3, T4|Rest]):-
vocal(T1), consonant(T2), consonant(T3), vocal(T4),
append(Start, [T1, T2], D1).
divide(Start, [T1|Rest], D1, D2):-
append(Start, [T1], S),
divide(S, Rest, D1, D2).
vocal('a').vocal('e').vocal('i').
vocal('o').vocal('u').vocal('y').
consonant(B):-
not(vocal(B)), B <= 'z', 'a' <= B.
string_word("", []):-!.
string_word(Str, [H|T]):-
bound(Str), frontchar(Str, H, S), string_word(S, T).
string_word(Str, [H|T]):-
free(Str), bound(H), string_word(S, T),
frontchar(Str,H,S).
append([], L, L):-!.
append([X|L1], L2, [X|L3]) :-
append(L1, L2, L3).
repeat.
repeat :- repeat.