我正在尝试使用CLIPSPY修改来自python的事实模板。它的行为很奇怪,因为它第一次修改了一个插槽,但对于下一个插槽,它不会,甚至会将之前修改的插槽值重新修改为其他值!!
这是python文件。
# run.py
import clips
clips_env = clips.Environment()
def py_modify_s1(p):
p.retract()
p["s_1"] = clips.Symbol("ABC")
p.assertit()
def py_modify_s2(p):
p.retract()
p["s_2"] = clips.Symbol("DEF")
p.assertit()
clips_env.define_function(py_modify_s1)
clips_env.define_function(py_modify_s2)
clips_env.load("KB.clp")
clips_env.reset()
clips_env.run()这是clp文件。
(deftemplate t
(slot s_1 (type SYMBOL) (default none))
(slot s_2 (type SYMBOL) (default none))
)
(defrule rule_0
(initial-fact)
=>
(assert (t))
)
(defrule rule_1
?p<-(t (s_1 none) (s_2 none))
=>
(py_modify_s1 ?p)
(facts)
)
(defrule rule_2
?p <- (t (s_1 ?x&~none) (s_2 none))
=>
(py_modify_s2 ?p)
(facts)
)
(defrule rule_3
?p <- (t (s_1 ?x&~none) (s_2 ?y&~none))
=>
(printout t "All set")
(facts)
)在clip shell中运行相同的剪辑文件(用(modify ?p (s_1,ABC))替换py_modify )会产生预期的结果。但是从clipspy运行我得到了:
f-0 (initial-fact)
f-2 (t (s_1 ABC) (s_2 none))
For a total of 2 facts.
f-0 (initial-fact)
f-2 (t (s_1 ▒▒▒3wU) (s_2 none))
For a total of 2 facts.注意,在触发rule_2之后,s_1包含了一些无用的值,并且s_2并没有被修改。因此,rule_3永远不会被解雇。
发布于 2019-01-02 07:15:36
事实证明,一旦通过C(以及Python) API断言,就不能修改事实。改变一个事实的唯一方法是收回原来的事实并断言一个新的事实。《高级编程指南》的4.4.22 EnvPutFactSlot章。
唯一可能的方法似乎是收回旧的事实,并用更新的值断言新的事实。
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()我也在CLIPS论坛上的discussion中提出了这个问题。
https://stackoverflow.com/questions/53998103
复制相似问题