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

5.11.1 Цикл repeat-fail

Цикл с возвратом используется в тех случаях, когда нужно перебрать альтернативные варианты ( решения ) некоторых предикатов. Но существуют предикаты, не имеющие альтернатив. Т.е. можно заставить Пролог возвращаться к точкам выбора, используя предикат fail, но такие точки не всегда имеются.

Например:

передает управление на альт. т. выбора

Выполняется ввод_строки(S), обработка(S), fail.

предикаты не имеющие альтернатив

Предикат, создающий т. выбора

Соответствует _ repeat

Дадим определение предиката, имеющего бесконечное число решений и бесконечное число раз завершающегося успешно.

repeat :- ?- repeat

succeed;

repeat.

succeed repeat

succeed repeat

... ...

 Бесконечный цикл :- repeat, тело_цикла, fail.

 Конечный_цикл  :- repeat, ввод_строки(S),

(последняя_строка(S), !;

обработка_строки(S), fail).

Цикл  For  - цикл с заранее известным количеством повторений (цикл со счетчиком).

repeat(1) :- !.

repeat(N) :- succeed; M is N-1, repeat(M).

?- repeat(3)

/ \

succeed M is 3-1,repeat(M)

¦ M:=2

repeat(2)

/ \

succeed M is 2-1,repeat(M)

¦ M:=1

repeat(1)

¦

успех

Цикл_со_счетчиком:- repeat(4),тело_цикла, fail.

5.11.2 Сопоставление цикла с возвратом и рекурсии

В тех случаях, когда мы ищем альтернативные решения цикл с возвратом - естественный способ приближения. Во многих случаях задачу можно сформулировать и рекурсивно. Например предикат "общие_элементы" (см. предыдущий параграф). Эту же задачу мы опишем рекурсивно.

ПРИМЕР 1:

общие_элементы([],_).

% Такая запись говорит о том, что каждый объект имеет общим элементом пустой список [].

общие_элементы([A|L1],L2) :-

вывести_на_экран(A,L2), % Если A входит в L2

общие_элементы(L1,L2).

вывести_на_экран(A,L2) :-

элемент(A,L2),вывод(A);

succeed.

ПРИМЕР 2:

цикл :- ввод_строки(S),

(последняя_строка(S), !;

обработка_строки(S), цикл).

Здесь под последней строкой понимается признак конца текста, например "END".

Цикл с возвратом имеет ограниченное применение и используется в тех случаях, когда в определении цикла применяют некоторое побочное действие (например, вывод на экран).

ПРИМЕР 3:

% Вывод промежуточных результатов на экран

%

цикл :- repeat, ввод_строки(S),

(последняя_строка(S), !;

обработка_строки(S), fail).

Особенность такой организации цикла заключается в том, что между двумя последовательными выполнениями ядра цикла нельзя передавать промежуточные результаты (они теряются, т.к. при возвратах теряются конкретизации переменных). Однако, такой же эффект возможен и в цикле с рекурсией. Т.е. необходимы "нелогические" средства.

Построим дерево выполнения для обоих случаев:

цикл :- repeat, ввод_стр(S), цикл :- ввод_строки(S),

(последняя_строка(S), !; ( последняя_строка(S), !;

обработка_строки(S), fail). обработка_строки(S), цикл).

?- цикл ?-цикл

repeat, ввод_стр(S), ввод_строки(S),

(последняя_строка(S), !; ( последняя_строка(S), !;

обработка_строки(S), fail). обработка_строки(S), цикл).

succeed repeat,... посл_стр(S),! обр_стр(S),цикл

ввод_стр(S), S:= ...

(посл_стр(S), fail

!;обр_стр(S), -- ввод_стр(S),

fail). (посл_стр(S),

!;обр_стр(S),

succeed repeat... цикл).

S:= ...

... N .

fail раз .

S:=... .

fail

Это дерево растёт в ширину Это дерево растет в глу-

одна ветка выросла- её "спи- бину. Одна ветка наращивает-

лили",выросла другая и т.д. ся до огромных размеров.

Достоинства - экономное Достоинство - может переда-

расходование памяти, НО в вать значения от итерации к

памяти хранятся только пере- итерации ; все переменные

менные. хранятся в памяти, НО неэко-

номично используется память.

Очевидно, что Пролог-система может работать с путями дерева не длиннее лишь определенного предела (зависящего от памяти ЭВМ). Это означает, что применение цикла repeat-fail обычно предпочтительнее рекурсии.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]