Programmatically modify a fact slot using ClipsPy

微笑、不失礼 提交于 2019-12-11 17:08:08

问题


How to modify a fact of a template in CLIPS using ClipsPy.

I have tried the reassigning slot value and sending modify in clips.build routine, (see py_modify function below) which did not work.

This is the .clp file

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

This is the python file..

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

The ouput is

 BEFORE
(initial-fact)
(t (s_1 v_1))
--modifying v_1
AFTER
(initial-fact)
(t (s_1 v_1))

I expect s_1 slot to be modified to v_2 from v_1, but it is not.


回答1:


The environment.build method is for building constructs (defrule, deftemplate, etc.) within the engine. To execute CLIPS code, you need to use environment.eval.

In CLIPS it's not possible to change a fact once asserted. Only way to do so is by retracting the old one and asserting a new one with updated values.

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 provides the modify command which does the exact same: retracts the fact and asserts it with the new value. Nevertheless, it cannot be used via environment.eval as fact indexes cannot be used via the API. If you want to modify a fact within a rule, you'd better use the modify command directly.

(defrule rule_1
  ?p <- (t (s_1 ?v))
  =>
  (modify ?p (s_1 v_2)))


来源:https://stackoverflow.com/questions/53967519/programmatically-modify-a-fact-slot-using-clipspy

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!