Метод повтора, определённый пользователем.
Рассмотрим следующую структуру
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>, !.