问题
I am trying to find average value of temperature observations in JessTab which requires joining facts from multiple classes. The following rule:
(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)))
in the WM has the following form:
(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)))
and while running it the following error appears:
Jess reported an error in routine Context.getVariable while executing (nth$ 3 ?res) while executing (bind ?q (nth$ 3 ?res)) while executing defrule MAIN::averageOfObsValue655 while executing (run). Message: No such variable res. Program text: ( run ) at line 137.
回答1:
It seems (and your latest observation confirms it) that accumulate cannot be applied to a CE with a conjunction. The best way is to create temporary facts containing the values over which the average needs to be computed, but care must be taken to create distinct temporary fact.
(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
)
These Value
facts can be easily accumulated:
(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))
来源:https://stackoverflow.com/questions/27665616/complex-conditional-element-in-accumulate-in-jess-rules