- •«Рекурсивно-логическое программирование»
- •Содержание
- •1 Введение в язык Пролог
- •2 Логические основы Пролога
- •3 Основные понятия Пролога
- •4 Рекурсия
- •5 Структура программы на Турбо Прологе
- •6 Управление выполнением программы на Прологе
- •7 Списки
- •8 Сортировка списков
- •9 Множества и деревья
- •10 Строки
- •11 Файлы
- •12 Внутренние (динамические) базы данных
- •13 Пролог и искусственный интеллект
6 Управление выполнением программы на Прологе
Используется откат (бэктрекинг), или механизм поиска в глубину. Суть механизма такова, что в том месте программы, где возможен выбор нескольких вариантов, Пролог сохраняет в специальный стек точку возврата для последующего возврата в эту позицию. Точка возврата содержит информацию, необходимую для возобновления процедуры при откате. Выбирается один из возможных вариантов, после чего продолжается выполнение программы.
Во всех точках программы, где существуют альтернативы, в стек заносится указатели. Если вариант не приводит к успеху, то осуществляется откат к последней из имеющихся в стеке точек программы, где был выбран один из вариантов. Выбирается очередной вариант, программа продолжает свою работу. Если все варианты в точке уже были использованы, то регистрируется неудачное завершение и осуществляется переход на предыдущую точку возврата, если такая есть. При откате все связанные переменные, которые были означены, опять освобождаются.
DOMAINS /* раздел описания доменов */
s=string /* вводим синоним для строкового типа данных */
PREDICATES /* раздел описания предикатов */
mother(s,s) /* предикат мама будет иметь два аргумента
строкового типа */
grandmother(s,s) /* то же имеет место и для предиката
бабушка */
CLAUSES /* раздел описания предложений */
mother("Даша","Маша"). /* "Даша" и "Маша" связаны
отношением мама */
mother("Наташа","Даша"). /* "Наташа" является мамой
"Даши" */
mother("Наташа","Глаша"). /* "Наташа" и "Глаша" связаны
отношением мама */
mother("Даша","Саша"). /* "Даша" является мамой "Саши" */
grandmother(X,Y):– /* X является бабушкой Y,
если найдется такой Z, что */
mother(X,Z), /* X является мамой Z, а */
mother(Z,Y). /* Z является мамой Y */
Предикат, который выводит имена всех дочек:
show_names:–
mother(_,Name), /* означивает переменную Name
именем дочки */
write(" ", Name), nl,
/* выводит значение переменной
Name на экран */
fail. /* вызывает откат на место, сохраненное
в стеке точек возврата */
GOAL
write("Имена дочек:"),nl,
show_names.
Результат:
Имена дочек:
Маша
Даша
Глаша
Саша
Рассмотрим пример вывода дочек только одной мамы, имя которой задано в качестве параметра:
show_names2(Mother):–
mother(M,Name), /* означивает переменную Name
именем дочки мамы Mother */
M=Mother, /* проверяет совпадение имен мам M
и Mother */
write(" ", Name), nl, /* выводит значение
переменной Name
на экран */
fail. /* вызывает откат к месту, сохраненному
в стеке точек возврата */
Результат:
Имена дочек Даши:
Маша
Саша
Метод отсечения и отката.
В основе этого метода лежит использование комбинации предикатов fail (для имитации неудачи и искусственной организации отката) и "!" (отсечение или cut), который позволяет прервать этот процесс в случае выполнения какого-то условия.
Пример:
PREDICATES
nal(symbol, symbol)
zar(symbol)
min(symbol)
max(symbol)
dop(symbol)
prof(symbol,symbol)
CLAUSES
nal(Pred, Vid_nal):-zar(Pred), prof(Pred, “Образование”),!, fail.
nal(Pred, Vid_nal):-zar(Pred), max(Vid_nal).
max(X):-min(X);dop(X).
min(“Местные”).
min(“На прибыль”).
dop(“На добавочную стоимость”) .
zar(“РГРТУ”).
zar(“контора РиК”).
prof(“РГРТУ”, “Образование”).
prof(“Контора РиК”, “Комерция”).
Метод повтора
Также использует откат, однако в отличие от отката после неудачи, в котором откат осуществляется только после специально созданной неудачи, в этом методе откат возможен всегда за счет использования специального предиката, обычно кодируемого в виде:
repeat.
repeat:–
repeat.
Этот предикат всегда успешен после выполнения первого предложения процедуры в стек точек возврата запоминается указатель поскольку имеется ещё один альтернативный вариант. В теле второго предложения опять вызывается предикат repeat. Предикат repeat не является встроенным предикатом, а его имя – зарезервированным словом. Вместо этого имени можно использовать любое другое. С помощью подобного предиката можно организовывать циклы.
DATABASE
counter(integer)
PREDICATES
repeat
count
GOAL
count.
CLAUSES
repeat.
repeat:-repeat.
count:-assert(counter(0)),fail.
count:-repeat,counter(X),Y=X+1,retract(counter(X)), asserta(counter(Y)),write(Y), nl, Y=5.
