Search code examples
global-variablesclips

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

Solution

  • 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)