Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
AlgStr / Библиотека / ЛЕКЦИИ / POSIBNIK / ПРОГР НА ПРОЛОГЕ.doc
Скачиваний:
42
Добавлен:
23.03.2015
Размер:
669.7 Кб
Скачать

5.2. Метод відкоту після невдачі (впн)

Як уже зазначалося, при доведенні внутрішньої цілі вбудовані уніфікаційні процедури ПРОЛОГу зупиняють пошук рішень після першого ж успішного обчислення цілі. Для керування обчисленням внутрішньої цілі при пошуку всіх можливих її розв’язків можна застосувати убудований предикат fail. При виклику він завжди дає відмову й застосовується тільки для ініціювання механізму відкоту. Для ілюстрації цього механізму розглянемо задачу друку спипендіальної відомості деякої студентської групи, що зберігається у вигляді набору фактів:

студент(“ПЗ-98-1”, іванов, 39).

студент(“ПЗ-98-1”, петров, 39).

студент(“ПЗ-99-1”, павлов, 49).

студент(“ПЗ-99-1”, петров, 49).

. . .

студент(“ПЗ-98-1”, сидоров, 79).

друк_групи(Група):-

студент(Група, Студент, Стипендія),

write(Студент,” “,Стипендія), nl,

fail.

При виклику цілі “друк_групи(“ПЗ-98-1”)” обчислення починаються з першої підцілі, що буде мати вигляд “студент(“ПЗ-98-1”, Студент, Стипендія)”. Вона служить для пошуку в базі даних придатного твердження й означування змінних “Студент” і “Стипендія”. Такий запис у базі даних існує (перший) і змінні одержать відповідні значення “іванов” і “39”. Оскільки в базі даних існують й інші твердження, що можуть бути використані для доказу цієї цілі, перед першим із них ПРОЛОГ поставить покажчик відкоту. Потім спрацює підціль “write(Студент, “ ”, Стипендія)” й інформація про знайденого студента групи ПЗ-98-1 і його стипендію буде виведена на екран. Після цього буде переведений рядок і виконається предикат fail.

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

Слід зверніти увагу, що будуть надруковані тільки студенти групи “ПЗ-98-1”, тому що для студентів інших груп підціль “студент(“ПЗ-98-1”, Студент)” не зможе узгодитись. У такий спосіб цим методом можна обробляти не всі записи бази даних, а тільки ті, які задовольняють задані умови. Ці умови можна задавати як у самій підцілі, що дістає інформацію з бази даних, так і за допомогою підцілі, що міститься в тілі правила (така підціль буде називатися сторожовою). Визначення предиката “друк_групи”, за необхідності надрукувати список студентів, що одержують підвищену стипендію, буде мати такий вигляд:

друк_групи(Група):-

студент(Група, Студент, Стипендія),

Стипендія > 39,

write(Студент,” “,Стипендія), nl,

fail.

Правила, що застосовують предикат fail у такому вигляді як показано вище, ніколи не можуть завершитися успішно. Тому визначення таких предикатів іноді доповнюється ще одним твердженням, після того як усі альтернативи в базі даних будуть перебрані. Щоб визначення попереднього предиката завжди завершувалось успішно, він повинен мати такий вигляд:

друк_групи(Група):-

студент(Група, Студент, Стипендія),

Стипендія > 39,

write(Студент,” “,Стипендія), nl,

fail.

друк_групи( _ ).

Такий предикат може застосовуватись як підціль у тілі якого-небудь правила в ланцюжку інших підцілей і не викличе ініціювання небажаного відкоту, наприклад:

Обробка(Група):-

друк_шапки,

друк_групи(Група),

підведення_підсумків.