【问题标题】:Jess defquery and accumulate CEJess defquery 和累积 CE
【发布时间】:2014-08-07 11:45:46
【问题描述】:

我是 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))))

请帮忙。 谢谢

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

【问题讨论】:

    标签: rule-engine jess accumulate


    【解决方案1】:

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

    (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))))
     =>
     ;;...
     )
    

    【讨论】:

    • 您好,非常感谢您的回复。但是我想将查询结果返回到Java代码-我的错误我没有在描述中指定它,对不起。通过使用您编写的代码,我需要用 Java 实现代码的第二部分,我不想要它。我想在 Jess 中做所有事情,只将最终结果作为整数值返回给 Java。
    • 再次您好,感谢您的建议。我将您的第二个解决方案与显着性结合起来,并将 maxSentence 插槽的值返回给 Java - 我认为这非常复杂。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-15
    • 2013-12-25
    • 2014-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多