编写扩展 deftemplate 的 defrule

Writing a defrule that extends a deftemplate

假设我有

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

根据之前的规则我有 A => C。我想将模板扩展到

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

您如何编写使用预先存在的规则来填充事实模板的规则。

提前致谢

如果当前有任何事实正在使用 deftemplate,则不能重新定义 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>

但是,如果不存在这样的事实,您可以使用内省函数检查现有的 deftemplate 并结合构建函数来创建新的 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> 

如果您想使用现有事实重新定义模板,则需要使用 save-facts 函数保存现有事实,收回所有事实,重新定义模板,然后重新加载保存的事实。如果已经执行,这可能会导致与现有事实相匹配的规则被列入议程。