写一个扩展deftemplate的defrule

时间:2015-02-26 04:16:33

标签: clips

假设我有

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

从早期的规则我得到A => C.我想将模板扩展到

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

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

提前致谢

1 个答案:

答案 0 :(得分:0)

如果目前有任何事实使用该模板,则无法重新定义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函数保存现有事实,撤回所有事实,重新定义模板,然后重新加载保存的事实。这可能导致与现有事实匹配的规则如果已经执行则被列入议程。