
- •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.7. Задача про n королев.
Задача про N королев формулюється наступним чином. Потрібно розставити на шахматній досці N королев таким чином , щоб ніякі дві королеви не змогли побити одна одну згідно правил гри в шахи. Тому, ніякі дві королеви не можуть бути розміщені в одному ряду: по вертикалі , горизонталі , діагоналі.
Для вирішення задачі, пронумеруємо вертикальні та горизонтальні рядки шахматної доски від 1 до N. Для нумерації діагоналі , розділимо їх на два типи таким чином , щоб діагональ специфицифікувалась типом і номером, які обчислюються із її вертикальних і горизонтальних рядів:
Diagonal = N + Column - Row (type 1)
Diagonal = Row + Column - 1 (type 2)
Якщо ви дивитесь на шахматну доску на ряд 1 по горизонталі та колонку 1 по вертикалі з лівої сторони , тоді Tun1 розділяє діагоналлю клітку як символ похилої риски вліво (\), а Tun2 - вправо (/). Малюнок9.5. демонструє нумерацію діагоналей Tunу2 на досці 4х4.
| 1 | 2 | 3 | 4 |
1 | 1 | 2 | 3 | 4 |
2 | 2 | 3 | 4 | 5 |
3 | 3 | 4 | 5 | 6 |
4 | 4 | 5 | 6 | 7 |
Мал. 9.5. Нумерація діагоналей Типу2 на шахматній досці.
Для вирішення задачі про N королев на Пролозі, ми повинні вміти встановлювати який рядок, колонка і діагональ ще не зайняті , а також вміти відмічати де вже розміщені королеви.
Позицію королеви можна описати за допомогою зазначення номера рядка та колонки:
queen = q(integer, integer) .
Такий опис задає позицію одної королеви. Для фіксації більшої кількості позицій, можемо використать список:
queens = queen* .
Нам, також, будуть потрібні декілька списків чисел, які будуть визначати ще не зайняті королевами ряди , колонки та діагоналі. Ці списки опишемо наступним чином:
freelist = integer* .
Шахматну дошку зможемо обробляти як єдиний об'єкт, якщо зробимо наступний опис:
board = board(queens, freelist,freelist,freelist,freelist)
де чотири аргументи типу freelist задають відповідно ряди, колонки та діагоналі Типу1 і Типу2.
Наприклад, шахматну доску 4х4 без королев можна задать:
board([],[1,2,3,4],[1,2,3,4],[1,2,3,4,5,6,7],[1,2,3,4,5,6,7]),
а шахматну доску з однією королевою в самому лівому верхньому кутку опише предикат:
board([q(1,1)],[2,3,4],[2,3,4],[1,2,3,4,5,6,7],[2,3,4,5,6,7])
Накінець, ми можемо вирішити поставлену задачу, описуючи відношення між пустою доскою і доскою з N королевами. Визначимо предикат placeN(integer, board, board) з двома фразами. Королеви розташовуються одна за одною, поки кожний рядок і кожна колонка не будуть зайняті. Тому в першій фразі два списки freerows і freecols - пусті:
placeN(_, board(D,[],[],X,Y), board(D,[],[],X,Y)):- !.
placeN(_, Board1, Rеsult):-
place_a_queen(N, Board1, Board2),
place_N(N, Board2, Result).
В другій фразі предикат place_a_guun описує зв'язок між Board1 і Board2. В Board2 на одну королеву більше, ніж в Board1. Для опису предикату можемо використати наступну декларацію:
plase_a_queen(integer, board, board)
Тому суть задачі з N королевами заключається в тому, щоб описати , як можна розмістити максимальну кількість королев на досці, починаючи з пустої доски. Реалізовувать таке поповнення королев будемо через поповнення списку новою королевою : [q(R,C) | Queens].
Для розміщення наступної королеви нам потрібно серед вільних рядів Rows знайти ряд R, в якому ми зможемо розмістити королеву. Потім видалимо R і з списку вільних рядів NewR. Цю роботу буде виконувати предикат:
findandremove( R, Row, NewR) .
Аналогічні дії ми повинні зробити і з вакантною колонкою С. Із R і C ми також можемо обчислити номера зайнятих діагоналей. А потім ми зможемо визначити чи є серед D1 і D2 вільні діагоналі.
place_a_gueen( N,
board(Queens,Rows,Columns,Dig1,Dig2),
board([q(R,C) | Queens],NewR,NewS,NewD1,NewD2)):-
findandremove( R, Rows, NewR),
findandremove( C, Columns, NewC),
D1 = N + S + R,
findandremove(D1, Diag1, NewD1),
D2 = R + S - 1,
findandremove(D2, Diag2, NewD2).
Далі ми приводимо повну програму, яка містить тільки декілька добавок. Ці добавки розраховані на те, щоб ви одним викликом:
goal: nqueens(5), могли задати пошук рішення для розміщення п'яти королев на досці 5х5.
domains
queen = q(integer, integer)
queens = queen*
freelist = integer*
board = board(queens, freelist, freelist, freelist,
freelist)
predicates
placeN(integer, board, board)
place_a_queen(integer, board, board)
nqueens(integer)
makelist(integer, freelist)
findandremove(integer, freelist, freelist)
nextrow(integer, freelist, freelist)
clauses
nqueens(N) :-
makelist(N, L),
Diagonal = N*2-1,
makelist(Diagonal, LL),
placeN(N, board([], L, L, LL, LL), Final),
write(Final).
placeN(_,
board(D, [], [], D1, D2),
board(D, [], [], D1, D2)):- !.
placeN(N, Board1, Result) :-
place_a_queen(N, Board1, Board2),
placeN(N, Board2, Result).
place_a_queen(N,
board(Queens, Rows, Columns, Diag1, Diag2),
board([q(R,C)|Queens], NewR, NewC, NewD1, NewD2)):-
nextrow(R, Rows, NewR),
findandremove(C, Columns, NewC),
D1 = N+C-R,
findandremove(D1, Diag1, NewD1),
D2 = R+C-1,
findandremove(D2, Diag2, NewD2).
findandremove(X, [X|Rest], Rest).
findandremove(X, [Y|Rest], [Y|Tail]):-
findandremove(X, Rest, Tail).
makelist(1, [1]).
makelist(N, [N|Rest]) :- N1 = N-1,
makelist(N1, Rest).
nextrow(Row, [Row|Rest], Rest).
Вправи.
9.1.Написати програму, яка моделює роботу недетермінованого скінченного автомату.
9.2.Напишіть програму, яка зливає два впорядковані списки в один впорядкований список.
9.3.Граф називається зв`язаним, якщо між довільними двома вершинами існує шлях. Нехай G=(V,E’), де E’ така підмножина Е, що
1) Т - зв`язний граф
2) в Т не має циклів
Написати предикат остдерево(G,T), де Т - остове дерево G.
9.4.Розглянемо наступну задачу планування. Маємо набір задач t1, t2, ..., які мають час виконання відповідно Т1, Т2, ... . Всі задачі потрібно обробити на m ідентичних процесорах. Кожна задача може бути вирішена на довільному процесорі, але в кожний даний момент часу кожний процесор вирішує тільки одну із задач. Між задачами існує відношення порядку, яке визначає, котрі з задач (якщо такі є), мають бути завершені, перш ніж дана задача може бути оброблена. Потрібно розподілити задачі між процесорами таким чином, щоб не порушити відношення порядку, причому так, щоб вся сукупність задач була вирішена за мінімальний час.