You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@jena.apache.org by George News <ge...@gmx.net> on 2017/03/10 09:51:41 UTC
Inference not working
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
Re: Inference not working
Posted by "A. Soroka" <aj...@virginia.edu>.
> On Mar 10, 2017, at 11:05 AM, Dave Reynolds <da...@gmail.com> wrote:
>
>> 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
Re: Inference not working
Posted by George News <ge...@gmx.net>.
On 10/03/2017 17:05, Dave Reynolds wrote:
> Hi,
>
> On 10/03/17 15:45, George News wrote:
>> On 10/03/2017 12:35, Dave Reynolds wrote:
>>>
>>> On 10/03/17 10:03, George News wrote:
>>>> 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)
>>
>>> 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.
>>
>>> 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 :(
>> 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".
>> 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?
>> 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.
>
>>> 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
>
>
Re: Inference not working
Posted by Dave Reynolds <da...@gmail.com>.
Hi,
On 10/03/17 15:45, George News wrote:
> On 10/03/2017 12:35, Dave Reynolds wrote:
>>
>> On 10/03/17 10:03, George News wrote:
>>> 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)
>
>> 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.
>
>> 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.
> 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.
> 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.
> 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.
>> 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
Re: Inference not working
Posted by George News <ge...@gmx.net>.
On 10/03/2017 12:35, Dave Reynolds wrote:
>
> On 10/03/17 10:03, George News wrote:
>> 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)
> 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.
> 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.
> 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?
> Dave
>
>>
>> Regards Jorge
>>
>> On 10/03/2017 10:51, George News wrote:
>>> 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
>>>
>
Re: Inference not working
Posted by Dave Reynolds <da...@gmail.com>.
On 10/03/17 10:03, George News wrote:
> 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
>
> Regards
> Jorge
>
> On 10/03/2017 10:51, George News wrote:
>> 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
>>
Re: Inference not working
Posted by George News <ge...@gmx.net>.
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
On 10/03/2017 10:51, George News wrote:
> 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
>