You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@jena.apache.org by "Gibson, Michael Scott" <mi...@abdn.ac.uk> on 2013/08/04 16:49:04 UTC

Jena - rule engine agenda

Hi there,


I'm working on a project where I would like to know which rules can and cannot be fired depending if they can be satisfied and to perform further processing on the "cannot fire" rules. I've settled on using Jena because it offers an "all-in-one" solution (OWL reasoning, inference and rule engine), although depending on the complexity of my problem I can look towards other solutions.


My main problem is I've been looking through Jena's RETEEngine implementation and I cannot figure out how it takes the antecedent (left-hand-side) of a rule and attempts to validate it to be put on the agenda. This is especially true on how it chains triples with variables, e.g. (?x rdf:Type someClass) (?x :someProperty ?y) (?y :hasValue True) -> ... and handles built-ins/functors. Essentially, I would like to get a hold of Jena's agenda-making function and put in my own functionality to extract which rule failed the validation and why, i.e. which triple did the rule fail on.


My question is does anybody know how Jena's agenda system works and how I can use it for my own work? If it's too complex, would it be silly of me to make my own? I was thinking of making SPARQL queries based on the antecedent and if it returns any result, the rule can be fired, but somehow I think this will lead to too much overhead (I am aware of SPARQL/SPIN rules, but my problem still remains). Alternatively, I use an existing rule engine (e.g. Jess or Drools) and see their agenda, but lose ontology reasoning and integration to the rule engine. Any help and/or suggestions will be great!


Regards,


Michael Gibson





The University of Aberdeen is a charity registered in Scotland, No SC013683.

RE: Jena - rule engine agenda

Posted by "Gibson, Michael Scott" <mi...@abdn.ac.uk>.
The SPARQL queries were just examples, but you did raise a good point -- why reinvent the wheel? I did manage to write my own builtin which accepted other builtins (with some difficulties; I didn't realise you can't do functor nesting) but it's working a treat now. My builtin can process builtins with their own parameters and depending on the net result of triggering all these builtins, it'll allow the rule to fire or not but still report on the result of each builtin (printing to screen for now,  but this'll change to event firing). This "global builtin" also gets around the lazy evaluation as well (as you stated with your guard idea).

Thanks again for all your help!

Regards
Michael
________________________________________
From: Dave Reynolds <da...@gmail.com>
Sent: 08 August 2013 21:05
To: users@jena.apache.org
Subject: Re: Jena - rule engine agenda

On 07/08/13 19:45, Gibson, Michael Scott wrote:
> Thanks for clarifying the builtins. Actually this'll help out with my rule analysis (explained below). The only reason I ran a SPARQL query outright was just to see how easy it was converting from rule to query. (And I think my time results were a bit hasty...!)
>
> Regarding the SPARQL builtin, I was thinking of having a rule now along the lines of:
> (?x rdf:type MyClass), (?x :somePropertyBoolean ?y), (?x :somePropertyInt ?z), SPARQL(?y, "ASK WHERE {(?y is True)}"), SPARQL(?z, "ASK WHERE {FILTER(?z > 10)}) -> (?x :somePropertyInt 10)
>
> Where SPARQL() is a builtin taking the bound variable as the first parameter and the SPARQL (ask) query as the second parameter.

OK (I assume those examples are just for illustration, those ones could
of course be done directly by the existing builtins).

> My questions now are, assuming the triples match, is rule triggering done by "lazy evaluation"; if the first SPARQL builtin returns false, will the other (subsequent) SPARQL builtins be evaluated?

No. Guard builtins will be evaluated in sequence and if any one fails
the rule fails.

> My other question is do I have to do any processing regarding the variable to "inject" it into the SPARQL query? I'm hoping it'll be something as simple as replacing the query String's variable with the passed variable's literal value. Something like:
>
> Node n = getArgs(0, args, context);
> String q = getArgs(1, args, context);
> q.replace(n.getName(), n.getLiteralValue());

To get the variable name I think you want args[0].getName()

You can't use getArgs because that will get the bound value instead of
the variable.

To substitute the bound value for the variable in the SPARQL query then
there are a couple of options.

You can create a set of query bindings by building a QuerySolutionMap
and then pass that into the QueryExecutionFactory.create call.

However, I see on the dev list some discussion on that which might mean
this changing the future.

There is an alternative of ParameterizedSparqlString which allows you to
do query string rewrites. I've no experience with that, and not sure
when it might be preferable to the QuerySolutionMap option. I think both
will work for your case.

Dave






The University of Aberdeen is a charity registered in Scotland, No SC013683.


Re: Jena - rule engine agenda

Posted by Dave Reynolds <da...@gmail.com>.
On 07/08/13 19:45, Gibson, Michael Scott wrote:
> Thanks for clarifying the builtins. Actually this'll help out with my rule analysis (explained below). The only reason I ran a SPARQL query outright was just to see how easy it was converting from rule to query. (And I think my time results were a bit hasty...!)
>
> Regarding the SPARQL builtin, I was thinking of having a rule now along the lines of:
> (?x rdf:type MyClass), (?x :somePropertyBoolean ?y), (?x :somePropertyInt ?z), SPARQL(?y, "ASK WHERE {(?y is True)}"), SPARQL(?z, "ASK WHERE {FILTER(?z > 10)}) -> (?x :somePropertyInt 10)
>
> Where SPARQL() is a builtin taking the bound variable as the first parameter and the SPARQL (ask) query as the second parameter.

OK (I assume those examples are just for illustration, those ones could 
of course be done directly by the existing builtins).

> My questions now are, assuming the triples match, is rule triggering done by "lazy evaluation"; if the first SPARQL builtin returns false, will the other (subsequent) SPARQL builtins be evaluated?

No. Guard builtins will be evaluated in sequence and if any one fails 
the rule fails.

> My other question is do I have to do any processing regarding the variable to "inject" it into the SPARQL query? I'm hoping it'll be something as simple as replacing the query String's variable with the passed variable's literal value. Something like:
>
> Node n = getArgs(0, args, context);
> String q = getArgs(1, args, context);
> q.replace(n.getName(), n.getLiteralValue());

To get the variable name I think you want args[0].getName()

You can't use getArgs because that will get the bound value instead of 
the variable.

To substitute the bound value for the variable in the SPARQL query then 
there are a couple of options.

You can create a set of query bindings by building a QuerySolutionMap 
and then pass that into the QueryExecutionFactory.create call.

However, I see on the dev list some discussion on that which might mean 
this changing the future.

There is an alternative of ParameterizedSparqlString which allows you to 
do query string rewrites. I've no experience with that, and not sure 
when it might be preferable to the QuerySolutionMap option. I think both 
will work for your case.

Dave


RE: Jena - rule engine agenda

Posted by "Gibson, Michael Scott" <mi...@abdn.ac.uk>.
Thanks for clarifying the builtins. Actually this'll help out with my rule analysis (explained below). The only reason I ran a SPARQL query outright was just to see how easy it was converting from rule to query. (And I think my time results were a bit hasty...!)

Regarding the SPARQL builtin, I was thinking of having a rule now along the lines of:
(?x rdf:type MyClass), (?x :somePropertyBoolean ?y), (?x :somePropertyInt ?z), SPARQL(?y, "ASK WHERE {(?y is True)}"), SPARQL(?z, "ASK WHERE {FILTER(?z > 10)}) -> (?x :somePropertyInt 10)

Where SPARQL() is a builtin taking the bound variable as the first parameter and the SPARQL (ask) query as the second parameter.

My questions now are, assuming the triples match, is rule triggering done by "lazy evaluation"; if the first SPARQL builtin returns false, will the other (subsequent) SPARQL builtins be evaluated? If so, this will help in knowing how the rule has failed (I'm planning to always have the objects necessary to satisfy any rule, but I could do some pre-evaluation of each rule with SPARQL if this plan doesn't go ahead). This leads on to the SPARQL builtin firing an event with which rule, objects and properties failed so I can do further processing once all events have been collected after running the rule engine. My other question is do I have to do any processing regarding the variable to "inject" it into the SPARQL query? I'm hoping it'll be something as simple as replacing the query String's variable with the passed variable's literal value. Something like:

Node n = getArgs(0, args, context);
String q = getArgs(1, args, context);
q.replace(n.getName(), n.getLiteralValue());

Thanks again for your help so far! I did have another peek at Jess OWL 2 RL and figured out how I can have direct access to Jess' Rete engine -- that'll allow me to use Jess rules instead of SWRL if my back is against the wall :).

Regards,

Michael

-----Original Message-----
From: Dave Reynolds [mailto:dave.e.reynolds@gmail.com]
Sent: 07 August 2013 15:29
To: users@jena.apache.org
Subject: Re: Jena - rule engine agenda

On 07/08/13 12:12, Gibson, Michael Scott wrote:
> Thanks for the suggestion. I had a shot of turning a rule's antecedent
> into a SPARQL query

Not sure why you would do that (see below).

> (after some extensive String rewriting) and whilst it worked well, it took longer than I thought even with a small ontology (250ms for around 100 triples; I may be pedantic here, but I have other time-critical methods to worry about).

Such a time suggests either a very complex query or some problem with your code (or an error in the timing, like using clock time and not allowing for java class loading). Most SPARQL queries over a 100 triples don't take anything remotely like that time!

> The only thing I didn't try was putting the SPARQL query into a builtin. I can see how to do that (even though I have to convert the InfGraph from RuleContext to a Model just to run the query), but a problem I can see is how can I get the variables bound in an antecedent's builtin visible in the same rule's consequent (right-hand-side)? Say for example I have the rule [example: sparql("SELECT ?y WHERE {(?x rdf:type MyClass) (?x :someProperty ?y) (?y :hasValue True)}") -> (?y :hasValue False)], would ?y be visible in the consequent and, hence, fire correctly? I'm guessing no, but by the looks of things (and I think I'm answering my own question here!) I can use RuleContext.getEnv().bind() to bind ?y with the node from the query's ResultSet. But just to confirm, the RuleContext object only applies to the just-fired rule; as in if another rule fired it won't use the same RuleContext object?

Yes you will have different RuleContexts for different rule firings.

However ...

I was suggesting you could use a SPARQL builtin as *guard*. A builtin can accept/reject a binding environment or it can bind new variables in a environment but it can't generate a stream of new environments.

What's more if your rule is just a call to a builtin with no other clauses then it will only fire once. It will never be able to tell when changes to the data might mean it should fire again.

By using it as a guard what I meant was that you still have triple patterns in your rule but you then use the bindings of those as inputs to your SPARQL builtin which would then do whatever these complex validation steps are that you are trying to implement and either pass or fail. It would be possible to bind a new variable (using env.bind() as you say) but that only makes sense if there is a single value to bind.

> One last question, how can I go about implementing my own event handler/listener for this? Basically, going back to my problem of seeing if a rule failed, I want to fire an event when the SPARQL query has failed so my own method outside of Jena will be triggered with some information regarding the rule. I see there's a ModelChangedListener, but I don't think that's what I need.

There's nothing in Jena you need to hook in to. Just implement this handler/listener mechanism however you want - observer pattern/message queues/whatever suits the architecture you are trying to create.

However, as I said before this won't let you tell why a rule hasn't fired, it'll only tell you that a rule tried to fire but was rejected by your builtin. That may or may not be enough for you.

> I will admit I had a look at Jess + OWL 2 RL (using SWRLJessTab), but I don't want to give up on this just yet! Jena's non-monotonic rules are exactly what I needed instead of SWRL's monotonic rules...

Like I say, the non-monotonic bits of JenaRules fall in the category of "nasty hack" in my mind so wouldn't put too much faith in them being the right answer for you :)

Dave

> -----Original Message-----
> From: Dave Reynolds [mailto:dave.e.reynolds@gmail.com]
> Sent: 05 August 2013 22:50
> To: users@jena.apache.org
> Subject: Re: Jena - rule engine agenda
>
> On 04/08/13 15:49, Gibson, Michael Scott wrote:
>> Hi there,
>>
>>
>> I'm working on a project where I would like to know which rules can and cannot be fired depending if they can be satisfied and to perform further processing on the "cannot fire" rules. I've settled on using Jena because it offers an "all-in-one" solution (OWL reasoning, inference and rule engine), although depending on the complexity of my problem I can look towards other solutions.
>>
>>
>> My main problem is I've been looking through Jena's RETEEngine implementation and I cannot figure out how it takes the antecedent (left-hand-side) of a rule and attempts to validate it to be put on the agenda. This is especially true on how it chains triples with variables, e.g. (?x rdf:Type someClass) (?x :someProperty ?y) (?y :hasValue True) -> ... and handles built-ins/functors. Essentially, I would like to get a hold of Jena's agenda-making function and put in my own functionality to extract which rule failed the validation and why, i.e. which triple did the rule fail on.
>
> The Jena rule implementation is a somewhat simplified RETE. It is just designed to do forward closure and doesn't have the full rule prioritization/refraction type stuff that a modern forward engine would have. So the conflict set implementation, such as is it is, is not particularly flexible and is not designed to be intercepted and extended.
>
> If you want to look at it is in:
> com.hp.hpl.jena.reasoner.rulesys.impl.RETEConflictSet
>
> In any case in a RETE engine the rules aren't "validated" in quite the way you describe. It is not that a rule fails validation it is that the tokens don't fall out of the network so a rule which doesn't yet match is simply not submitted to the conflict set. If you need to know why a rule has *not* fired then you'll need to use a different rule engine.
>
>> My question is does anybody know how Jena's agenda system works and how I can use it for my own work? If it's too complex, would it be silly of me to make my own? I was thinking of making SPARQL queries based on the antecedent and if it returns any result, the rule can be fired, but somehow I think this will lead to too much overhead (I am aware of SPARQL/SPIN rules, but my problem still remains).
>
> If that's all you want to do then this might be accomplished with a builtin. Create a builtin which runs the SPARQL query you want.
> Antecedent builtins are checked when the triple patterns all match (via the network) but before it is added to the conflict set. So a builtin can act as a guard to only let the rule fire if some condition is true.
>
> Beware that the engine won't know anything about your SPARQL queries so it won't be able to reshedule the rule if something changes that would change the results of a query. At the minimum mark your builtin as non-monotonic.
>
>> Alternatively, I use an existing rule engine (e.g. Jess or Drools) and see their agenda, but lose ontology reasoning and integration to the rule engine. Any help and/or suggestions will be great!
>
> If you just want to add some more complex guards and can separate those guards from the rule matching itself you may be able to get away with constructing your own builtins as above.
>
> If you really need deeper access to the rule engine internals then my advice would be to go with something like Jess or Drools.
>
> Dave
>
>
>
>
>
>
> The University of Aberdeen is a charity registered in Scotland, No SC013683.
>






The University of Aberdeen is a charity registered in Scotland, No SC013683.


Re: Jena - rule engine agenda

Posted by Dave Reynolds <da...@gmail.com>.
On 07/08/13 12:12, Gibson, Michael Scott wrote:
> Thanks for the suggestion. I had a shot of turning a rule's antecedent into a SPARQL query

Not sure why you would do that (see below).

> (after some extensive String rewriting) and whilst it worked well, it took longer than I thought even with a small ontology (250ms for around 100 triples; I may be pedantic here, but I have other time-critical methods to worry about).

Such a time suggests either a very complex query or some problem with 
your code (or an error in the timing, like using clock time and not 
allowing for java class loading). Most SPARQL queries over a 100 triples 
don't take anything remotely like that time!

> The only thing I didn't try was putting the SPARQL query into a builtin. I can see how to do that (even though I have to convert the InfGraph from RuleContext to a Model just to run the query), but a problem I can see is how can I get the variables bound in an antecedent's builtin visible in the same rule's consequent (right-hand-side)? Say for example I have the rule [example: sparql("SELECT ?y WHERE {(?x rdf:type MyClass) (?x :someProperty ?y) (?y :hasValue True)}") -> (?y :hasValue False)], would ?y be visible in the consequent and, hence, fire correctly? I'm guessing no, but by the looks of things (and I think I'm answering my own question here!) I can use RuleContext.getEnv().bind() to bind ?y with the node from the query's ResultSet. But just to confirm, the RuleContext object only applies to the just-fired rule; as in if another rule fired it won't use the same RuleContext object?

Yes you will have different RuleContexts for different rule firings.

However ...

I was suggesting you could use a SPARQL builtin as *guard*. A builtin 
can accept/reject a binding environment or it can bind new variables in 
a environment but it can't generate a stream of new environments.

What's more if your rule is just a call to a builtin with no other 
clauses then it will only fire once. It will never be able to tell when 
changes to the data might mean it should fire again.

By using it as a guard what I meant was that you still have triple 
patterns in your rule but you then use the bindings of those as inputs 
to your SPARQL builtin which would then do whatever these complex 
validation steps are that you are trying to implement and either pass or 
fail. It would be possible to bind a new variable (using env.bind() as 
you say) but that only makes sense if there is a single value to bind.

> One last question, how can I go about implementing my own event handler/listener for this? Basically, going back to my problem of seeing if a rule failed, I want to fire an event when the SPARQL query has failed so my own method outside of Jena will be triggered with some information regarding the rule. I see there's a ModelChangedListener, but I don't think that's what I need.

There's nothing in Jena you need to hook in to. Just implement this 
handler/listener mechanism however you want - observer pattern/message 
queues/whatever suits the architecture you are trying to create.

However, as I said before this won't let you tell why a rule hasn't 
fired, it'll only tell you that a rule tried to fire but was rejected by 
your builtin. That may or may not be enough for you.

> I will admit I had a look at Jess + OWL 2 RL (using SWRLJessTab), but I don't want to give up on this just yet! Jena's non-monotonic rules are exactly what I needed instead of SWRL's monotonic rules...

Like I say, the non-monotonic bits of JenaRules fall in the category of 
"nasty hack" in my mind so wouldn't put too much faith in them being the 
right answer for you :)

Dave

> -----Original Message-----
> From: Dave Reynolds [mailto:dave.e.reynolds@gmail.com]
> Sent: 05 August 2013 22:50
> To: users@jena.apache.org
> Subject: Re: Jena - rule engine agenda
>
> On 04/08/13 15:49, Gibson, Michael Scott wrote:
>> Hi there,
>>
>>
>> I'm working on a project where I would like to know which rules can and cannot be fired depending if they can be satisfied and to perform further processing on the "cannot fire" rules. I've settled on using Jena because it offers an "all-in-one" solution (OWL reasoning, inference and rule engine), although depending on the complexity of my problem I can look towards other solutions.
>>
>>
>> My main problem is I've been looking through Jena's RETEEngine implementation and I cannot figure out how it takes the antecedent (left-hand-side) of a rule and attempts to validate it to be put on the agenda. This is especially true on how it chains triples with variables, e.g. (?x rdf:Type someClass) (?x :someProperty ?y) (?y :hasValue True) -> ... and handles built-ins/functors. Essentially, I would like to get a hold of Jena's agenda-making function and put in my own functionality to extract which rule failed the validation and why, i.e. which triple did the rule fail on.
>
> The Jena rule implementation is a somewhat simplified RETE. It is just designed to do forward closure and doesn't have the full rule prioritization/refraction type stuff that a modern forward engine would have. So the conflict set implementation, such as is it is, is not particularly flexible and is not designed to be intercepted and extended.
>
> If you want to look at it is in:
> com.hp.hpl.jena.reasoner.rulesys.impl.RETEConflictSet
>
> In any case in a RETE engine the rules aren't "validated" in quite the way you describe. It is not that a rule fails validation it is that the tokens don't fall out of the network so a rule which doesn't yet match is simply not submitted to the conflict set. If you need to know why a rule has *not* fired then you'll need to use a different rule engine.
>
>> My question is does anybody know how Jena's agenda system works and how I can use it for my own work? If it's too complex, would it be silly of me to make my own? I was thinking of making SPARQL queries based on the antecedent and if it returns any result, the rule can be fired, but somehow I think this will lead to too much overhead (I am aware of SPARQL/SPIN rules, but my problem still remains).
>
> If that's all you want to do then this might be accomplished with a builtin. Create a builtin which runs the SPARQL query you want.
> Antecedent builtins are checked when the triple patterns all match (via the network) but before it is added to the conflict set. So a builtin can act as a guard to only let the rule fire if some condition is true.
>
> Beware that the engine won't know anything about your SPARQL queries so it won't be able to reshedule the rule if something changes that would change the results of a query. At the minimum mark your builtin as non-monotonic.
>
>> Alternatively, I use an existing rule engine (e.g. Jess or Drools) and see their agenda, but lose ontology reasoning and integration to the rule engine. Any help and/or suggestions will be great!
>
> If you just want to add some more complex guards and can separate those guards from the rule matching itself you may be able to get away with constructing your own builtins as above.
>
> If you really need deeper access to the rule engine internals then my advice would be to go with something like Jess or Drools.
>
> Dave
>
>
>
>
>
>
> The University of Aberdeen is a charity registered in Scotland, No SC013683.
>


RE: Jena - rule engine agenda

Posted by "Gibson, Michael Scott" <mi...@abdn.ac.uk>.
Thanks for the suggestion. I had a shot of turning a rule's antecedent into a SPARQL query (after some extensive String rewriting) and whilst it worked well, it took longer than I thought even with a small ontology (250ms for around 100 triples; I may be pedantic here, but I have other time-critical methods to worry about).

The only thing I didn't try was putting the SPARQL query into a builtin. I can see how to do that (even though I have to convert the InfGraph from RuleContext to a Model just to run the query), but a problem I can see is how can I get the variables bound in an antecedent's builtin visible in the same rule's consequent (right-hand-side)? Say for example I have the rule [example: sparql("SELECT ?y WHERE {(?x rdf:type MyClass) (?x :someProperty ?y) (?y :hasValue True)}") -> (?y :hasValue False)], would ?y be visible in the consequent and, hence, fire correctly? I'm guessing no, but by the looks of things (and I think I'm answering my own question here!) I can use RuleContext.getEnv().bind() to bind ?y with the node from the query's ResultSet. But just to confirm, the RuleContext object only applies to the just-fired rule; as in if another rule fired it won't use the same RuleContext object?

One last question, how can I go about implementing my own event handler/listener for this? Basically, going back to my problem of seeing if a rule failed, I want to fire an event when the SPARQL query has failed so my own method outside of Jena will be triggered with some information regarding the rule. I see there's a ModelChangedListener, but I don't think that's what I need.

I will admit I had a look at Jess + OWL 2 RL (using SWRLJessTab), but I don't want to give up on this just yet! Jena's non-monotonic rules are exactly what I needed instead of SWRL's monotonic rules...

Regards,

Michael

-----Original Message-----
From: Dave Reynolds [mailto:dave.e.reynolds@gmail.com]
Sent: 05 August 2013 22:50
To: users@jena.apache.org
Subject: Re: Jena - rule engine agenda

On 04/08/13 15:49, Gibson, Michael Scott wrote:
> Hi there,
>
>
> I'm working on a project where I would like to know which rules can and cannot be fired depending if they can be satisfied and to perform further processing on the "cannot fire" rules. I've settled on using Jena because it offers an "all-in-one" solution (OWL reasoning, inference and rule engine), although depending on the complexity of my problem I can look towards other solutions.
>
>
> My main problem is I've been looking through Jena's RETEEngine implementation and I cannot figure out how it takes the antecedent (left-hand-side) of a rule and attempts to validate it to be put on the agenda. This is especially true on how it chains triples with variables, e.g. (?x rdf:Type someClass) (?x :someProperty ?y) (?y :hasValue True) -> ... and handles built-ins/functors. Essentially, I would like to get a hold of Jena's agenda-making function and put in my own functionality to extract which rule failed the validation and why, i.e. which triple did the rule fail on.

The Jena rule implementation is a somewhat simplified RETE. It is just designed to do forward closure and doesn't have the full rule prioritization/refraction type stuff that a modern forward engine would have. So the conflict set implementation, such as is it is, is not particularly flexible and is not designed to be intercepted and extended.

If you want to look at it is in:
com.hp.hpl.jena.reasoner.rulesys.impl.RETEConflictSet

In any case in a RETE engine the rules aren't "validated" in quite the way you describe. It is not that a rule fails validation it is that the tokens don't fall out of the network so a rule which doesn't yet match is simply not submitted to the conflict set. If you need to know why a rule has *not* fired then you'll need to use a different rule engine.

> My question is does anybody know how Jena's agenda system works and how I can use it for my own work? If it's too complex, would it be silly of me to make my own? I was thinking of making SPARQL queries based on the antecedent and if it returns any result, the rule can be fired, but somehow I think this will lead to too much overhead (I am aware of SPARQL/SPIN rules, but my problem still remains).

If that's all you want to do then this might be accomplished with a builtin. Create a builtin which runs the SPARQL query you want.
Antecedent builtins are checked when the triple patterns all match (via the network) but before it is added to the conflict set. So a builtin can act as a guard to only let the rule fire if some condition is true.

Beware that the engine won't know anything about your SPARQL queries so it won't be able to reshedule the rule if something changes that would change the results of a query. At the minimum mark your builtin as non-monotonic.

> Alternatively, I use an existing rule engine (e.g. Jess or Drools) and see their agenda, but lose ontology reasoning and integration to the rule engine. Any help and/or suggestions will be great!

If you just want to add some more complex guards and can separate those guards from the rule matching itself you may be able to get away with constructing your own builtins as above.

If you really need deeper access to the rule engine internals then my advice would be to go with something like Jess or Drools.

Dave






The University of Aberdeen is a charity registered in Scotland, No SC013683.


Re: Jena - rule engine agenda

Posted by Dave Reynolds <da...@gmail.com>.
On 04/08/13 15:49, Gibson, Michael Scott wrote:
> Hi there,
>
>
> I'm working on a project where I would like to know which rules can and cannot be fired depending if they can be satisfied and to perform further processing on the "cannot fire" rules. I've settled on using Jena because it offers an "all-in-one" solution (OWL reasoning, inference and rule engine), although depending on the complexity of my problem I can look towards other solutions.
>
>
> My main problem is I've been looking through Jena's RETEEngine implementation and I cannot figure out how it takes the antecedent (left-hand-side) of a rule and attempts to validate it to be put on the agenda. This is especially true on how it chains triples with variables, e.g. (?x rdf:Type someClass) (?x :someProperty ?y) (?y :hasValue True) -> ... and handles built-ins/functors. Essentially, I would like to get a hold of Jena's agenda-making function and put in my own functionality to extract which rule failed the validation and why, i.e. which triple did the rule fail on.

The Jena rule implementation is a somewhat simplified RETE. It is just 
designed to do forward closure and doesn't have the full rule 
prioritization/refraction type stuff that a modern forward engine would 
have. So the conflict set implementation, such as is it is, is not 
particularly flexible and is not designed to be intercepted and extended.

If you want to look at it is in: 
com.hp.hpl.jena.reasoner.rulesys.impl.RETEConflictSet

In any case in a RETE engine the rules aren't "validated" in quite the 
way you describe. It is not that a rule fails validation it is that the 
tokens don't fall out of the network so a rule which doesn't yet match 
is simply not submitted to the conflict set. If you need to know why a 
rule has *not* fired then you'll need to use a different rule engine.

> My question is does anybody know how Jena's agenda system works and how I can use it for my own work? If it's too complex, would it be silly of me to make my own? I was thinking of making SPARQL queries based on the antecedent and if it returns any result, the rule can be fired, but somehow I think this will lead to too much overhead (I am aware of SPARQL/SPIN rules, but my problem still remains).

If that's all you want to do then this might be accomplished with a 
builtin. Create a builtin which runs the SPARQL query you want. 
Antecedent builtins are checked when the triple patterns all match (via 
the network) but before it is added to the conflict set. So a builtin 
can act as a guard to only let the rule fire if some condition is true.

Beware that the engine won't know anything about your SPARQL queries so 
it won't be able to reshedule the rule if something changes that would 
change the results of a query. At the minimum mark your builtin as 
non-monotonic.

> Alternatively, I use an existing rule engine (e.g. Jess or Drools) and see their agenda, but lose ontology reasoning and integration to the rule engine. Any help and/or suggestions will be great!

If you just want to add some more complex guards and can separate those 
guards from the rule matching itself you may be able to get away with 
constructing your own builtins as above.

If you really need deeper access to the rule engine internals then my 
advice would be to go with something like Jess or Drools.

Dave