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.
The
environment.build
method is for building constructs (defrule
,deftemplate
, etc.) within the engine. To execute CLIPS code, you need to useenvironment.eval
.In CLIPS 6.30 it's not possible to change a fact once asserted (6.40 added APIs for that). Only way to do so is by retracting the old one and asserting a new one with updated values.
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 viaenvironment.eval
as fact indexes cannot be used via the API. If you want to modify a fact within a rule, you'd better use themodify
command directly.