Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Основы программирования на языке Turbo Prolog.doc
Скачиваний:
61
Добавлен:
09.11.2019
Размер:
563.2 Кб
Скачать

4. Правило повтора

Попытаемся заставить правило show_point читать ряд значений координат точки. Организуем бесконечный цикл с именем repeat:

repeat.

repeat :- repeat.

Первый repeat является утверждением, объявляющим предикат repeat истинным. Однако, поскольку имеется еще один вариант для этого правила, то указатель возврата устанавливается на второй repeat. Второй repeat — это рекурсивное правило, которое вызывает само себя. Этот вызов вычисляется успешно, так как первый repeat удовлетворяет подцели repeat.

Следовательно, предикат repeat будет вычисляться успешно при каждой новой попытке его вызвать после возврата.

Вставим его в правило show_point:

show_point:-

repeat,

readreal(X),readreal(Y),

<.....................>,

fail.

Чтобы превратить этот бесконечный цикл в цикл с постусловием, поступим так:

show_point:-

repeat,

<................>,

< условие выхода >,

!.

Если < условие выхода > дает отказ, то происходит возврат к repeat; если же условие выхода успешно согласовывается, то отсечение не дает осуществить возврат к repeat, цель show_point дает отказ, и запросы прекращаются.

/* Программа 4.3 «Точки». Назначение: */

/* демонстрации использования правила повтора */

predicates

show_point

repeat

pos_point(real,real,real)

out_sqr(real,real,real)

in_circ(real,real,real)

goal

show_point.

clauses

show_point:-

write(" R? "), readreal(R),

repeat,

write(" X? "),readreal(X),

write(" Y? "),readreal(Y),

pos_point(X,Y,R), % условие выхода

!.

repeat. % бесконечный цикл

repeat:-repeat.

% выход из цикла для точки (0,0)

pos_point(0,0,_):-!.

pos_point(X,Y,R):-

out_sqr(X,Y,R),!,

write(" вне квадрата"), nl,

fail.

pos_point(X,Y,R):-

in_circ(X,Y,R),!,

write("внутри круга"), nl,

fail.

pos_point(_,_,_):-

!,

write("вне круга и внутри квадрата"),

nl, fail.

out_sqr(X,Y,R):- % условие вне квадрата

abs(X)>R;

abs(Y)>R.

in_circ(X,Y,R):- % условие внутри круга

X*X+Y*Y<R*R.

/* Конец программы */

Подсчитать число точек является делом более сложным, так как при возвратах переменные будут «забывать» накопленные значения, а глобальных переменных у нас нет.

Для того, чтобы решить эту задачу, не отказываясь от цикла repeat, нужно воспользоваться динамической базой данных, которая играет роль «глобальной переменной».

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

Подобным же образом в правиле можно использовать более одного правила повтора. Ниже приведено правило, включающее два правила повтора:

do_two_things :-

repeat1,

<повторяемое тело>,

<условие выхода 1>,!,

repeat2,

<повторяемоу тело>,

<условие выхода 2>,!.

repeat1.

repeat1 :- repeat1.

repeat2.

repeat2 :- repeat2.

Упражнение 4.3.

На числовую прямую с тремя отмеченными областями (от — до —1, от —1 до 2 и от 2 до +). Показать, куда падает точка.

Упражнение 4.4.

Имеется база данных о результатах партий теннисного матча. Результаты представлены в программе в виде фактов типа:

win(tom,john).

Определить отношение class, которое будет распределять игроков по категориям:

profi — победитель всех сыгранных им матчей;

player —выигравший и проигравший хотя бы одну игру;

user — проигравший все матчи.

Если игрок отсутствует в базе, программа должна выдавать соответствующее сообщение.