logo
TurboProlog / Документация / TOM_2

Встроенные предикаты

И, наконец, поговорим о некоторых побочных эффектах. Раньше мы уже

использовали один встроенный предикат, имющий имя true, для завершения

выполнения базы правил. Другие встроенные предикаты, вызывающие побочные

эффекты или конвертирующие способ представления информации, можно вклю-

чать таким же способом. Рассмотрим очевидное расширение команды call:

call("fail", []):- !, fail.

У нас было true. С помощью fail мы можем передать телу значение "ес-

ли это факт существует, то это неверно" (хотя такую операцию можно было

бы совершить и с помощью not). Или рассмотрим подачу звукового сигнала:

call("beep", []):- !, beep.

"подтверждение" beep приведет к побочному эффекту - компьютер подаст

звуковой сигнал. А вот несколько более полезный предикат, один из тех,

которые используются для объединения строк:

call("concat",[str(A), str(B), str(C)]):- !, concat (A,B,C).

Это - основа других предикатов, котороые можно строить с такой же

легкостью. Необходимо понять очень важную мысль, что можно создать меха-

низм вывода, выполняющий интерпретацию правил с обратной цепочкой рассуж-

дений, который может включать (но не ограничен только ними) любые стан-

дартные предикаты Турбо Пролога. Если вам нужно что-то, чего нет в Турбо

Прологе, вы просто сделаете сами, у вас получится интерпретатор с теми

встроенными предикатами, которые необходимы вашей базе правил.

Уникальные встроенные функции можно писать даже на других языках,

таких как Си и ассемблер. База правил может их вызывать прямо из Турбо

Пролога. В Турбо Прологе есть редко используемые предикаты низкого уров-

ня, с помощью которых можно создать оболочку экспертных систем, использу-

ющих встроенные предикаты, непосредственно взаимодействующие с импортом и

экспортом, вызовом подпрограмм BIOS или даже управляющих модемом. При их

написании пользуйтесь подсказкой, имеющейся в Turbo Prolog Toolbox.

При работе со встроенными предикатами интерпретатора наиболее слож-

ной мыслью для понимания является тот факт, что мы можем создать то, что

пока не поддерживается встроенными предикатами системы Турбо Пролога. Это

будет полностью показано, по мере того как мы продолжим создание механиз-

ма вывода для интерпретатора Пролога.

Сейчас мы обсудим реализацию предиката, совершающего текущую оценку

дерева арифметических выражений. При создании традиционного Пролога этому

предикату дали имя is.

call("is", (int(Res), T2]):- !, eval (T2, Res).

is не может быть вычислен непосредственно в Турбо Прологе, но он

создан с помощью предиката eval:  

predicate

eval(aTerm, refInt)

clause

eval(T,_) :- free(T),!, fail.

eval(int(I), I) :- !.

eval(cmp("+",[T1, T2]), R) :- !,

eval(T1, R1), eval(T2, R2), R = R1 + R2.

eval(cmp("-",[T1, T2]), R) :- !,

eval(T1, R1), eval(T2, R2), R = R1 - R2.

eval(cmp("*",[T1, T2]), R) :- !,

eval(T1, R1), eval(T2, R2), R = R1 * R2.

eval(cmp("/",[T1, T2]), R) :- !,

eval(T1, R1), eval(T2, R2), R = R1 div R2.

eval(cmp("-",[T]), R) :- !,

eval(T, R1) R = R1 - R2.

eval(cmp("mod",[T1, T2]), R) :- !,

eval(T1, R1), eval(T2, R2), R = R1 mod R2.

eval(cmp("abs",[T]), R) :- !,

eval(T, R1) R = abs(R1).

Вот пример использования eval:

/* пример оценивающего предиката */

Goal: eval(cmp("+",[int(2), int(3)]), Result)

Result = 5

1 solution

Арифметические выражения - это просто термы Пролога со специальными

функторами, т.е. хорошо известные арифметические операторы. Предикат eval

не включает ничего странного, но обратите внимание на легкость добавления

других предикатов оценки, как, например, мы добавили предикат abs.

Так как мы решили представлять числовые термы в виде целых, то воз-

никают некоторые ограничения на то, что можно успешно добавлять. Однако,

если бы мы выбрали значения с плавающей точкой (что потребует небольших

изменений в объявлениях сканнера и области), то возможности бы резко воз-

росли. Тогда бы вы смогли включить в ваш механизм вывода оценочные преди-

каты, работающие со специальными инженерными или статистическими функция-

ми.

Рассмотрим работу с целыми числами на примере реализации преобразо-

ваний градусов Фаренгейта в градусы Цельсия и наоборот, как арифметичес-

ких функций:

eval(cmp("fahrenheit",[T]), R) :- !,

eval(T, R1) R = R1 * 9 div 5 + 32.

eval(cmp("celsius",[T]), R) :- !,

eval(T, R1) R = (R1 - 32) * 5 div 9.

Эти правила могли бы включать что-либо типа:

..., Triple_far is fahrenheit(Celsius_temp) * 3, ...

(хотя мы и не знаем, зачем это вам потребовалось).

Имея значения с плавающей точкой, можно сделать более полезный при-

мер для гиперболического синуса, косинуса и тангенса:

eval(cmp("sinh",[T]), R) :- !,

eval(T, R1) R = (exp(R1)-exp(-R1))/2.

eval(cmp("cosh",[T]), R) :- !,

eval(T, R1) R = (exp(R1)+exp(-R1))/2.

eval(cmp("tanh",[T]), R) :- !,

eval(T, R1) X = (exp(-R1), R = X/exp(-R1))+X+X+1.

Или напряжение при разряде аккамулятора

eval(cmp("capvolt",[V,T, C, R]), CV) :- !,

eval(V, EV) eval(T, ET),

eval(C, EC) eval(R, ER),

CV = EV*EXP(-ET/(EC*ER)).

Предположим, ваша база правил включает предикат, возвращающий дейст-

вующее напряжение, силу тока и сопротивление земли для данной лучевой

трубки и телевизора. Вам надо определить можно ли коснуться конденсатора

высокого напряжения, вычислив текущее напряжение (Tension), как функцию

этих параметров и время, прошедшее с момента выключения телевизора:

..., params (Brand, Volt, Cap, Leak),

Tension is capvolt(Volt, Time * 60, Cap, Leak)/Humid_fact,

Tension < Safe_lim, ...

Если бы пользователя спросили бы о времени в минутах, то Humid_ fact

стал бы фактором, учитывающим влажность воздуха, Safe _lim - это вопрос,

который мы не будем обсуждать в настоящем приложении.

Конечно оболочка должна будет работать со встроенным предикатом <,

но мы проиллюстрируем это позже. Вероятно, труднее всего будет установить

влияние влажности воздуха, которая должна базироваться на эмпирических

результатах и интуитивных правилах (обратите внимание, что в целях эконо-

мии сил мы советуем использовать терм "эвристика" во всех случах, когда

вы публично обсуждаете подобные вопросы). При действительной реализации

данной задачи ничто не мешает вам соединить гидрометр с компьютером и

позволить оболочке экспертной системы считывать показания с помощью пре-

диката portbyte прямо в Турбо Пролог.

Или, предположим, вам надо оценить скорость поршня в поршневой маши-

не, данной с помощью 2 * stroke * rpm:

eval(cmp("pist_speed", [S, RPM), R) :- !,

eval(S, ES), eval(RPM, ERPM), R = ES * ERPM/360

Код правильный; pist_speed получает stroke в дюймах и ударах в мину-

ту, а возвращает скорость в футах в секунду.

Как вы могли заметить, смонтированный вами специализированный меха-

низм вывода может стать сердцем легко программируемой экспертной системы,

используемой в каком-либо серьезном анализе: финансовом, инженерном или

управляющим и контролирующим работу завода. В дополнение к вводу portbyte

от внешних датчиков, прибавьте некоторые украшения, взяв их из Borland

Grapfics Interface (BGI), и вы получите оболочку, снабжающую вашу базу

правил немедленным сенсорно-топографическим отображением происходящего.

Ваши правила будут определять, нужно ли считать текущие данные нормальны-

ми, а если нет, то используйте встроенную в оболочку модемную коммуника-

цию, чтобы предупредить супервизора и уточнить текущее состояние. Супер-

визором может быть как человек, так и другая машина.

С другой стороны, ничто не смогло бы остановить те компании, произ-

водяшие компьютеры, в чьи контракты по обслуживанию включены регулярная

передача и анализ ошибок пользователя, от перекладывания этой задачи на

специальную оболочку экспертной системы и соответствующей базы данных.

Разумность любой ситстемы зависит от двух причин: встроенных специа-

лизированных особенностей оболочки - которые создаются "инженером по обо-

лочкам" со специальными знаниями в применяемой области, и правилами, ис-

пользующими эти встроенные особенности. Такую оболочку можно было бы наз-

вать "разумная интегрированная среда для базы знаний".

Вероятно не существует области в научных исследованиях и в сфере об-

служивания, которая бы больше проклиналась щедрыми охотниками сильнее чем

рынок ИИ. Так как наступления Borland на разработку систем и работающего

инструментария продолжается, то нам было бы очень приятно услышать от ис-

следователей в области Применений Искусственного Интеллекта, кто развил

систему, основанную на этих идеях. Конечно, не обязательно глубоко прора-

ботать новую область, но все-таки хотелось бы прояснить отличие традици-

онного ИИ от Применений ИИ.