David Clarance
David Clarance

Reputation: 528

Writing a defrule that extends a deftemplate

Suppose I have

(deftemplate a-template (slot A) (slot B))

and from an earlier rule I have A => C. I want to extend the template to

(deftemplate a-template (slot A) (slot B) (slot C))

How do you a write a rule that uses pre-existing rules to populate a fact template.

Thanks in advance

Upvotes: 0

Views: 1248

Answers (1)

Gary Riley
Gary Riley

Reputation: 10757

You can't redefine a deftemplate if any facts currently make use of that deftemplate:

CLIPS> (clear)
CLIPS> (deftemplate a-template (slot A) (slot B))
CLIPS> (deftemplate a-template (slot A) (slot B) (slot C))
CLIPS> (assert (a-template))
<Fact-1>
CLIPS> (deftemplate a-template (slot A) (slot B) (slot C) (slot D))

[CSTRCPSR4] Cannot redefine deftemplate a-template while it is in use.

ERROR:
(deftemplate MAIN::a-template
CLIPS>

However, if no such facts exist you can use introspection functions to examine the existing deftemplate in conjunction with the build function to create a new deftemplate:

CLIPS> (clear)
CLIPS> 
(deffunction add-slot (?template ?slot)
   (bind ?slots (deftemplate-slot-names ?template))
   (if (member$ ?slot ?slots)
      then
      (return))
   (bind ?build (str-cat "(deftemplate " ?template))
   (progn$ (?s ?slots)
      (if (deftemplate-slot-multip ?template ?s)
         then
         (bind ?build (str-cat ?build " (multislot " ?s ")"))
         else
         (bind ?build (str-cat ?build " (slot " ?s ")"))))
   (bind ?build (str-cat ?build " (slot " ?slot ")"))
   (bind ?build (str-cat ?build ")"))
   (build ?build))
CLIPS> (deftemplate a-template (slot A) (slot B))
CLIPS> (ppdeftemplate a-template)
(deftemplate MAIN::a-template
   (slot A)
   (slot B))
CLIPS> (add-slot a-template C)
TRUE
CLIPS> (ppdeftemplate a-template)
(deftemplate MAIN::a-template
   (slot A)
   (slot B)
   (slot C))
CLIPS> 

If you wanted to redefine a template with existing facts, you'd need to save the existing facts using the save-facts function, retract all of them, redefine the template, and then reload the saved facts. This could cause rules matching the existing facts to be placed on the agenda if they had already executed.

Upvotes: 1

Related Questions