On 09/12/15 23:12, Chris Snyder wrote:
I was finally able to get my rule to work. I’m not sure this is the best way to
do it though as it seems very clunky.
It appears that the reasoner is applied only at the time of the ontModel
creation. Since i was updating the reasoner rules after the ontModel was
created the model and its inferred axioms were not regenerated. I tried just a
plain rebind on the ontModel but that did not work either.
The rules are not run at OntModel creation. Forward rule are run when
you first ask for any result or via an explicit prepare(). Backward
rules are run in response to each query.
Dyanamically changing the forward rules associated with an InfModel is
not supported (which I think is what you mean here). If you have a new
ruleset then create a new InfModel (or OntModel with inference).
What I finally did was:
1) rebind the reasoner that is associated to the current ontModel (which
already had its rules updated) with the base model of the ontModel
2) create an InfModel using the updated reasoner and the base model
3) rebind the current ontModel to reset it (not sure why this did not use the
update reasoner rules)
4) add the deduced triples from the infModel into the ontModel
This seems roundabout but I can't figure out what you are trying to achieve.
Assuming you have some base model, and then receive a new rule set,
simply create a reasoner from that rule set, create an InfModel (or
OntModel with inference) over the base model and consult that.
I’m haven’t looked into why the ontModel.rebind() doesn’t seem to redo the
reasoning but at least I have something to demo now.
Curiously, the rule update works with the RDFSReasoner and the
GenericRuleReasoner but not the OWLFBRULE reasoner. I’m not sure why that is
the case either although I expect that my rule is not valid for some option set
with the OWLFBRule reasoner.
Here is the relevant bit of code. If someone has a better way of doing this
please let me know.
ruleReasoner.setRules(existingRules);
This is OK but (as it says in the javadoc) this does not side effect any
inference models that were already using the reasoner.
ruleReasoner.bind(getRepository().getOntModel().getBaseModel().getGraph());
This is not doing what you think. GenericRuleReasoner.bind takes a base
model and returns a new InfModel which applies the reasoner to the base
triples. It does not side effect either the reasoner or the base model.
Since you are doing nothing with the result of the bind this is
essentially a no op.
InfModel inf =
ModelFactory.createInfModel(ruleReasoner,
getRepository().getOntModel().getBaseModel());
This is fine but if want a work with OntModels then why not create a new
OntModel at this stage?
getRepository().getOntModel().rebind();
Not sure why this step. If the OntModel has a reasoner attached then
this will cause it to notice any under-the-covers data changes. However,
you haven't changed the data and, as already mentioned, your changes to
the rule reasoner apply to new Inf/OntModels not this one.
getRepository().getOntModel().add(inf.getDeductionsModel());
This will only see the forward deductions, which would be fine for your
earlier example.
Seems to me the easier sequence is something like:
OntModel oldModel = getRepository().getOntModel();
OntModelSpec os = new OntModelSpec(ontModelSpec);
os.setReasoner( new GenericRuleReasoner(rules) );
OntModel newModel = ModelFactory.createOntologyModel(os,
oldModel.getBaseModel());
getRepository().putOntModel(newModel);
Dave