【问题标题】:Complex conditional element in accumulate in Jess rulesJess规则中累积的复杂条件元素
【发布时间】:2014-12-27 08:26:32
【问题描述】:

我试图在 JessTab 中找到温度观测值的平均值,这需要加入来自多个类的事实。以下规则:

(defrule averageOfObsValue  
?res <- 
(accumulate  
    (progn (bind ?s 0)(bind ?n 0)) 
    (progn (bind ?s (+ ?s ?v)) (++ ?n)) 
    (create$ ?n ?s ?qo) 
    (and  
        (object (is-a http..#ObservationValue) 
                (OBJECT ?ov)
                (http..#hasDataValue ?v)
        )
        (object (is-a http..#SensorOutput) 
                (OBJECT ?so) 
                (http..#hasValue ?ov)
        )
        (object (is-a http..#Observation)
                (OBJECT ?o)
                (http..#observationResult ?so)
                (http..#qualityOfObservation ?qo)
        )   
    )
)
=>  
(bind ?q (nth$ 3 ?res))  
(bind ?s (nth$ 2 ?res))  
(bind ?n (nth$ 1 ?res))  
(if (= (?q getURI) "http..#Temperature") then
(printout t "Average value is " (/ ?s ?n) " of " ?n " temperature observations." crlf)))

在WM中有如下形式:

(defrule MAIN::averageOfObsValue 
   (or 
     (and 
       (object (is-a http..#ObservationValue) 
               (OBJECT ?ov) 
               (http..#isValueOf ?so) 
               (http..#hasDataValue ?v))) 
     (and 
       (object (is-a http..#SensorOutput) 
               (OBJECT ?so) (http..#isObservationResultOf ?o))) 
     (and 
       (object (is-a http..#Observation) 
               (OBJECT ?o) (http..#qualityOfObservation ?qo)))) 
   => 
   (bind ?q (nth$ 3 ?res)) 
   (bind ?s (nth$ 2 ?res)) 
   (bind ?n (nth$ 1 ?res)) 
   (if (= (?q getURI) "http..#Temperature") then
   (printout t "Average value is " (/ ?s ?n) " of " ?n " temperature observations." crlf)))

运行时出现以下错误:

Jess 在例程 Context.getVariable 中报告错误 执行时 (nth$ 3 ?res) 执行时 (bind ?q (nth$ 3 ?res)) 在执行 defrule MAIN::averageOfObsValue655 在执行(运行)时。 消息:没有这样的变量 res。 程序文本:(运行)在第 137 行。

【问题讨论】:

  • (progn (bind ?s 0)(bind ?n 0) 行中有一个相当明显的语法错误 - 没有右括号。
  • @laune 我解决了这个问题并修改了问题

标签: rules protege jess


【解决方案1】:

似乎(您最近的观察证实了这一点)累积不能应用于带有连词的 CE。最好的方法是创建包含需要计算平均值的值的临时事实,但必须注意创建不同的临时事实

(deftemplate Value (slot v)(slot s)

(defrule createValueFacts
    (declare (salience 100))
    (object (is-a http..#ObservationValue) 
            (OBJECT ?ov)
            (http..#hasDataValue ?v)
    )
?s<-(object (is-a http..#SensorOutput) 
            (OBJECT ?so) 
            (http..#hasValue ?ov)
    )
    (object (is-a http..#Observation)
            (OBJECT ?o)
            (http..#observationResult ?so)
            (http..#qualityOfObservation ?qo)
    )
=>
    (assert (Value (v ?v)(s ?s))   ; using slot s to make fact unique
)

这些Value的事实很容易积累:

(defrule averageOfObsValue 
?res <- (accumulate  
    (progn (bind ?s 0)(bind ?n 0)) 
    (progn (bind ?s (+ ?s ?v)) (++ ?n)) 
    (create$ ?n ?s) 
    (Value (v ?v)))
=>
(bind ?s (nth$ 2 ?res))  
(bind ?n (nth$ 1 ?res))  
(printout t "Average value is " (/ ?s ?n) " of " ?n " temperature observations." crlf))

【讨论】:

  • 在 RBS 中,引擎可能存在一种自动删除重复事实的模式。不确定 Jess 是否有这种模式,以及它是如何(停用)激活的。我在 Jess 文档中没有找到对此的参考。显然这是不可修改的默认行为。 - 在我的 A 中添加注释。
  • 感谢它的工作:)。但是,只有不同的 v 值在 WM 上被断言,因为相同的值会相互覆盖,因此平均值不正确。知道如何解决这个问题...
  • 我刚刚添加了s.th。致我的 A。我不确定你的三重事实中有什么独特之处;如有必要,添加另一个插槽。 -- 事实是“真理”,在 Jess 中不能重复——它不会变得更真实。
  • 另一种方法是将值累积到一个单一的事实中。在这种情况下,不要插入而是修改并使用 no-loop 来避免循环。需要第一个高显着性规则来创建总和,并将其槽设置为零。
  • 我根据新插槽的唯一值使用了 URI,它给出了结果。再次感谢您的快速回复
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-16
  • 1970-01-01
  • 2021-09-12
  • 2015-11-27
  • 2016-01-04
  • 1970-01-01
相关资源
最近更新 更多