Search code examples
protegejess

JessTab: Finding average value


I am trying to find the average age of the people asserted in the family ontology by the following JessTab rule:

(defrule print_people_total_age 
   (object (https://wiki.csc.calpoly.edu/OntologyTutorial/family_example.owl#age ?a1)) 
   => 
   (bind ?s 0) 
   (bind ?num 0) 
   (foreach ?a (create$ ?a1) (+ ?s ?a) (++ ?num) (printout t "Total age " ?s " and average age is " (/ ?s ?num) " of persons" crlf)))

The rule compiles well, but when activated errors this:

Jess reported an error in routine +
    while executing (+ ?s ?a)
    while executing (foreach ?a (create$ ?a1) (+ ?s ?a) (++ ?num) (printout t "Total age " ?s " and average age is " (/ ?s ?num) " of persons" crlf))
    while executing defrule MAIN::print_people_total_ageSSS
    while executing (run).
  Message: Not a number: "~@http://www.w3.org/2001/XMLSchema#integer 20".

Where am I wrong?


Solution

  • You need to understand the basics of rule execution, most notably that each fact (or set of facts) that matches a rule results in an execution of this rule and all of these executions are independent from each other. To combine data contained in several facts you may use the accumulate CE; in more complex situation an auxiliary fact may be required.

    (defrule sumofages
    ?res <- (accumulate (progn (bind ?s 0)(bind ?n))
                        (progn (bind ?s (+ ?s ?a)) (++ ?n))
                        (create$ ?n ?s)
                        (object (age ?a)))
    =>
    (bind ?s (nth$ 2 ?res))
    (bind ?n (nth$ 1 ?res))
    (printout t "Total age " ?s
                " and average age is " (/ ?s ?n) " of persons" crlf))
    

    You should also make sure to understand the basic workings of the arithmetic functions. (+ ?s ?a)? adds but changes neither operand.