Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
48
Добавлен:
05.03.2016
Размер:
1.28 Mб
Скачать

5.2 Керування пошуком з поверненням

Один з варіантів керування пошуком з поверненням можна ілюструвати на прикладі предиката do_answer, записаного в дещо іншій формі.

do_answer(X) :-colleague(Z,Y), X==Z, write(" ", X, " -> ", Y), nl, fail.

Альтернативна форма запису не змінює суті даного правила, але дає можливість показати, що введення нових підцілей у правило можна керувати пошуком з поверненням. З цього прикладу видно, що друга підмета може виявитися неуспішної через невідповідність працівника, уніфікованого з першої підмети, із працівником, уніфікованим через заголовок правила, тобто введеного з клавіатури. Неуспіх уніфікації другої підмети приведе до того, що відкат виникне до видачі інформації на екран і предикат fail не буде застосовано. Включення предикату fail у правило, забезпечує відкат, якщо умови правила будуть виконані і все правило виявиться успішним.

Ще одним прикладом по керуванню пошуком з поверненням є процедура побудови меню show_menu.

show_menu:-makеwindow(1,7,15," Меню ",1,50,10,20), repeat, clearwindow, write(" 1 - процес 1"), nl, write(" 2 - процес 2"), nl, write(" 0 - вихід "), nl, nl, write(" Ваш вибір -> "), readint(Menu), Menu < 3, process(Menu), stop_menu(Menu).

stop_menu(0).

stop_menu(_) :- fail.

У ній repeat використовується так, що після виходу з будь-якого модуля, що викликається предикатом process(), йде повернення в меню.

Виключенням є вибір нуля, що викликає закінчення програми.

У даному правилі керування відкатом використовується двічі: у виді предикатів Menu підмета Menu.

Якщо процедура process() завершиться успіхом, то система робить спробу виконати процедуру stop_menu(), яка при будь-яких значеннях, крім 0, завершується невдачею, що викликає відкат до предиката repeat. При значенні вибору рівному 0 – вона є щирим фактом, і програма завершується.

Завдання 5.

Створіть файл lab5menu.pro, у якому, використовуючи приведені вище предикати, напишіть програму організації виконання двох довільних процесів з вибором їх через меню. Процеси повинні бути описані відповідними предикатами і мати найпростіший вигляд. Наприклад, відкриття вікна і видача повідомлення.

Запустіть програму на виконання. Потім, використовуючи трасування, вивчіть хід рішення задачі, відкати і повтори, виконувані програмою.

5.3 Керування ходом виконання програм з використанням відсікання

Пролог містить засіб, що перешкоджає пошукові з поверненням при визначених умовах. Ця операція називається відсіканням і виконується предикатом cut, що у програмах позначається знаком оклику (!). Вплив цього предикату просто зводиться до припинення пошуку. Відсікання використовується в двох випадках:

1. Для обмеження простору пошуку у випадках, коли заздалегідь відомо, що деякі можливі шляхи не приведуть до необхідних нам рішень, тобто їх обробка приведе до непотрібної втрати часу. З використанням відсікання програма вирішується швидше і вимагає меншого обсягу пам'яті.

2. Коли відсікання потрібно по логіці програми для:

– Недопущення повернення до попередньої підмети правила при відкаті. Нехай яке-небудь правило має вигляд:

r1(X,Y,Z) if a(X), b(Y), !, c(X,Y,Z).

Дане правило вказує на те, що система пройде через предикат cut тільки в тому випадку, якщо і підмета а(Х), і підмета b(Y) будуть успішними. Після того, як предикат cut буде оброблений, система не зможе повернутися назад для повторного розгляду підцілей а(Х) і b(Y). якщо підмета c(X,Y,Z) зазнає невдачі при поточних значеннях змінних X, Y і Z.

– Запобігання переходу до наступної пропозиції процедури.

Нехай процедура опису предикату r складається з трьох правил. Позначимо через r1, r2 і r3 – записи того самого предиката r у кожній із трьох пропозицій процедури. Тоді два варіанти запису цієї процедури у виді:

a) r1(X,Y) if !, a(X), b(Y), c(X,Y). 6) r1(X,Y) if a(X), b(Y), c(X,Y), !.

r2(X,Y) if !, d(X,Y). r2(X,Y) if d(X,Y), !.

r3(X,Y) if e(X,Y). r3(X,Y) if e(X,Y).

відповідають тому, що, у першому випадку, при обробці предиката r буде використано лише одне з правил r1, r2, r3, а, у другому випадку правила будуть оброблятися одне за одним, причому, істинність якого-небудь одного з правил приводить до закінчення процедури і виключенню з розгляду всіх записаних нижче.

Розглянемо на приклад, процедуру пошуку максимального з двох чисел можна записати у виді двох правил для предиката max. Але ці правила взаємно виключають. Якщо перше правило істинне, то друге правило немає змісту виконувати.

max(X,Y,X):-X> =Y.

max(X,Y,Y):-X< Y.

Тому з використанням відсікання можливе значно більш коротке формулювання процедури.

max(X,Y,X):-X> =Y,!.

max(X,Y,Y).

Таким чином, якщо предикат fail ініціює бектрекінг (повернення до перебору чергових альтернатив після першої знайденої), то предикат cut його завершує.