1

我正在开发一个专家系统,它将使用 PyClips 做出录取决定。但是,代码不断产生“内存不足”错误。我想我已经隔离了我的问题。我的 CLIPS 文件有问题。希望有人能看到我在这里做错了什么。这是代码的最简单版本....为了调试它,我进行了简化:所以这是我的模板,为了论证,只有一条规则:如果收到成绩单,则 app-complete属性被标记为 TRUE。

; template for application facts
(deftemplate application "structure of an application"
(slot app-id (type INTEGER))
(slot app-complete (type SYMBOL))
(slot transcript-received (type SYMBOL))
 )


(defrule complete "rule for app completeness"

?f <- (application
        (transcript-received Yes)    
    )
=>
    (modify ?f
        (app-complete TRUE)
    )
)
; end.

所以当我这样做时(assert (application (app-id 123) (transcript-received Yes))) ,我的事实是被添加的。当我点击运行时.... CLIPS 中的窗口开始被成千上万的事实超载... app-complete 属性看起来被标记为 TRUE,然而,事实只是不停地循环和循环。当事实太多时,我说的是100K之类的……然后CLIPS就退出了……知道我在这里做错了什么吗?我的语法以某种方式搞砸了?我的意图是让一个 sqlite 数据库能够从数据库中读取“事实”,以便系统能够做出决定......但我无法超越这个!

4

1 回答 1

2

要记住的重要一点是,当您修改一个deftemplate事实时,该事实将被撤回并断言一个新的(修改后的)事实。您的规则也匹配修改后的事实,然后再次修改和匹配等,从而导致无限循环。如果您在运行代码时观察事实和激活,您会看到如下内容:

<== f-1     (application (app-id 123) (app-complete nil) (transcript-received Yes))
==> f-2     (application (app-id 123) (app-complete TRUE) (transcript-received Yes))
==> Activation 0      complete: f-2
<== f-2     (application (app-id 123) (app-complete TRUE) (transcript-received Yes))
==> f-3     (application (app-id 123) (app-complete TRUE) (transcript-received Yes))
==> Activation 0      complete: f-3
<== f-3     (application (app-id 123) (app-complete TRUE) (transcript-received Yes))
==> f-4     (application (app-id 123) (app-complete TRUE) (transcript-received Yes))
==> Activation 0      complete: f-4
(etc.)

您可以通过仅匹配尚未完成的应用程序来防止这种情况。这是您的代码的修改版本,它FALSEapp-complete插槽添加了默认值,并且仅匹配不完整的应用程序:

(deftemplate application "structure of an application"
  (slot app-id (type INTEGER))
  (slot app-complete (type SYMBOL) (default FALSE))
  (slot transcript-received (type SYMBOL)))

(defrule complete "rule for app completeness"
  ?f <- (application (transcript-received Yes) (app-complete FALSE))
  =>
  (modify ?f (app-complete TRUE)))

现在,如果您观察事实和激活,当您断言事实并运行时,您应该会看到以下内容:

CLIPS> (assert (application (app-id 123) (transcript-received Yes)))
==> f-0     (application (app-id 123) (app-complete FALSE) (transcript-received Yes))
==> Activation 0      complete: f-0
<Fact-0>
CLIPS> (run)
<== f-0     (application (app-id 123) (app-complete FALSE) (transcript-received Yes))
==> f-1     (application (app-id 123) (app-complete TRUE) (transcript-received Yes))
CLIPS>
于 2013-04-09T13:11:33.997 回答