0

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.

noxdafox
  • 14,439
  • 4
  • 33
  • 45
greenlantern
  • 374
  • 1
  • 3
  • 15
  • It is not necessary to add the initial-fact to a rule with no other conditions; it is added automatically in versions of CLIPS prior to version 6.3. The initial-fact functionality was deprecated in the 6.3 release; it is still asserted by a reset, but rules without conditions no longer rely on it. In the 6.4 release, the initial-fact is no longer asserted, so rules that explicitly match this fact will no longer be activated. – Gary Riley Jan 03 '19 at 17:29

1 Answers1

2

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 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.

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)))
noxdafox
  • 14,439
  • 4
  • 33
  • 45
  • Can we send a root level command using clipsPy? Something like SendCommand, because Eval raises an error if I send a modify statement in it. – greenlantern Dec 30 '18 at 18:28
  • `clipspy` does not support such feature. It makes little sense to eval CLIPS commands in Python when you can simply execute them natively within the rules. The `eval` method should be really used in corner cases as it is quite slow. – noxdafox Dec 30 '18 at 19:39
  • For my use case, I need to analyse user input to decide which slot of template needs to be modified/asserted/retracted or to handle some special cases. Not sure but may be SendCommand would have been helpful for special cases. (I'm still learning clips. I have experimented with PyCLIPS which supports both Eval and SendCommand) – greenlantern Dec 30 '18 at 19:56
  • I'd recommend you to explain what you are trying to achieve in a more broad question then. State what are you trying to do. What have you done so far and what is the challenge you are facing. – noxdafox Dec 30 '18 at 19:59
  • You can also use the CLIPS forum for open ended questions and recommendations. – noxdafox Dec 30 '18 at 20:02
  • Sure. Btw It is briefly explained [here](http://pyclips.sourceforge.net/web/?q=node/13) that some actions behave differently when evaluated and hence the SendCommand in PYCLIPS. I don't know which are these actions and if I will need to use them in future. However if you can confirm such an issue will not come up in CLIPSPY It'll save me some time. – greenlantern Dec 30 '18 at 20:09