
- •Логічне програмування
- •Логічне програмування
- •7.080403 - “Програмне забезпечення автоматизованих систем”
- •Лабораторна робота № 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.1 Програмна реалізація лексикографічного впорядкування при символьному вхідному потоці.
- •Лабораторна робота № 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. Стиль програмування.
6.2.Дії типу до і після.
Можливо в попередній програмі треба для наглядності зробити наступні зміни:
1. надрукувати заголовок;
2. надрукувати всі можливі розв'язки запиту;
3. надрукувати в кінці заключне повідомлення.
Тоді нам потрібно в попередню програму внести наступні модифікації в визначенні предикату Print-countries.
print_countries:- write("Some delightful places to live are"),
nl, fail.
print_countries:- country(X), write(X), nl, fail.
print_countries:- write(" And maybe others."), nl.
6.3.Застосування бектрекінгу для реалізації циклів.
repeat.
Розглянемо наступний предикат
repeat:-repeat.
Такий трюк дозволяє реалізувати управляючу структуру, яка дозволяє отримати нескінченну кількість рішень. Більш детально можна зрозуміти її роботу після вивчення поняття хвостової рекурсії. Для прикладу розглянемо наступну програму.
predicates
repeat
typewriter
clauses
repeat.
repeat :- repeat.
typewriter :- repeat,
readchar(C),
write(C),
char_int(C,13).
Ця програма показує як працює repeat. Правило typewriter... описує процедуру, яка отримує символи з кейборди і друкує їх на екрані, поки не буде натиснута клавіша ENTER (ASCII кoд 13).
Вона працює так:
1.Виконається repeat (який нічого не робить).
2.Потім читається символ в змінну C.
3.Потім друкується C.
4.Потім перевіряється чи С не дорівнює 13 в коді ASCII.
5.Якщо так, тоді фінішуємо. Інакше, починається бектрекінг і перегляд альтернатив. Ні write ні readchar не генерують альтернативних рішень, тому бектрекінг веде до repeat, котрий дозволяє отримати альтернативні рішення.
6.Тепер обробка може повернутись знову на початок, читати інший символ, друкувати його, перевіряти на рівність 13.
6.4.Рекурсивні процедури.
Інший шлях реаліцації повторення є використання рекурсії. Розглянемо рекурсивну програму обчислення значення факторіалу n!. Яку можна проінтерпретувати наступним чином. Якщо n=1, тоді n!=1 (за рахунок factorial(1,1):-!), інакше n!=n*(n-1)!. Останнє обчислення забезпечується наступною фразою визначення factorial(x,FactX).
predicates
factorial(integer, real)
clauses
factorial(1, 1) :- !.
factorial(X, FactX) :- Y = X-1,
factorial(Y, FactY),
FactX = X*FactY.
6.5.Використання аргументів в якості параметрів циклу.
Попередня рекурсивна програма обчислення факторіалу може бути описана на Паскалі в наступному ітераційному вигляді:
p:=1;
for i:=1 to n do
p:=p*i;
FacN:=p;
або ж використовуючи цикл типу while:
p:=1; i:=1;
while i<=n do
begin p:=p*i; i:=i+1 end;
FacN:=p;
Мал.6.2.
Фрагмент програми, зображений на мал.6.2, можна транслювати в Пролог наступним чином.
predicates
factorial(integer, real)
factorial_aux(integer,real, integer, real)
/* Числа більші за 32767 повинні бути описані як дійсні. */
clauses
factorial(N, FactN):- factorial_aux(N, FactN, 1, 1).
factorial_aux(N, FactN, I, P):- I <= N, !,
NewP = P * I,
NewI = I + 1,
factorial_aux(N, FactN, NewI, NewP).
factorial_aux(N, FactN, I, FactN) :- I > N.
Мал.6.3.
Більш красивіший варіант попередньої програми поданий на мал.6.4.
predicates
factorial(integer,real)
factorial(integer, real,integer, real)
clauses
factorial(N,FactN):- factorial(N,FactN,1,1).
factorial(N, FactN, N, FactN):- !.
factorial(N, FactN, I,P):-NewI = I+1,
NewP = P*NewI,
factorial(N,FactN,NewI,NewP).
мал.6.4.
6.1. Написати рекурсивну і нерекурсивну програми, які обчислюють значення F(M,N) для довільної пари цілих чисел M,N>=0, яке визначається наступним чином:
M+N+1 якщо M*N=0
F(M,N)=
F(M-1, F(M,N-1)) в іншому випадку
6.2. N-те число Фіббоначі визначається наступним чином
0 якщо N=0
F(N)= 1 якщо N=1
F(N-1)+F(M,N-1)) в іншому випадку
Написати рекурсивну і некурсивну програми, які обчислюють N-те число Фіббоначі.
6.3. Найбільший спільний дільник G(M,N) двох цілих чисел M і N можна визначити наступною рекурсивною схемою
M якщо N=0
G(M,N)=
G(N, MOD(M,N)) якщо N0
Написати програму, яка використовує рекурсивно-визначений предикат G(M,N), для визначення найбільшого спільного дільника декількох пар чисел.