user2018
user2018

Reputation: 43

How can I define a global variable in a defrule and use it in another defrule in CLIPS?

I wrote these code in CLIPS but it doesn't work. It says "Local variables can not be accessed by a deffact." I also want to use the value of number1 and number2 in other defrules. How can I define these variables as global in the rule?

(deffunction calculation1
(?x ?y)
(+ ?x ?y))
(defrule rule1
=>
(printout t "What is the first number?")
(bind ?number1 (read))
(assert (number-1 ?number1))
(printout t "What is the second number?")
(bind ?number2 (read))
(assert (number-2 ?number2))
(bind ?theirsum (calculation1 ?number1 ?number2))
(printout t "The sum is " ?theirsum crlf))
(deffacts data
(first num1 ?number1
second num2 ?number2))

Upvotes: 0

Views: 505

Answers (1)

kombinatorix
kombinatorix

Reputation: 122

The error message says exactly where the problem lies. I can only guess, what you are trying to accomplish. The problem is, deffacts are only asserted after an (reset). So, after a (reset) all facts are removed and deffacts are asserted. So the moment the deffacts statement is evaluated, no local variables are still present (Additionally: Local variables are only visible in the scope they are defined in: deffunction, defrule). Global variables won't work either, because they will be set back, the moment you call (reset). One solution that comes to my mind would be a hack: See Clips hack

You can also use CLIPS' build expression:

         CLIPS (6.30 3/17/15)
CLIPS> (defrule rule1
=>
    (printout t "What is the first number?")
    (bind ?number1 (read))
    (assert (number-1 ?number1))
    (printout t "What is the second number?")
    (bind ?number2 (read))
    (assert (number-2 ?number2))
    (bind ?theirsum (+ ?number1 ?number2))
    (printout t "The sum is " ?theirsum crlf)
    (build (str-cat
        "(deffacts data (first num1 " ?number1 " second num2 " ?number2     "))"
        )
    )
)
CLIPS> (run)
What is the first number?1
What is the second number?2
The sum is 3
CLIPS> (get-deffacts-list)
(initial-fact data)
CLIPS> (reset)
CLIPS> (facts)
f-0     (initial-fact)
f-1     (first num1 1 second num2 2)
For a total of 2 facts.

Or you could using a file:

         CLIPS (6.30 3/17/15)

CLIPS> (defrule rule1   
=>
    (printout t "What is the first number?")
    (bind ?number1 (read))
    (assert (number-1 ?number1))
    (printout t "What is the second number?")
    (bind ?number2 (read))
    (assert (number-2 ?number2))
    (bind ?theirsum (+ ?number1 ?number2))
    (printout t "The sum is " ?theirsum crlf)
    (printout data
        "(deffacts data (first num1 " ?number1 " second num2 " ?number2 "))"
    crlf)
    (close data)    
)
CLIPS> (run)
What is the first number?1
What is the second number?2
The sum is 3
CLIPS> (load data.dat)
Defining deffacts: data
TRUE
CLIPS> (get-deffacts-list)
(initial-fact data)

Upvotes: 1

Related Questions