Search code examples
clips

Defining "anonymous" rules in CLIPS


I know that rules in CLIPS are usually given names using defrule. This rule is called rule1:

(deftemplate animal (slot species))

(deffacts animal
  (animal (species dog)))

(defrule rule1
   (animal (species ?name))
   =>
   (printout t ?name crlf))
(reset)

(run)

(exit)
;

But I still don't know whether it is necessary for the rules to be named. Is it possible to define a rule without giving it a name, like this?

(deftemplate animal (slot species))

(deffacts animal
  (animal (species dog)))

(defrule
   (animal (species ?name))
   =>
   (printout t ?name crlf))
(reset)

(run)

(exit)
;

Solution

  • From section 5 of the Basic Programming Guide:

    (defrule <rule-name> [<comment>] 
       [<declaration>]
       <conditional-element>*
       =>
       <action>*)
    

    The rule name is required.

    To dynamically generate a rule name, use the gensym* function which creates a unique symbol:

    CLIPS> 
    (deffunction create-anonymous (?conditions ?actions)
       (bind ?str (str-cat "(defrule " (gensym*) " "
                            ?conditions " => " ?actions ")"))
       (build ?str))
    CLIPS> (deftemplate animal (slot species))
    CLIPS> 
    (create-anonymous "(animal (species ?name))"
                      "(printout t ?name crlf)")
    TRUE
    CLIPS> (rules)
    gen1
    For a total of 1 defrule.
    CLIPS> (ppdefrule gen1)
    (defrule MAIN::gen1
       (animal (species ?name))
       =>
       (printout t ?name crlf))
    CLIPS>