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

6.3 Особливості виконання рекурсивних процедур Прологом-системою

При використанні рекурсії, при дуже великій кількості рекурсивних викликів, кількість відкладених на виконання підцілей у стеку запитів постійно росте й у деякий момент стек переповниться. На екрані з’явиться повідомлення про помилку. Частково допомогти в цій ситуації може збільшення розміру стека, що може бути змінений за допомогою опції меню системи Установки/Різні – Установки/Розмір стека. Однак, якщо встановлено граничне значення, те це вже не допоможе. Недоліки, у цьому випадку, викликані погано продуманою організацією процедур. Для прикладу, повернемося до процедури “предок” і визначемо її трохи інакше:

предок1(А, Б):-батько(А,Б).

предок1(А, Б):-предок1(А, В), батько(В, Б).

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

Завдання 3.

В програмі “lab6.рго”, замініть в ній процедуру предок” на “предок1”. Виконаєте ряд запитів і дослідіть результат.

Процедура “предок1” називається процедурою з лівою рекурсією, тому що в другому правилі рекурсивна мета стоїть ліворуч від інших підцілей. Пролог не може надійно обробляти ліворекурсивні процедури, що обумовлено природою стратегії рішення задач, що закладена в Пролог. Тому, будуючи рекурсивні процедури, необхідно це враховувати. Це особливо важливо, так як рекурсія – це основний алгоритмічний підхід побудови Пролог-програм.

6.4 Приклад рекурсивної процедури пошуку довжини маршруту на графі

Розглянута вище рекурсивна процедура “предок” будувалася на основі бінарного відношення Батько(Батько, Дитина), що встановлювало логічний зв'язок між цими двома об'єктами. Разом з тим у практиці часто зустрічаються випадки, коли між об'єктами існує як якісний, так і кількісний взаємозв'язок.

Прикладом такого відношення може бути відношення Дорога(Місто_1, Місто_2, Відстань), яке характеризує не тільки наявність зв'язку між якими-небудь містами, але і відстань між ними.

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

Шлях(Місто_1, Місто_2, Довжина_шляху),

на основі вихідного відношення “дорога”. Метод рекурсії, що використовувався при складанні процедури “предок” можна застосувати і в цьому випадку.

/* програма 6.2 */

domains

town = string

distance = integer

predicates

road(town, town, distance)

route(town,town,distance)

clauses

road(„Івано-Франківськ”, ”Львів”, 135).

road(„Івано-Франківськ”, „Тернопіль”, 137).

rоаd(„Луцьк”, „Львів”, 152).

road(„Луцьк”, „Тернопіль”, 163).

rоаd(„Львів”, „Тернопіль”, 127).

route(Town1, Town2, Distance):-road(Town1 ,Town2, Distance).

route(Town1, Town2, Distance):-road(Town1, X, Dist1), route(X, Town2, Dist2), Distance=Dist1+Dist2, !.

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

Кожна пропозиція для предиката road() описує дорогу з одного міста в іншій, що має визначену відстань.

Правила процедури route() указують на можливість як прямого маршруту, так і маршруту через інші міста. Предикат route() визначений рекурсивно.

Якщо маршрут містить тільки одну ділянку дороги, то в цьому випадку відстань між містами дорівнює довжині цієї ділянки.

У випадку, якщо маршрут з Міста_1 у Місто_2 є сумою маршрутів з Міста_1 у Х і з Х в Місто_2, то відстань між Містом_1 і Містом_2 буде дорівнює відстані між Містом_1 і Х плюс відстань між Містом_2 і X, тобто сумі двох відстаней.

Друге правило є рекурсивним. Відношення, записане в заголовку правила, залежить від більш простої версії самого себе. Перше правило визначає граничну умова виходу з рекурсії. Як тільки воно стане істинним, то процес рекурсії припинитися.

Рисунок 6.3 – Симетричне транзитивне відношення

Завдання 4.

Введіть програму 6.2 і дослідіть процес знаходжнення шляху від Івано-Франківська до Львова і до Луцька. Після чого спробуйте визначити маршрут від Львова до Івано-Франківська.

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