Простой интерпретатор для программ, управляемых шаблонами

Выберем следующий синтаксис для определения модулей, управляемых шабло­нами:

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( В) .