0

我是 Jess The Rule Engine 的新手,我在进行简单查询时遇到了问题。我有一个简单的 java bean 文件和一个 .clp 文件。通过使用 java bean 文件,我创建了 word 对象,并通过使用 .clp,我通过定义规则对导入的 java 对象进行了一些处理,这些对象现在位于 Jess 的工作内存中。在我描述的规则的末尾,我想执行一个查询,该查询将找到最高的 sentenceNumber - sentenceNumber 是我的 Word 事实中的一个槽变量 - 通过使用累积条件元素。而且我想将结果值返回给 Java 代码。问题是,如果我在查询中使用累积 CE 而不是在 defrule 中,我写的查询会给我错误。

所以我的问题是:在查询中使用累积 CE 是否不合适?我找不到任何说是或否的材料。

下面我给你我的查询:

(defquery get-Total-Sentence-Number
 "this query gets the total number of newly created sentences"
 ;(accumulate <initializer> <action> <result> <conditional element>)
 ?result <- (accumulate (bind ?max FALSE) ;initializer
                        (if (or (not ?max);action
                        (> ?sentenceNumber ?max))
                             then (bind ?max ?sentenceNumber))
                        ?max ;result
                        (Word (sentenceNumber ?sentenceNumber))))

请帮忙。谢谢

ps 我不想在 defrule 中使用累积 CE,因为据我了解,规则会在事实列表的每次更改中一次又一次地触发。我只想执行一次,在我定义的规则结束时需要它。

4

1 回答 1

0

我认为有一个限制。无论如何,在查询中运行累积是没有意义的。定义一个返回事实的查询会更容易:

(defquery get-words
   (Word (sentenceNumber ?sentenceNumber)))

运行它,并评估查询集合的迭代中的最大值:

(bind ?result (run-query* get-words))

(bind ?max 0)
(while (?result next) do
    (bind ?snr (?result getString sentenceNumber))
    (if (> ?snr ?max) then (bind ?max ?snr))
)
(printout t "max: " ?max crlf)

稍后 然后我推荐以下方法:

;; define an auxiliary fact
(deftemplate MaxWord (slot maxSentence))

;; initialze one fact
(deffacts  maximum
  (MaxWord (maxSentence 0))
)

;; a rule to compute the maximum
(defrule setMax
  ?mw <- (MaxWord (maxSentence ?ms))
  (Word (sentenceNumber ?snr & :(> ?snr ?ms)))
=>
  (modify ?mw (maxSentence ?snr))
)

 ;; the query
(defquery getMax
   (MaxWord (maxSentence ?maxSentence)))

;; obtain the result
(bind ?result (run-query* getMax))
(?result next)
(bind ?max (?result getString maxSentence))
(printout t "max: " ?max crlf)

请注意,如果撤回 Word 事实,这将无法正常工作,这势必会使最大值无效。

可以通过使用具有累积的规则和在触发规则时需要断言的初始(辅助)事实来实现完全不同的方法。这样可以避免频繁重复累加。基本上:

(defrule "calcMax"
  (FreeToCalc)
  ?result <- (accumulate (bind ?max 0)
                    (if  (> ?sentenceNumber ?max)
                         then (bind ?max ?sentenceNumber))
                    ?max
              (Word (sentenceNumber ?sentenceNumber))))
 =>
 ;;...
 )
于 2014-08-07T15:57:49.717 回答