Функция Python в LHS правила CLIPS вызывается несколько раз - как ждать, пока переменная будет содержать значение?

Я прочитал здесь, как вызвать функцию Python для lhs правила клипов.

Теперь у меня есть следующее правило:

(defrule python_func_lhs "comment me"
    (object (is-a clips_TEST_CLASS) (some_slot ?some_slot_value))
    (test (eq (python-call python_print (str-cat "some_slot: " ?some_slot_value)) TRUE))
    =>
    ;(assert (do_something))
)

Моя проблема в том, что функция Python вызывается дважды, сначала печатая

some_slot: nil

а потом

some_slot: some_slot_value

Кажется, что вторая часть правила, содержащая функцию python, не "ждет" соответствия первой части правила LHS.

Как я могу сделать, чтобы клипы вызывали функцию python только один раз, если первая часть правила LHS совпадает? Другими словами, я хочу подождать, пока ?some_slot_value переменная имеет значение.

Если возможно, я бы хотел избежать создания нескольких правил и использования "контрольных фактов".

1 ответ

Решение

Различные механизмы правил имеют разные средства указания, когда изменения объекта завершены, но, вообще говоря, когда вы вносите несколько различных изменений в объект, процесс сопоставления с образцом будет вызываться один раз для каждого изменения. Вы включили фрагмент кода, а не воспроизводимый пример, в свой вопрос, чтобы я мог только догадываться о причине вашей проблемы, но, вероятно, вы создаете объект, а затем изменяете его в отдельном шаге. Сопоставление с образцом задерживается при создании объекта до тех пор, пока не будут обработаны все переопределения слотов, и аналогично при внесении изменений в объект можно использовать функцию modify-instance, чтобы сгруппировать коллекцию изменений слотов как одно изменение. Если вам нужно отложить сопоставление с образцом при нескольких вызовах функций, вы можете использовать функцию сопоставления с образцом.

CLIPS> 
(defclass clips_TEST_CLASS
   (is-a USER)
   (slot some_slot))
CLIPS>    
(definstances initial
   (i1 of clips_TEST_CLASS (some_slot some_slot_value)))   
CLIPS> 
(deffunction pcall (?v) (printout t ?v crlf) TRUE)
CLIPS> 
(defrule python_func_lhs 
    (object (is-a clips_TEST_CLASS) (some_slot ?some_slot_value))
    (test (pcall (str-cat "some_slot: " ?some_slot_value)))
    =>)
CLIPS> (reset)
some_slot: some_slot_value
CLIPS> (make-instance i2 of clips_TEST_CLASS (some_slot some_other_value))
some_slot: some_other_value
[i2]
CLIPS> (make-instance i3 of clips_TEST_CLASS)
some_slot: nil
[i3]
CLIPS> (send [i3] put-some_slot another_value)
some_slot: another_value
another_value
CLIPS> 
(object-pattern-match-delay
   (make-instance i4 of clips_TEST_CLASS)
   (send [i4] put-some_slot still_another_value))
some_slot: still_another_value
still_another_value
CLIPS> (modify-instance [i4] (some_slot value))
some_slot: value
TRUE
CLIPS>
Другие вопросы по тегам