Метод повтора, определённый пользователем.

Рассмотрим следующую структуру

1  repeat.

2  repeat:- repeat  3

Repeat1 является утверждением без аргументов и всегда сопоставляется успешно. Repeat2 является правилом с одной подцелью, ссылающееся на Repeat1.

Если в каком-либо запросе в качестве подцели будет содержаться какая-нибудь Repeat4, то такая подцель будет сопоставляться успешно сколько угодно раз. И каждый раз ПРОЛОГ будет считать, что он нашел новую альтернативу, т.е. эта конструкция обманывает интерпретатор, порождая альтернативу там, где их на самом деле нет. a : - b, c, repeat, l, m, …

   Пусть среди подцели правее repeat есть приводящие к неуспеху. Подцели пересопоставляются справа налево. Как только ближайшей правой подцелью станет repeat будет полностью повторяться поиск сопоставления по l и m. Это используется для организации циклов.

Do_loop : - repeat,

<тело цикла>

fail

Цикл бесконечный. Для нормальной работы надо менять параметр цикла и предусмотреть условие выхода.

Do_loop : - repeat

<тело>

<усл_вых>

Условие выхода - успех.

Пример:

predicates

write_mess

rep.

echo.

test(symbol)

goal.

write_mess, echo

clouses

rep.

rep : - rep.

write_mes : - nl, write(“Введите строку”), nl,

write(“Я её повторю”), nl,

write(“Для остального - stop”), nl.

echo : - rep,

readln (str),

write (str),

test (str), !.

test (stop) : - nl, write (“Конец работы”).

Test (_): - fail.

   При вводе любой строки кроме “stop” предикат test не сопоставляется, тело цикла повторяется с разными строками. Если будет введена строка “stop”, тест сопоставляется успешно. Поводов для отката не видно, да и отсечение в любом случае воспрепятствует откату. Цикл закончен.

Вопрос: так ли необходим предикат отсечения, нельзя ли его убрать?

Примечание: возможно использование нескольких предикатов типа rep.

rep1.

rep1 : - rep1.

rep2.

rep2 : - rep2.

Do_loop : - rep1, -(внеш. цикл)

<тело1>,

<усл_вых_1>, !,

rep2,                    -(внутр. влож цикл)

<тело2>,

<усл_вых_2>, !.

 

Hosted by uCoz