|
дб. Четвертое издание джозеф Джарратано Университет Хьюстон клиэрЛэйк Гари Райли People5oft, Издательский дом "Вильямс" Москва СанктПетербург Киев 2007 ббк 32. 973. 26 018 75 Д
(defmessage-handler INSTANCE-COUNTER delete before () (bind ? self:count (- ?self:count 1))) Функционирование обработчика сообщений create типа after требует определенных пояснений. Сообщение create передается экземпляру до применения каких- либо заданных по умолчанию значений. В случае создания первого экземпляра INSTANCE — COUNTER слоту count в качестве значения присваивает. Модификация и дублирование экземпляров 919 Модификация и дублирование экземпляров В языке предусмотрено несколько команд для работы с экземплярами, которые предоставляют функциональные возможности, аналогичные возможностям команд модификации и дублирования, предусмотренным для фактов. Эти команды имеют следующий синтаксис (modify-instance *) (message-modify-instance ся символ nil вовремя вызова обработчика сообщений Попытка сложить единицу с этим значением привела бык возникновению ошибки, поскольку символ nil — не числовой. Проверка наличия этой ситуации осуществляется с помощью функции i f в обработчике сообщений create типа a f ter, что позволяет предотвратить выполнение указанной операции сложения. А поскольку заданное по умолчанию значение совместно используемого слота применяется только один раз при создании первого экземпляра, то заданное по умолчанию значение слота count устанавливается равным 1, чтобы при создании первого экземпляра слот count автоматически приобретал правильное значение. При последующих вызовах обработчика create типа after будет обнаруживаться, что значение слота count является целочисленным, поэтому вызов предикативной функции вовремя проверки с помощью функции if завершится успешно и значение слота count увеличится на Ниже приведена последовательность команд, которая показывает, что в результате создания двух новых экземпляров класса INSTANCE — COUNTER значение слота count увеличится должным образом до 4, а после удаления одного экземпляра соответственно уменьшится до 3. CLIPS> (make- instance 13 of INSTANCE-COUNTER)J [i3] CLIPS> (make-instance i4 of INSTANCE-COUNTER)J [i4] CLIPS> (send [ii] get count)J 4 CLIPS> (send [i4] delete)J TRUE CLIPS> (send [ii] get-count)J 3 CLIPS> 920 Глава 11. Классы, экземпляры и обработчики сообщений *) (active-modify-instance *) (active-message-modify- instance *) (duplicate- instance [to ] *) (message-duplicate-instance [to пате *) (active-duplicate-instance [to пате- expression>] *) (active-message-duplicate-instance
[to пате *) В этих определениях терм содержит список модификаций слотов, а что касается команд дублирования, то терм представляет собой необязательное новое имя для дублируемого экземпляра. Наиболее важной командой модификации экземпляра является команда modЫу-1пйапсе. Ниже приведен пример ее использования. CLIPS> (unwatch all)J CLIPS> (clear)J CLIPS> (defclass PERSON ар- паве "Public"))J [pl] CLIPS> (watch messages)J CLIPS> (watch slots)J CLIPS> 11 12. Модификация и дублирование экземпляров 921 (modify- instance [p1] (паве "Jack" ) (паве Private"))J MSG » direct- modify ED:1 ( ) ::= local slot first-name in instance р <- "Jack" ::= local slot патер ро) (пате "Private" ) CLIPS> Обратите внимание на то, что сообщение direct-modify передается экземпляру [pl], а сообщения put — first — пате и put — last — пате не передаются. От имени программиста автоматически создается еще один определяемый системой обработчик сообщений — обработчик сообщений direct — пюЖйу. Если используется команда modify — instance, то значения слотов изменяются непосредственно с помощью обработчика сообщений direct — modiйу, поэтому средства передачи сообщений не вызываются. Следствием указанного положения дел является то, что не вызываются обработчики put — типов primary, af ter, before и around, связанные со слотом. Команда message-modify4nstàncå имеет такой же синтаксис параметров, как и команда modify — instance, но при ее использовании изменение значений слотов осуществляется с помощью средств передачи сообщений, например, как показано ниже. CLIPS> (watch messages)J CLIPS> (message modify- instance [p1] (first-name "Jeff" ) (last-name "Public"))J MSG » message-modify ED:1 ( ) MSG » put-first-name ED:2 ( "Jeff" ) MSG « пате ( "Jeff" ) MSG » пате ED:2 ( "Public" ) MSG « пате ED:2 ( "Public" ) MSG « message-modify ED:1 (Глава 11. Классы, экземпляры и обработчики сообщений 922 ) TRUE CLIPS> В данном случае применялась команда message — modify — instance, поэтому для изменения значений слотов использовались обработчики сообщений put — first — пате и put — last — пате. А для модификации экземпляра вместо direct — modify применялся еще один определяемый системой обработчик сообщений — message-modify. Наконец, предусмотрены две дополнительные команды модификации экземпляра, обеспечивающие более широкий контроль над сопоставлением с шаблоном объекта, — active-modify-instance и active-message-modify instance. Ив этом случае синтаксис параметров является таким же, как ив других командах модификации. При использовании команд modify — instance и message — modify- instance сопоставление с шаблоном объекта не происходит до тех пор, пока не будет завершена обработка всех изменений в слоте. Поэтому при использовании команд active — modify — instance и active — message — modify — instance сопоставление с шаблоном объекта осуществляется только после того, как будут внесены изменения в каждый слот. Как правило, действительно требуется, чтобы все модификации слотов в экземпляре были выполнены до сопоставления с шаблоном объекта, поскольку обычно это позволяет повысить производительность, нона тот случай, если потребуется дополнительная обработка, предусмотрены указанные команды активизированной модификации. Кроме того, в языке CLIPS имеются четыре аналогичные команды, предназначенные для дублирования экземпляров duplicate instance, message-duplicate- instance, active-duplicate-instance и active-message-modify instance. Каждая из этих команд имеет такой же принцип действия и состав параметров, как и команды модификации, имеющие подобные имена. Нос помощью этих команд вместо модификации экземпляра, переданного в качестве параметра, создается дубликат экземпляра, к которому применяются операции перекрытия значений слотов. Кроме того, в качестве необязательного параметра в командах дублирования может быть задано имя дублируемого экземпляра в противном случае такое имя создается автоматически. Возвращаемым значением этих команд является дублированный экземпляр. Ниже приведены примеры, в которых показано, как используются две из указанных команд дублирования. CLIPS> (duplicate-instance [p1] (паве "Jack"))J MSG » direct-duplicate ED:1 ( [gen2] ) MSG « direct-duplicate ED:1 ( [gen2] ) 11.12. Модификация и дублирование экземпляров 923 [gen2] CLIPS> (fi MSG » [p31 CLIPS> (instances)J [pl] of PERSON [gen2] of PERSON [p3] of PERSON For а total of 3 instances. CLIPS> В примере использования команды duplicate — instance имя экземпляра не задано, поэтому применяется имя, сформированное системой, [gen2]. А в примере использования команды message — duplicate для дублированного экземпляра служит указанное имя, [p3]. Двум другим определяемым системой обработчикам сообщений, direct-duplicate и message- duplicate, передаются сообщения, зависящие оттого, какая команда дублирования экземпляра была вызвана. В случае вызова команд message — duplicate и active — message — dupl icate передаются дополнительные сообщения create, init и put для копирования и перекрытия значений слотов во вновь созданном экземпляре. Наконец, предусмотрена возможность определить обработчики сообщений типа around, before и ай1ег для определяемых системой обработчиков сообщений direct — modify, message — modify, direct — duplicate и message— duplicate. Тем не менее, поскольку значения перекрытий слотов передаются как типа такие параметры могут быть декодированы только с помощью внешнего кода, то программист, определяя свои собственные обработчики, вряд ли сможет добиться каких-либо продуктивных результатов. MSG » MSG « MSG » MSG « MSG » MSG « MSG » MSG « MSG « (message-duplicate-instance [p1] to [p3] гете.-пате "Jill"))J message-duplicate ED:1 ( [рЗ] Ox006b8840>) create ED:2 () create ED:2 () put-first-name ED:2 ( "Jill" ) пате ED:2 ( "Jill" ) пате ED:2 ( "Public" ) put-last-name ED:2 ( "Public" ) init ED:2 () init ED:2 () message-duplicate ED:1 ( [p3] ) 924 Глава 11. Классы, экземпляры и обработчики сообщений Классы и универсальные функции Ограничения параметров для универсальных функций не сводятся к использованию только заранее определенных типов, предусмотренных в языке CLIPS. В качестве ограничений параметров могут также использоваться определяемые пользователем классы. Например, следующий класс может служить для представления комплексного числа (defclass COMPLEX (is — а USER) (slot real) (slot imaginary)) Класс представляет комплексные числа в таком формате: а+bi В этом определении аи квадратный корень от — В классе COMPLEX значение а хранится в слоте real, а значение b — в слоте imaginary. Операция сложения комплексных чисел выполняется просто аса+ с) + (b + d)i Ниже приведено определение метода, который перегружает функцию+ в целях реализации операции сложения двух комплексных чисел. (defmethod + ((?cl COMPLEX) (?c2 COMPLEX)) (make-
instance of COMPLEX (real (+ (send ?cl get-real) (send ?c2 get- real))) (imaginary (+ (send ?cl get-imaginary) (send ?c2 get- imaginary))))) Все действия, выполняемые этим методом, сводятся к тому, что складываются части real комплексных чисел, а затем части imaginary комплексных чисел, после чего они сохраняются во вновь созданном экземпляре класса. Приведенные ниже примеры создания экземпляров класса COMPLEX и сложения представленных ими комплексных чисел показывают, что данный метод работает правильно (make-instance с of COMPLEX (real 3) (imaginary 4)) [cl) CLIPS> (make-instance c2 of COMPLEX (real 5) (imaginary 6)) 1 [c2] CLIPS> (+ [c1] [c2] ) J [genlj 11.14. Функции запроса множества экземпляров 925 CLIPS> (send [gen321] print)J [gen1] of COMPLEX (real 8) (imaginary 10) CLIPS> 11.14 Функции запроса множества экземпляров В языке не только предусмотрены возможности применять операции сопоставления с шаблонами к объектам, но допускается непосредственная передача запросов системе, касающихся множеств экземпляров, которые удовлетворяют заданному множеству условий. Для иллюстрации применения этих функций будут служить следующие конструкции, представляющие небольшое генеалогическое дерево (defclass PERSON (is — а USER) (slot full-name) (slot gender) (multislot children)) (defclass FEMALE (is à PERSON) (slot gender (access read-only) (storage shared) (default female))) (defclass MALE (is à PERSON) (slot gender (access read-only) (storage shared) (default male))) (definstances people (р of патер) (р of FEMALE патер (пате "Bob Jones" ) (children [рб])) (р of FEMALE (пате "Рат Jones" ) (children [рб]))
Глава 11. Классы, экземпляры и обработчики сообщений 926 ([p5] of MALE (full — патер) ([рб] of FEMALE патер) Определение того, успешно ли выполнен запрос Простейшей из функций запроса является функция any-instancep, которая имеет следующий синтаксис ) (+) В этом определении терм member — template> имеет такую форму ( +) Терм — name — expression> — это классы, содержащие экземпляры, которые по отдельности должны быть связаны с переменной — field- variable>. Наиболее простая проверка, которая может быть выполнена с помощью функции any — состоит в определении того, существует ли какой-либо экземпляр некоторого класса CLIPS> (any-instancep (р) TRUE)J FALSE CLIPS> (reset)J CLIPS> (р PERSON)) TRUE)J TRUE CLIPS> В данном примере какие- либо экземпляры класса PERSON не обнаруживаются до тех пор, пока не выполняется команда reset и не создаются экземпляры В данном определении терм template> представляет собой спецификацию классов, в которых должен осуществляться поиска терм — это булево выражение, которому должны соответствовать согласующиеся с запросом экземпляры этих классов. Если обнаруживается непустое множество экземпляров, удовлетворяющих запросу, то функция any — instancep возвращает символ TRUE; в противном случае она возвращает символ FALSE. Терм template> имеет следующий синтаксис. Функции запроса множества экземпляров 927 в конструкциях def instances с именем people. В качестве запросе используется символа это означает, что запросу удовлетворяет любой экземпляр, присвоенный переменной ? р. Если бы создавались только экземпляры MALE и FEMALE, то можно было бы определить, есть ли какие-либо экземпляры класса PERSON, просто указав эти два класса CLIPS> (any- instancep (р MALE FEM3QiE)) TRUE)J TRUE CLIPS> С другой стороны, наличие экземпляров класса MALE можно определить с помощью любого из следующих трех запросов CLIPS> (any- instancep (р M3QiE)) TRUE)J TRUE CLIPS> (any-instancep (р) (eq (send р get-gender) male))J TRUE CLIPS> (any- instancep (р PERSON)) (eq р male))J TRUE CLIPS> В первом случае проводится поиск экземпляров класса MALE, в отношении которых известно, что слот gender содержит значение male. Во втором случае экземпляру присвоенному переменной р, передается сообщение get — gender и используется функция eq для определения того, равно ли полученное значение символу male. В третьем случае показано, как можно использовать сокращенное обозначение слота с переменными, связанными в шаблоне множества экземпляров. В шаблоне может быть также задано несколько элементов множества экземпляров примерно таким образом (any-instancep ((?2 FEM3QiE) (р PERSON)) (аепЬех$ р TRUE CLIPS> В данном примере проверяется, являются ли какие-либо представительницы класса Женщина) матерями. К каждой комбинации экземпляров класса с экземплярами класса PERSON применяется запрос для определения то- Глава 11. Классы, экземпляры и обработчики сообщений 928 го, является ли экземпляр PERSON? родним из детей (лица женского пола, данные о котором представлены с помощью экземпляра FEMALE ? f. Определение экземпляров, удовлетворяющих запросу Функции запроса find-instance и find- all-instances имеют синтаксис, подобный синтаксису функции any — instancep: (find-instance ) (find- all-instances ) Но функция запроса find — instance возвращает не символ TRUE или а многозначное значение, содержащее первое множество экземпляров, удовлетворяющее запросу. Если не обнаруживается множество экземпляров, удовлетворяющее запросу, то возвращаемое многозначное значение остается пустым. Аналогичным образом, функция find — all — instances возвращает многозначное значение, содержащее все множества экземпляров, удовлетворяющих запросу, например, как показано ниже. CLIPS> (find-instance (р MALE)) TRUE)J ([pl]) CLIPS> (find-all-instances (р MALE)) TRUE)J (р [рЗ] р р) CLIPS> (find-all-instances (р MALE)) (eq р female) ) J () В том случае, если в шаблоне задано несколько элементов множества, необходимо обеспечить группирование элементов в возвращаемом значении программным путем, например, как в следующем диалоге CLIPS> (find-all-instances ((?f УЕМИЕ) (?p PERSON)) (members р ?f:children))J (р р р [рб] [рб] р (deffunction print-mother-message (Экземпляры р и р принадлежат к первому множеству экземпляров, экземпляры р и [pá] — ко второму множеству экземпляров, а экземпляры [рб] и р к третьему множеству экземпляров. Ниже приведена конструкция de f f unction, которая показывает, как можно сгруппировать элементы множеств экземпляров программным путем. Функции запроса множества экземпляров 929 (bind ? iterations (div (length( ?query-result) 2)) (loop-for-count (?i ?iterations) do (bind ?mother (nth$ (- (* 2 ?i) 1) ?query-result)) (bind ? child (nth$ (* 2 ?i) ?query — result)) (printout t (send ?mother get- full-name) is the mother of (send ?child get-full-name) 11 и cr] f ) ) ) CLIPS> (print-mother message (find-all-instances ((7f F1M3QiE) (р) (members р 7f: children) ) ) J Jan Smith is the mother of Frank Smith. Pam Jones is the mother of Sue Jones. Sue Jones is the mother of Dave Smith. FALSE CLIPS> Выполнение действий над экземплярами, удовлетворяющими запросу Функции запроса до4ог-1пйапсе, до4ог-а11 1пйапсея и delayed-до4ог-аll- instances позволяют выполнять необходимые действия надмножествами экземпляров, удовлетворяющих запросу. Эти функции имеют такой синтаксис (do-for-instance *) (do-for-all-instances *) (delayed-do-for-all-instances *) Длина возвращаемого значения запроса делится на количество экземпляров в расчете на каждое множество элементов для определения количества множества элементов, подлежащего обработке в цикле. Затем используется функция loop — for — count в сочетании с функцией nth$ для извлечения значения для каждого экземпляра в множестве элементов. С помощью сообщения print — mother — message с возвращаемым значением, равным результату предыдущего вызова find — all — instances, вырабатываются следующие результаты Глава 11. Классы, экземпляры и обработчики сообщений Функция do — for — instance применяет указанные действия к первому множеству экземпляров, удовлетворяющих запросу, например, таким образом CLIPS> (do-for-instance ((?f УЕИЪТЛ) (?р PERSON)) (вевЬех$ р ?f:children) (printout t ?f:full-name " is the mother of " р "." crlf))J Jan Smith is the mother of Frank Smith. CLIPS> Функция do — for — all — instances выполняет указанные действия над всеми множествами экземпляров, удовлетворяющих запросу, например, следующим образом CLIPS> (do-for-all-instances ((?f УЕМАТЛ) (р PERSON))
|
|
|