Discussion:
Inference not working
George News
2017-03-10 09:51:41 UTC
Permalink
Hi,

I have the following properties defined in my ontology:

<owl:ObjectProperty rdf:about="http://mydomain.com#by">
<rdfs:domain rdf:resource="http://mydomain.com#data"/>
<owl:inverseOf rdf:resource="http://mydomain.com#made"/>
<rdfs:range rdf:resource="http://mydomain.com#node"/>
</owl:ObjectProperty>

<owl:ObjectProperty rdf:about="http://mydomain.com#made">
<owl:inverseOf rdf:resource="http://mydomain.com#by"/>
<rdfs:domain rdf:resource="http://mydomain.com#node"/>
<rdfs:range rdf:resource="http://mydomain.com#data"/>
</owl:ObjectProperty>

And I have registered multiple entity data and nodes using a JSON-LD document similar to the one below:
{
"@context": {
"my": "http://mydomain.com#"
},

"@graph": [
{
"@id": "_:b81",
"@type": "my:data",
"my:by": {
"@id": "Node1"
},
},
{
"@id": "Node1",
"@type": "my:node",
}
]
}

I'm using:
OntModel ontModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM_MICRO_RULE_INF);

And this is the model I'm injecting to the QueryExecution, etc.

Then I try to run SPARQL sentences on the TDB, but I'm facing issues with the inference. If I run

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX my: <http://mydomain.com#>

SELECT ?d ?n
WHERE {
?n rdf:type/rdfs:subClassOf my:node .
?d my:by ?n .
}

I'm getting results, but if I run

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX my: <http://mydomain.com#>

SELECT ?d ?n
WHERE {
?n rdf:type/rdfs:subClassOf my:node .
?n my:made ?d .
}

I don't get any. The inference model should be infering that made is the inverse of and I should be getting the same results, shouldn't I? Or should I create a InfModel base on the desired reasoner and then inject it to the QueryExecution? From my understanding the first option should be working.

Thanks for your help.
Jorge
George News
2017-03-10 10:03:47 UTC
Permalink
Hi again,

I forgot to mention that the model is retrieved from a TDB. ¿Should I
always create the OntModel from the TDB?

I don't really know how I should do that to work.

Regards
Jorge
Post by George News
Hi,
<owl:ObjectProperty rdf:about="http://mydomain.com#by">
<rdfs:domain rdf:resource="http://mydomain.com#data"/>
<owl:inverseOf rdf:resource="http://mydomain.com#made"/>
<rdfs:range rdf:resource="http://mydomain.com#node"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:about="http://mydomain.com#made">
<owl:inverseOf rdf:resource="http://mydomain.com#by"/>
<rdfs:domain rdf:resource="http://mydomain.com#node"/>
<rdfs:range rdf:resource="http://mydomain.com#data"/>
</owl:ObjectProperty>
{
"my": "http://mydomain.com#"
},
{
"my:by": {
},
},
{
}
]
}
OntModel ontModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM_MICRO_RULE_INF);
And this is the model I'm injecting to the QueryExecution, etc.
Then I try to run SPARQL sentences on the TDB, but I'm facing issues with the inference. If I run
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX my: <http://mydomain.com#>
SELECT ?d ?n
WHERE {
?n rdf:type/rdfs:subClassOf my:node .
?d my:by ?n .
}
I'm getting results, but if I run
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX my: <http://mydomain.com#>
SELECT ?d ?n
WHERE {
?n rdf:type/rdfs:subClassOf my:node .
?n my:made ?d .
}
I don't get any. The inference model should be infering that made is the inverse of and I should be getting the same results, shouldn't I? Or should I create a InfModel base on the desired reasoner and then inject it to the QueryExecution? From my understanding the first option should be working.
Thanks for your help.
Jorge
Dave Reynolds
2017-03-10 11:35:26 UTC
Permalink
Post by George News
Hi again,
I forgot to mention that the model is retrieved from a TDB. ¿Should I
always create the OntModel from the TDB?
I don't really know how I should do that to work.
Your OntModel needs to see both the data and the ontology.

From your code snippets I can't see how either of those are getting
into your OntModel.

If they are all in the same TDB store and accessible as the default
model then you could construct the OntModel over a TDB-backed model.
Though be warned that inference over persistent storage is slow.

That performance issue can sometimes be addressed by caching your data
to an in-memory model and reasoning over that and performing inference
over that and/or by materializing the relevant inferences ahead of time
and persisting them to the TDB store (normally in a separate graph) for
later query.

I'm afraid that Jena doesn't currently have very smooth provision for
inference over large and/or database backed stores.

Dave
Post by George News
Regards
Jorge
Post by George News
Hi,
<owl:ObjectProperty rdf:about="http://mydomain.com#by">
<rdfs:domain rdf:resource="http://mydomain.com#data"/>
<owl:inverseOf rdf:resource="http://mydomain.com#made"/>
<rdfs:range rdf:resource="http://mydomain.com#node"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:about="http://mydomain.com#made">
<owl:inverseOf rdf:resource="http://mydomain.com#by"/>
<rdfs:domain rdf:resource="http://mydomain.com#node"/>
<rdfs:range rdf:resource="http://mydomain.com#data"/>
</owl:ObjectProperty>
{
"my": "http://mydomain.com#"
},
{
"my:by": {
},
},
{
}
]
}
OntModel ontModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM_MICRO_RULE_INF);
And this is the model I'm injecting to the QueryExecution, etc.
Then I try to run SPARQL sentences on the TDB, but I'm facing issues with the inference. If I run
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX my: <http://mydomain.com#>
SELECT ?d ?n
WHERE {
?n rdf:type/rdfs:subClassOf my:node .
?d my:by ?n .
}
I'm getting results, but if I run
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX my: <http://mydomain.com#>
SELECT ?d ?n
WHERE {
?n rdf:type/rdfs:subClassOf my:node .
?n my:made ?d .
}
I don't get any. The inference model should be infering that made is the inverse of and I should be getting the same results, shouldn't I? Or should I create a InfModel base on the desired reasoner and then inject it to the QueryExecution? From my understanding the first option should be working.
Thanks for your help.
Jorge
George News
2017-03-10 15:45:50 UTC
Permalink
Post by Dave Reynolds
Post by George News
Hi again,
I forgot to mention that the model is retrieved from a TDB. ¿Should
I always create the OntModel from the TDB?
I don't really know how I should do that to work.
Your OntModel needs to see both the data and the ontology.
From your code snippets I can't see how either of those are getting
into your OntModel.
Sorry for not pasting the full code. The OntModel is generated using the
spec and adding the normal model with all the data (including ontology
definition)
Post by Dave Reynolds
If they are all in the same TDB store and accessible as the default
model then you could construct the OntModel over a TDB-backed model.
Though be warned that inference over persistent storage is slow.
I've noticed that ;) After playing around a bit I was able to make it
working on a very small TDB. I was going to post my answer but you were
quicker.
Post by Dave Reynolds
That performance issue can sometimes be addressed by caching your
data to an in-memory model and reasoning over that and performing
inference over that and/or by materializing the relevant inferences
ahead of time and persisting them to the TDB store (normally in a
separate graph) for later query.
Could you further explain that? How do I cache in memory? And how do I
perform inference over a bit of data and then persist it?

This sounds pretty interesting. From what I understand, the idea is that
as I'm adding data to the database I should be inferring and storing not
only the original data but also the inferred. Am I right? Any help on
how to do that would be great!

Currently my TDB handles two named graph, that I fill with data
depending on the nature of the incoming. Then I also have another graph
which is the merging of both name graphs. Taking that into
consideration, how can I implement what you suggests? I'm pretty new to
the inference procedures.
Post by Dave Reynolds
I'm afraid that Jena doesn't currently have very smooth provision
for inference over large and/or database backed stores.
That's a pity. Should I try to use Virtuoso or others?
Post by Dave Reynolds
Dave
Post by George News
Regards Jorge
Post by George News
Hi,
<owl:ObjectProperty rdf:about="http://mydomain.com#by">
<rdfs:domain rdf:resource="http://mydomain.com#data"/>
<owl:inverseOf rdf:resource="http://mydomain.com#made"/>
<rdfs:range rdf:resource="http://mydomain.com#node"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:about="http://mydomain.com#made">
<owl:inverseOf rdf:resource="http://mydomain.com#by"/>
<rdfs:domain rdf:resource="http://mydomain.com#node"/>
<rdfs:range rdf:resource="http://mydomain.com#data"/>
</owl:ObjectProperty>
And I have registered multiple entity data and nodes using a
"http://mydomain.com#" },
I'm using: OntModel ontModel =
ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM_MICRO_RULE_INF);
And this is the model I'm injecting to the QueryExecution, etc.
Post by Dave Reynolds
Post by George News
Post by George News
Then I try to run SPARQL sentences on the TDB, but I'm facing
issues with the inference. If I run
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX
<http://mydomain.com#>
SELECT ?d ?n WHERE { ?n rdf:type/rdfs:subClassOf my:node . ?d
my:by ?n . }
I'm getting results, but if I run
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX
<http://mydomain.com#>
SELECT ?d ?n WHERE { ?n rdf:type/rdfs:subClassOf my:node . ?n
my:made ?d . }
I don't get any. The inference model should be infering that made
is the inverse of and I should be getting the same results,
shouldn't I? Or should I create a InfModel base on the desired
reasoner and then inject it to the QueryExecution? From my
understanding the first option should be working.
Thanks for your help. Jorge
Dave Reynolds
2017-03-10 16:05:17 UTC
Permalink
Hi,
Post by George News
Post by Dave Reynolds
Post by George News
Hi again,
I forgot to mention that the model is retrieved from a TDB. ¿Should
I always create the OntModel from the TDB?
I don't really know how I should do that to work.
Your OntModel needs to see both the data and the ontology.
From your code snippets I can't see how either of those are getting
into your OntModel.
Sorry for not pasting the full code. The OntModel is generated using the
spec and adding the normal model with all the data (including ontology
definition)
Post by Dave Reynolds
If they are all in the same TDB store and accessible as the default
model then you could construct the OntModel over a TDB-backed model.
Though be warned that inference over persistent storage is slow.
I've noticed that ;) After playing around a bit I was able to make it
working on a very small TDB. I was going to post my answer but you were
quicker.
Post by Dave Reynolds
That performance issue can sometimes be addressed by caching your
data to an in-memory model and reasoning over that and performing
inference over that and/or by materializing the relevant inferences
ahead of time and persisting them to the TDB store (normally in a
separate graph) for later query.
Could you further explain that? How do I cache in memory?
The simple approach is to create an in-memory model and use Model#add to
copy the entire TDB contents into it. That could be a plain model which
you then use as the base for a separate OntModel or add it to the
OntModel directly.

This is only really useful if your data volume is small, and/or there's
a suitable point in your application where the loading can be done, and
if the data is either static or all changes are funnelled through the
same application so that it can apply updates to both the in-memory and
persistent copies.
Post by George News
And how do I
perform inference over a bit of data and then persist it?
An inference model appears to the API as just another Model so can use
Model.add to copy all the inference-closure of a model back to a
separate TDB-backed Model.

If you only actually need certain entailments then it is sometimes
possible to use selective queries that return the results of those
entailments use the results of those to record the entailments as more
triples in a persistent model. This is highly application dependent.
Post by George News
This sounds pretty interesting. From what I understand, the idea is that
as I'm adding data to the database I should be inferring and storing not
only the original data but also the inferred. Am I right? Any help on
how to do that would be great!
See above. There's no neat process supported for incremental inference -
in general with Jena's rule engines you need a complete copy of the data
(ideally in memory) in order to reason over it.
Post by George News
Currently my TDB handles two named graph, that I fill with data
depending on the nature of the incoming. Then I also have another graph
which is the merging of both name graphs. Taking that into
consideration, how can I implement what you suggests? I'm pretty new to
the inference procedures.
What I'm suggesting isn't really specific to inference.

You would have separate named graphs for your data and for any inference
closure over your data, then use the union-default graph setting for
accessing the data plus inferences. It's not normally necessary to
manage your own union graph unless you need to omit some graphs from the
union. Basically just treat the inference results as more data which you
store like any other data.
Post by George News
Post by Dave Reynolds
I'm afraid that Jena doesn't currently have very smooth provision
for inference over large and/or database backed stores.
That's a pity. Should I try to use Virtuoso or others?
There are certainly commercial triple stores that have better inference
support. I can't comment on specifics.

Dave
A. Soroka
2017-03-10 16:07:56 UTC
Permalink
Post by George News
And how do I
perform inference over a bit of data and then persist it?
An inference model appears to the API as just another Model so can use Model.add to copy all the inference-closure of a model back to a separate TDB-backed Model.
If you only actually need certain entailments then it is sometimes possible to use selective queries that return the results of those entailments use the results of those to record the entailments as more triples in a persistent model. This is highly application dependent.
Just as a side-note here, SPARQL property paths are really useful for this kind of "targeted inference". You can duplicate a lot of subsumption rules and the like with property paths.

---
A. Soroka
The University of Virginia Library
George News
2017-03-10 16:25:13 UTC
Permalink
Post by Dave Reynolds
Hi,
Post by George News
Post by Dave Reynolds
Post by George News
Hi again,
I forgot to mention that the model is retrieved from a TDB. ¿Should
I always create the OntModel from the TDB?
I don't really know how I should do that to work.
Your OntModel needs to see both the data and the ontology.
From your code snippets I can't see how either of those are getting
into your OntModel.
Sorry for not pasting the full code. The OntModel is generated using the
spec and adding the normal model with all the data (including ontology
definition)
Post by Dave Reynolds
If they are all in the same TDB store and accessible as the default
model then you could construct the OntModel over a TDB-backed model.
Though be warned that inference over persistent storage is slow.
I've noticed that ;) After playing around a bit I was able to make it
working on a very small TDB. I was going to post my answer but you were
quicker.
Post by Dave Reynolds
That performance issue can sometimes be addressed by caching your
data to an in-memory model and reasoning over that and performing
inference over that and/or by materializing the relevant inferences
ahead of time and persisting them to the TDB store (normally in a
separate graph) for later query.
Could you further explain that? How do I cache in memory?
The simple approach is to create an in-memory model and use Model#add to
copy the entire TDB contents into it. That could be a plain model which
you then use as the base for a separate OntModel or add it to the
OntModel directly.
This is only really useful if your data volume is small, and/or there's
a suitable point in your application where the loading can be done, and
if the data is either static or all changes are funnelled through the
same application so that it can apply updates to both the in-memory and
persistent copies.
No way, as data is suppose to grow a lot :(
Post by Dave Reynolds
Post by George News
And how do I
perform inference over a bit of data and then persist it?
An inference model appears to the API as just another Model so can use
Model.add to copy all the inference-closure of a model back to a
separate TDB-backed Model.
If you only actually need certain entailments then it is sometimes
possible to use selective queries that return the results of those
entailments use the results of those to record the entailments as more
triples in a persistent model. This is highly application dependent.
So this could be like executing an SPARQL Construct over the original
model retrieving the required data and creating new triples. Then the
inference is "manually done".
Post by Dave Reynolds
Post by George News
This sounds pretty interesting. From what I understand, the idea is that
as I'm adding data to the database I should be inferring and storing not
only the original data but also the inferred. Am I right? Any help on
how to do that would be great!
See above. There's no neat process supported for incremental inference -
in general with Jena's rule engines you need a complete copy of the data
(ideally in memory) in order to reason over it.
In my case, I think I can run the inference over the incoming data prior
to store it. Then it is just over a small model, that then is stored in
the TDB. This extra information I can also store to the TDB.

I will try to make some tests during the next few weeks. Get back to you
with doubts. Do you have an example code for inference or a link to it?
Post by Dave Reynolds
Post by George News
Currently my TDB handles two named graph, that I fill with data
depending on the nature of the incoming. Then I also have another graph
which is the merging of both name graphs. Taking that into
consideration, how can I implement what you suggests? I'm pretty new to
the inference procedures.
What I'm suggesting isn't really specific to inference.
You would have separate named graphs for your data and for any inference
closure over your data, then use the union-default graph setting for
accessing the data plus inferences. It's not normally necessary to
manage your own union graph unless you need to omit some graphs from the
union. Basically just treat the inference results as more data which you
store like any other data.
Post by George News
Post by Dave Reynolds
I'm afraid that Jena doesn't currently have very smooth provision
for inference over large and/or database backed stores.
That's a pity. Should I try to use Virtuoso or others?
There are certainly commercial triple stores that have better inference
support. I can't comment on specifics.
Dave
Continue reading on narkive:
Loading...