Выберем следующий синтаксис для определения модулей, управляемых шаблонами:
ConditionPart ---- > ActionPart
где ConditionPart - часть с обозначением условия, a ActionPart •- часть с обозначением действия. Часть с обозначением условия представляет собой примерно такой список условий:
[ Condi, Ccnd2, Cond3,... ]
где Condi, Cond2 и т.д. - цели Prolog. Предварительное условие удовлетворяется, если достигаются все цели в этом списке. Часть с обозначением действия представляет собой список действий, заданных примерно таким образом:
[ Actionl, Action2,... ]
Каждое действие также представляет собой цель Prolog. Для выполнения списка действий должны быть выполнены все действия в списке. Это означает, что должны быть достигнуты все соответствующие цели. Среди доступных действий могут быть такие, которые манипулируют базой данных — добавляют, удаляют или заменяют объекты в базе данных. Действие "stop" останавливает дальнейшее выполнение.
В листинге 23.8 покачана соответствующая программа, управляемая шаблонами, для вычисления наибольшего общего делителя, которая написана с использованием такого синтаксиса.
Порождающие правила для -». |
Листинг 23.S. Программа вычисления наибольшего общего делителя для множества целых чисел, управляемая шаблонами
поиска наибольшего общего делителя [алгоритм Евклида.)
:- ор(800, xfx,-
:- op(300, fx, num)
Часть II Применение языка Prolog в области искусственного интеллет
t num X, rum Y, X > Y 1 >
[ ЫеиХ is X - Y, replace! num X, num NewX) ].
[ num X] ------- > [ write (X), Stop ].
% Начальное состояние Сазы данных
num 2 5. num 10. num 15. num 30.
Простейший способ реализации такого языка, управляемого шаблонами, состоит в использовании собственного встроенного механизма поддержки базы данных системы Prolog. Добавление объекта в базу данных и удаление объекта может осуществляться с помощью следующих встроенных процедур;
asserts! object) retract! Object}
Замена одного объекта другим также осуществляется достаточно просто:
replace! Objectl, Object2):-retract! Qbjectl),!, assertz(Object2).
В этом предложении оператор отсечения используется для того, чтобы предикат retract не мог удалить из базы данных (в результате перебора с возвратами) больше одного объекта.
Небольшой интерпретатор для программ, управляемых шаблонами, разработанный в соответствии с этим замыслом, приведен в листинге 23.9. Возможно, этот интерпретатор в определенных отношениях является слишком упрощенным. В частности, правило разрешения конфликтов в этом интерпретаторе является чрезвычайно простым и жестким, поскольку согласно этому правилу всегда выполняется первый потенциально активный модуль, управляемый шаблонами (в порядке их местонахождения в программе). Поэтому управление порядком выполнения со стороны программиста сводится лишь к упорядочению модулей. Первоначальное состояние базы данных для этого интерпретатора должно быть сформировано путем вставки фактов Prolog, возможно, в результате получения консультаций из файла. Затем выполнение программы активизируется в результате вызова следующей цели:?- run.
Листинг 23.9. Небольшой интерпретатор для программ, управляемых шаблонами
% Небольшой интерпретатор для программ, управляемых шаблонами. % Манипуляции с базой данных системы осуществляются с помощью % предикатов assert/retract
:- op(800, xfx, >).
% ran: выполнять порождавшие правила, заданные в форме Condition > Action,
% до тех пор, пока не будет активизировано действие 'stop'
run: -
Condition ------- > Action, % Порождающее правило
testl Condition), i Предварительное условие выполнено?
execute! Action).
% test ([ Condition!, condition2,...]) если результаты проверки всех условий % являются истинными
test( []). % Пустое условие
Глава 23. Метапрограммирование
test([First I Rest]):- * Проверить конъюнкцию условий
call(First), test(Rest).
% execute! [ Actionl, Action2,..,]): выполнить список действий
execute! [ stop]):-!. % Прекратить выполнение
execute! И>: - * Пустое действие (цикл ьылсгяекмя завершен)
run. % Перейти к следующему циклу выполнения
execute; [First t Rest]):-call{ First), execute (Rest).
replace Г A, B):- % Заменить в базе данных предложение А предложением В
retract! А),!, % Извлечв толвко один экземпляр
assert(В).