Простой интерпретатор для программ, управляемых шаблонами
Выберем следующий синтаксис для определения модулей, управляемых шаблонами:
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 numX , 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( В) .