2015-09-25 10 views
0

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

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

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

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

some_slot: ноль

, а затем

some_slot: some_slot_value

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

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

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

+0

Что с этим связано Джесс? – laune

+0

@laune вопрос не является специфическим для pyclips. В jess также должно быть возможно вызвать java-функцию на lhs правила. Но вы правы, я буду перефразировать вопрос или удалить тег. – stackoverflowwww

+0

Я просто попробовал '(deffacts someData (Data (obj (new String" A "))))' и '(defrule find? Data <- (Data (obj? A)) (test (eq (call? длина) 1)) => (printt t "find выполнено" crlf)) 'в Джессе, и он отлично работает. – laune

ответ

2

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

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> 
+0

В следующий раз я приведу полный пример. Вы правильно поняли проблему - спасибо вам за то, что вы делитесь своими ноу-хау от клипов на SO – stackoverflowwww