Программно изменить слот фактов с помощью ClipsPy
Как изменить факт шаблона в CLIPS, используя ClipsPy.
Я попытался переназначить значение слота и отправить изменения в clips.build
рутина, (см. py_modify
функция ниже), которая не работает.
Это файл.clp
;; KB.clp
(deftemplate t
(slot s_1 (type SYMBOL)))
(defrule main-intent
(initial-fact)
=>
(assert (t (s_1 v_1)))
)
(defrule rule_1
?p<-(t (s_1 ?v))
=>
(printout t"BEFORE"crlf) (py_pfact)
(py_modify ?p)
(printout t"AFTER"crlf) (py_pfact)
)
Это файл с питоном..
# run.py
import clips
clips_env = clips.Environment()
def py_pfact():
for fact in clips_env.facts():
print(fact)
def py_modify(p):
print("--modifying",p["s_1"])
p["s_1"] = "v_2" # Try 1
clips.build("(modify "+str(p.index)+ " (s_1 v_2)") #Try 2
clips_env.define_function(py_pfact)
clips_env.define_function(py_modify)
clips_env.load("KB.clp")
clips_env.reset()
clips_env.run()
Выход является
BEFORE
(initial-fact)
(t (s_1 v_1))
--modifying v_1
AFTER
(initial-fact)
(t (s_1 v_1))
Я жду s_1
слот для изменения v_2
от v_1
, но это не так.
1 ответ
environment.build
метод для строительных конструкций (defrule
, deftemplate
и т. д.) внутри двигателя. Чтобы выполнить код CLIPS, вам необходимо использовать environment.eval
,
В CLIPS невозможно изменить один раз утвержденный факт. Единственный способ сделать это - убрать старый и установить новый с обновленными значениями.
def modify_fact(fact):
"""Modify a template fact."""
fact.retract()
new_fact = fact.template.new_fact()
new_fact.update(dict(fact)) # copy over old fact slot values
new_fact["s_1"] = clips.Symbol("v_2")
new_fact.assertit()
Клипы обеспечивает modify
Команда, которая делает то же самое: убирает факт и подтверждает его новым значением. Тем не менее, он не может быть использован через environment.eval
поскольку индексы фактов не могут быть использованы через API. Если вы хотите изменить факт в правиле, лучше использовать modify
Команда напрямую.
(defrule rule_1
?p <- (t (s_1 ?v))
=>
(modify ?p (s_1 v_2)))