Reputation: 414
I am trying to modify a fact of a fact-template in clips using ClipsPY. Following code retracts and reasserts the fact. Why is it that after the fact is retracted, the slot value s_2
is not nil
on reassert?
import clips
clips_env = clips.Environment()
def py_pfact():
for fact in clips_env.facts():
print(fact)
def py_modify(p):
print("\nfacts:")
py_pfact()
p.retract()
print("\nfacts after retracted:")
py_pfact()
p["s_1"] = clips.Symbol("v_2")
p.assertit()
print("\nfacts after re_assert:")
py_pfact()
clips_env.define_function(py_pfact)
clips_env.define_function(py_modify)
clips_env.load("KB.clp")
clips_env.reset()
clips_env.run()
This is the clp file
;; KB.clp
(deftemplate t
(slot s_1 (type SYMBOL))
(slot s_2 (type SYMBOL))
)
(defrule main-intent
(initial-fact)
=>
(assert (t (s_1 v_1) (s_2 v_2)))
)
(defrule rule_1
?p<-(t (s_1 ?v&~v_2))
=>
(py_modify ?p)
)
The output is:
facts:
(initial-fact)
(t (s_1 v_1) (s_2 v_2))
facts after retracted:
(initial-fact)
facts after re_assert:
(initial-fact)
(t (s_1 v_2) (s_2 v_2))
I expected output to be (t (s_1 v_2) (s_2 nil))
, however s_2
is not nil but previous set value v_2
which was set before the fact retracted.
Upvotes: 0
Views: 167
Reputation: 15060
Asserting and retracting a fact does not modify it. It simply adds/removes it from the engine knowledge base.
You can see a deftemplate
as a class and a fact
created from it like an object. You can extend the engine knowledge base by adding and removing facts either from the API or through the rules.
# define a fact template within the engine
environment.build('(deftemplate foo (slot bar) (slot baz))')
template = environment.find_template('foo')
# create a new fact and set its values
fact = template.new_fact()
fact['bar'] = 1
fact['baz'] = 1
# assert the fact within the engine
fact.assertit()
assert fact in environment.facts()
# retract it
fact.retract()
assert fact not in environment.facts()
assert fact is fact # fact is the same object as before
fact['baz'] = 2
assert fact is fact # still the same object
fact.assertit()
assert str(fact) == '(foo (bar 1) (baz 2))'
Upvotes: 0