On 01/08/12 01:23, Alejandro Rodríguez González wrote:
Hi Dave,
Why?
The correct, standard way to do disjunctions in rule systems is to have
multiple rules. Stick with that approach.
Yep, I understand, but the problem is that the number of rules will get
quite high with this approach depending on the configuration of the disease
modeled.
Sure but rules done that way will run faster and are easier to write and
easier to maintain than with a non-monotonic counting approach.
If you really want to simplify management then you could create a rule
syntax of your own that includes disjunction and translate that syntax
into Jena rules.
I would keep away from implementing counting within JenaRules unless you
really really need it. Even then consider writing custom builtins to do
the counting.
The only rule that that initializes the counter is:
rule_dX_NOT_REST_SIGNS
which (a) only fires if there is a finding other than sA to sE and (b)
asserts your ont:dX_NOT_SIGNS flag.
So the only situation in which there is a zero counter to get the counting
started is one where you have some other finding and even then those
counting rules will never fire because they are guarded by:
noValue(?i, ont:hasNegSign ont:dX_NOT_SIGNS)
If they did fire than be aware that the counting rules you have do not
remove the older counts (the painful bit of counting in JenaRules) so
you'll end up with all the count values not a single total value.
I saw.. I've been working on this, and I've modified the rules. From my POV
are correct, but probably I'm missing something since the new approach is
not working:
http://pastebin.com/EGB2s2YK
I've created a rule to init the counter when a sign is received and the
counter doesn't have any value (I'm using value 4 as an example, but I have
also tried with noValue builtin), but it doesn't work.
That rule is:
[rule_dX_INIT_COUNTER:
(?i ont:hasFinding ?x) (?i ont:counter ?c) notEqual(?c,4) -> (?i
ont:counter 0) ]
That rule will never fire because if there is no counter then the second
triple pattern doesn't match.
For initialization you want something like:
[rule_dX_INIT_COUNTER:
(?i ont:hasFinding ?x) noValue(?i ont:counter) -> (?i ont:counter 0) ]
However, resetting a counter is much more of a problem. Setting
ont:counter to a particular value doesn't remove other statements about
other values. So to do counting you have to remove() the statement about
the current count value and then add a new one. However, the remove
sends a triple-removed signal to other counting rules which try to
"unfire" [*]. So to guard against that you have to track which things
you have already counted through setting marker flags with hidden
predicates and using noValue on those flags.
To repeat: keep away from implementing counting within JenaRules unless
you really really need it.
Dave
[*] The behaviour of JenaRules when a remove() is triggered I would
regard as a bug these days. It should either evolve into a proper
production rule system system with more explicit refraction, or should
revert to its original design goal of just doing monotonic deductions