Assuming that you have another deftemplate representing papers:
(deftemplate paper (slot author ) (slot number))
you could do away with the query and test CE and write a truly declarative
rule2:
(defrule rule2
(paper (number ?number))
?c <- (accumulate (bind ?list (new java.util.ArrayList)) ;; initializer
(?list add ?reviewer) ;; action
(?list size) ;; result
(review (reviewer ?reviewer)
(paper ?number))) ;; CE
=>
(printout t ?c " reviews for paper " ?number crlf))
With initial facts and additions:
(deffacts MAIN::myfacts
(paper (author Joe)(number 1))
(review (reviewer "1") (paper 1))
(review (reviewer "2") (paper 1))
(review (reviewer "3") (paper 1))
(paper (author Jack)(number 2))
(review (reviewer "1") (paper 2))
(review (reviewer "2") (paper 2))
(reset)
(run)
(assert (review (reviewer "6") (paper 1)))
(assert (paper (author Jack)(number 3)))
(assert (review (reviewer "6") (paper 2)))
(assert (review (reviewer "6") (paper 3)))
(printout t "second run" crlf)
(run)
you'll get this output:
2 reviews for paper 2
3 reviews for paper 1
second run
1 reviews for paper 3
3 reviews for paper 2
4 reviews for paper 1
3
Jess>
-W
On Wed, Jul 29, 2009 at 2:59 PM, <[email protected]> wrote:
> Hi all,
>
> Playing around a bit with the test function on the LHS of a rule I
> encountered some behavior that puzzles me.
>
> I implemented the following application in which I store facts about
> reviews for papers:
>
> (deftemplate review (slot reviewer) (slot paper))
>
> (deffacts MAIN::myfacts
> (review (reviewer "1") (paper 1))
> (review (reviewer "2") (paper 1))
> (review (reviewer "3") (paper 1))
> )
>
> I have two rules and one query. The first rule fires for each review.
>
> (defrule rule1
> (review (reviewer ?r))
> =>
> (printout t "rule1 fired for reviewer " ?r crlf)
> )
>
> The query evaluates to all reviews per paper and is used in the second
> rule that should fire when more than 3 reviews are received for paper 1.
>
> (defquery qry-reviews-for-paper
> (declare (variables ?paper))
> (review (reviewer ?reviewer) (paper ?paper))
> )
>
> (defrule rule2
> (test (> (count-query-results qry-reviews-for-paper 1) 3))
> =>
> (printout t "rule2 fired" crlf)
> )
>
> If I run the following code after this specification:
>
> (run)
> (assert (review (reviewer "6") (paper 0)))
> (printout t "second run" crlf)
> (run)
>
> it outputs:
>
> rule1 fired for reviewer 3
> rule1 fired for reviewer 2
> rule1 fired for reviewer 1
> second run
> rule1 fired for reviewer 6
>
> I expected the second rule to have fired also, but it didn't. Is it
> because the initial-fact is added to the LHS preceding the test and the
> rule will only be evaluated once (similar to a rule with an empty LHS)?
> This was not clear to me after having read section 6.12 of the manual,
> though.
>
> It should also be noted that even if I start with more than three reviews
> for paper 1, the second rule only fires if I put the reset command just
> before the definition of the rule. I believe the explanation of this
> behavior can be found here:
> (http://www.mail-archive.com/[email protected]/msg03592.html).
>
> - Nick.
>
>
> --------------------------------------------------------------------
> To unsubscribe, send the words 'unsubscribe jess-users [email protected]'
> in the BODY of a message to [email protected], NOT to the list
> (use your own address!) List problems? Notify [email protected].
> --------------------------------------------------------------------
>
>