How exactly (refresh) works in the clips?

2019-08-31 04:22发布

I want to rematch the rule when using CLIPS. But the refresh command doesn't work well every time. So I did some test but still confused about it.

Q1: can (refresh) work with those rules modifing facts? I create a .CLP:

>     (defglobal ?*lock* = 0)
>     
>     (deftemplate counter
>       (slot number))
>     
>     (deffacts initial-data
>       (counter (number 0)))
>     
>     (defrule rule-1
>     ?f<-(counter (number ?x))
>     (test (= ?*lock* 0))
>     =>
>     (printout t "counter number1" crlf)
>     (bind ?*lock* (+ ?*lock* 10))
>     (modify ?f (number (+ ?x 1)))
>     )
>     
>     (defrule rule-2
>     ?f<-(counter (number ?x))
>     (test (= ?*lock* 10))
>     =>
>     (printout t "counter number2" crlf)
>     (bind ?*lock* 0)
>     )

after run the first time, the lock becomes to 0. but then I type (refresh rule-1), the rule-1 doesn't enter into the agenda. I wonder if it is because the modify action in the RHS cause the problem.

Q2: does the global value work in the LHS when using refresh?

another strange point is that after run for the first time. the lock has been changed to 0.I type (refresh rule-2), and find rule-2 is in the agenda again. But the LHS of rule-2 has restrict that lock should equals to 10 if rule to want to be matched. It seems that the test condition doesn't work at all. But the test condition has actually works when I first run the system which I mean typing (reset) and (run) to run the system. what show on the terminal is like this:

CLIPS> (reset)
==> Activation 0      rule-1: f-1
CLIPS> (facts)
f-0     (initial-fact)
f-1     (counter (number 0))
For a total of 2 facts.
CLIPS> (run)
counter number1
==> Activation 0      rule-2: f-2
counter number2
CLIPS> (refresh rule-1)
CLIPS> (refresh rule-2)
==> Activation 0      rule-2: f-2
CLIPS> (run)
counter number2

I wonder if there is some different between (run) and (refresh) when firing rules?

It really confuses me. Thank you for any answer.

标签: clips
1条回答
兄弟一词,经得起流年.
2楼-- · 2019-08-31 04:36

Global variables do not trigger pattern matching so you shouldn't use them in the condition of a rule unless their value never changes. Use a facts or instances to store a value rather than a global. There's information on the behavior of globals in section 6 of the Basic Programming Guide, http://clipsrules.sourceforge.net/documentation/v630/bpg.htm, and another discussion on their behavior here: Number equality test fails in CLIPS pattern matching?.

In this specific example, when you perform a (reset), the counter fact is asserted which triggers pattern matching. The first condition of rule-1 and rule-2 is matched and then the subsequent test containing the global is evaluated using the current value of the global.

When rule-1 executes, the value of the global is first changed. This does not trigger any pattern matching. It's only when the counter fact is modified that pattern matching is triggered. The first condition of rule-1 and rule-2 are then reevaluated and then the subsequent test containing the global and its current value are evaluated.

When rule-2 is executed the global is again changed, but this does not trigger pattern matching. There are no changes made to any facts. As far as the conditions of rule-1 and rule-2 are concerned, there's been no changes to the data causing the rules to be satisfied. So when you do a refresh, the conditions of both of these rules consider the value of ?lock to be 10.

CLIPS> (watch rules)
CLIPS> (watch globals)
CLIPS> (watch facts)
CLIPS> (watch activations)
CLIPS> (reset)
<== f-0     (initial-fact)
:== ?*lock* ==> 0 <== 0
==> f-0     (initial-fact)
==> f-1     (counter (number 0))
==> Activation 0      rule-1: f-1
CLIPS> (run)
FIRE    1 rule-1: f-1
counter number1
:== ?*lock* ==> 10 <== 0
<== f-1     (counter (number 0))
==> f-2     (counter (number 1))
==> Activation 0      rule-2: f-2
FIRE    2 rule-2: f-2
counter number2
:== ?*lock* ==> 0 <== 10
CLIPS>

Bottom line, do not use global variables in the manner that you have been using them. They were not designed for this purpose. If you want to pass information from one rule to the conditions of another, use facts and/or instances.

查看更多
登录 后发表回答