Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inference and updating the triple store. #21

Closed
barrynl opened this issue Sep 4, 2017 · 15 comments
Closed

Inference and updating the triple store. #21

barrynl opened this issue Sep 4, 2017 · 15 comments
Labels
bug Developper confirm there is a bug in the product.

Comments

@barrynl
Copy link

barrynl commented Sep 4, 2017

Hi all,

Thanks for your efforts in keeping an up-to-date version of Pellet available!

I'm using Openllet to get a Protege-like inference experience within Apache Jena Fuseki, but I experience some problems after the repository in which inference is enabled is modified. After I remove (SPARQL: DELETE) the triples from which new triples are derived, the derived triples remain in the repository (i.e. they come up in SPARQL queries). I'm not sure yet, whether adding (SPARQL: CONSTRUCT) triples also gives problems.

Does anyone recognize this behaviour? Is this a bug, or is it a feature? For example, are the inferred triples 'converted' to real triples (after which there is no distinction between them)? I would say the ideal situation would be the distinction between stated and derived triples remains and after each modification the inference engine should update the inferred triples (like Sychronize in Protege).

Hope someone can help!

Regards, Barry

@Galigator Galigator added the help wanted Reporter need help to resolve his problem. label Sep 4, 2017
@Galigator
Copy link
Owner

In the reasonning kernel, removing an assertion result in a deprecation of the actual inference, and force a complete re-evaluation.
I'm almost never use the Jena module, but with the owl-api when you remove an axiom and flush the change, the inference are correctly updated.

Maybe there is a bug somewhere in the jena module. Do you have a short sample that demonstrate the problem ?

@ignazio1977
Copy link
Contributor

Another thing to take into account is whether the axiom removed can still be inferred from the remaining axioms. In that case, there is no bug: that's prescribed behaviour.

@barrynl
Copy link
Author

barrynl commented Sep 5, 2017

Hi, thanks for your replies.

@ignazio1977: I'm quite sure the removed axiom cannot be derived from other axioms, but I'll recheck that. Thanks.

I wanted to explain what I was doing exactly and show what went wrong, but unexpectedly the inferred statements are successfully updated in the scenario I'm explaining below. I'll have to check other examples, to see if this issue is fully solved.

You can see the exact configuration and ontology at the end of this post for more details.

I'm using Apache Jena Fuseki's assemblers to create a InfModel with the PelletReasonerFactory attached. Because I'm not using Openllet from Java code, I'm unable to see what is happening under the hood. In this configuration I'm loading the ontology-plus-data.ttl file (with the below content) into the InfModel and this works as expected.

When querying this dataset from Fuseki SPARQL query interface (see Query 1 below), it successfully returns the expected inferred statements of the single individual having the inffered data type property value "12".

Now I execute an update query (see Query 2 below) to remove an axiom and this is successful (note that in Fuseki for updates you need to use the /update URL and not the /query URL), however, the derived axiom (when executing Query 1 again) remains and the inferred statement are removed, which I did not expect.

Query 1

SELECT ?p ?o
{
	<http://ontology.tno.nl/2017/7/untitled-ontology-103/indiv> ?p ?o .
}

Query 2

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
DELETE DATA {
	<http://ontology.tno.nl/2017/7/untitled-ontology-103/indiv> rdf:type <http://ontology.tno.nl/2017/7/untitled-ontology-103/TestClass> .
}

File: config.ttl

# Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0

@prefix : <#> .
@prefix fuseki: <http://jena.apache.org/fuseki#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix tdb: <http://jena.hpl.hp.com/2008/tdb#> .
@prefix ja: <http://jena.hpl.hp.com/2005/11/Assembler#> .

[] rdf:type fuseki:Server ;
	fuseki:services (
	<#service1>
	) .

# Custom code.
[] ja:loadClass "com.hp.hpl.jena.tdb.TDB" .

# TDB
tdb:DatasetTDB rdfs:subClassOf ja:RDFDataset .
tdb:GraphTDB rdfs:subClassOf ja:Model .

## ---------------------------------------------------------------
## Service with only SPARQL query on an inference model.
## Inference model bbase data in TDB.

<#service1> rdf:type fuseki:Service ;
	fuseki:name "pizza" ; # http://host/pizza
	fuseki:serviceQuery "query" ; # SPARQL query service
	fuseki:serviceUpdate "update" ;
	fuseki:serviceUpload "upload" ; # Non-SPARQL upload service
	fuseki:serviceReadWriteGraphStore "data" ; # SPARQL Graph store protocol (read and write)
	# A separate read-only graph store endpoint:
	fuseki:serviceReadGraphStore "get" ; # SPARQL Graph store protocol (read only)
	fuseki:dataset <#dataset> .

<#dataset> rdf:type ja:RDFDataset ;
	ja:defaultGraph <#model_inf> .

<#model_inf> a ja:InfModel ;
	ja:baseModel <#tdbGraph> ;
	ja:content <#test-inf> ;
	ja:reasoner [
#		ja:reasonerURL <http://jena.hpl.hp.com/2003/RDFSExptRuleReasoner>
		ja:reasonerClass "openllet.jena.PelletReasonerFactory"
	] .

<#tdbGraph> rdf:type tdb:GraphTDB ;
	tdb:dataset <#tdbDataset> .

<#tdbDataset> rdf:type tdb:DatasetTDB ;
	tdb:location "DB" ;
	#set the timeout for a SPARQL query in milliseconds. 0 means no timeout and the query never times out.
	ja:context [ ja:cxtName "arq:queryTimeout" ;  ja:cxtValue "0" ] .

<#test-inf> ja:externalContent <file:///opt/ontology-plus-data.ttl> .

File: ontology-plus-data.ttl

@prefix : <http://ontology.tno.nl/2017/7/untitled-ontology-103#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@base <http://ontology.tno.nl/2017/7/untitled-ontology-103> .

<http://ontology.tno.nl/2017/7/untitled-ontology-103> rdf:type owl:Ontology .

<http://ontology.tno.nl/2017/7/untitled-ontology-103/testProperty> rdf:type owl:DatatypeProperty .

<http://ontology.tno.nl/2017/7/untitled-ontology-103/TestClass> rdf:type owl:Class ;
                                                                owl:equivalentClass [ rdf:type owl:Restriction ;
                                                                                      owl:onProperty <http://ontology.tno.nl/2017/7/untitled-ontology-103/testProperty> ;
                                                                                      owl:hasValue "12"
                                                                                    ] .

<http://ontology.tno.nl/2017/7/untitled-ontology-103/indiv> rdf:type owl:NamedIndividual ,
                                                                     <http://ontology.tno.nl/2017/7/untitled-ontology-103/TestClass> .

@barrynl
Copy link
Author

barrynl commented Sep 5, 2017

Hi, I've tested a slightly different scenario to the one described above. I use the following ontology file (I've removed the single individual and will create it with a SPARQL INSERT query):

@prefix : <http://ontology.tno.nl/2017/7/untitled-ontology-103#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@base <http://ontology.tno.nl/2017/7/untitled-ontology-103> .

<http://ontology.tno.nl/2017/7/untitled-ontology-103> rdf:type owl:Ontology .

<http://ontology.tno.nl/2017/7/untitled-ontology-103/testProperty> rdf:type owl:DatatypeProperty .

<http://ontology.tno.nl/2017/7/untitled-ontology-103/TestClass> rdf:type owl:Class ;
                                                                owl:equivalentClass [ rdf:type owl:Restriction ;
                                                                                      owl:onProperty <http://ontology.tno.nl/2017/7/untitled-ontology-103/testProperty> ;
                                                                                      owl:hasValue "12"
                                                                                    ] .

Now, when I insert an individual of type TestClass (see query below), it successfully infers it should have value 12 for DataTypeProperty testProperty:

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

INSERT DATA {
<http://ontology.tno.nl/2017/7/untitled-ontology-103/indiv> rdf:type <http://ontology.tno.nl/2017/7/untitled-ontology-103/TestClass> .
}

You can use the query below to see the inferred statements:

SELECT ?p ?o
{
	<http://ontology.tno.nl/2017/7/untitled-ontology-103/indiv> ?p ?o .
}

This works as expected, however, now I delete the same individual (triple) again (see query below), but some of the inferred statements remain:

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

DELETE DATA {
	<http://ontology.tno.nl/2017/7/untitled-ontology-103/indiv> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://ontology.tno.nl/2017/7/untitled-ontology-103/TestClass> .
}

Now run the query again and you will still see triples about our individual, which I think is not correct. Either the removal of the individual failed (although it said 'success'), but then I would still expect all triples remaining, or something goes wrong with updating and inference.

SELECT ?p ?o
{
	<http://ontology.tno.nl/2017/7/untitled-ontology-103/indiv> ?p ?o .
}

Hope this helps you to reproduce the behaviour!

Regards, Barry

@barrynl
Copy link
Author

barrynl commented Sep 5, 2017

Hi,

I've tested the above scenario from Java code (with openllet-jena as an Maven dependency) and it behaves exactly the same. I've shared the code here. After adding, it correctly infers the additional statements, but after removing the statement, it will not clean up correctly. Although it is now possible to step through the code to find out what goes wrong, I'm too unfamiliar with the openllet source code to understand what's happening. So, it would be helpful if someone with more knowledge tries it as well.

Regards, Barry

@Galigator Galigator added the bug Developper confirm there is a bug in the product. label Sep 5, 2017
@Galigator
Copy link
Owner

Thank for the code, coolest way to grab it.

The strangest thing is the "I sameAs I" statement that appear.
If this statement is remove as well, then the 'almost correct' behaviour appear.

This is strange enough to be classified as bug 👍

@Galigator Galigator removed the help wanted Reporter need help to resolve his problem. label Sep 6, 2017
@barrynl
Copy link
Author

barrynl commented Sep 7, 2017

Hi, thanks for your reply! I'm not sure what you mean with 'the strangest thing is the "I sameAs I" statement....'. Why is that the strangest?

However, what I find weird is that after removing the following statement:

[http://ontology.tno.nl/2017/7/untitled-ontology-103/indiv, http://www.w3.org/1999/02/22-rdf-syntax-ns#type, http://ontology.tno.nl/2017/7/untitled-ontology-103/TestClass]

The exact statement still shows up in the InfModel! Maybe I'm not removing correctly?

Regards, Barry

@Galigator
Copy link
Owner

You are doing things correctly, but there is a bug somewhere.
If you also remove the "I sameAs I" statement then the removal behave correctly.

I have start investigate it a little thuesday night, and clearly this 'sameAs' statement is crapy,it do not add information, so it is very strange that the reasoner produce it.

@barrynl
Copy link
Author

barrynl commented Sep 7, 2017

I would not say the 'I sameAs I' inference is wrong...logically it is true, isn't it? Similar to the inference that every individual has rdf:type owl:Thing, it is true, but it might not be very useful.

@Galigator
Copy link
Owner

Last commit may solve the problem.
It need more tests, maybe the correction force too mush re-computations.
Can I put your code as test for the jena module ?

@barrynl
Copy link
Author

barrynl commented Sep 8, 2017

Yes, you can use my code as Unit Test.

@barrynl
Copy link
Author

barrynl commented Sep 9, 2017

I noticed you included the test, but you did not yet include the '/ontology-plus-data.ttl' resource. Currently the test fails because of this. I would be able to include it, but I have never worked with pull-requests before...

@Galigator
Copy link
Owner

Thx, I forget to add the file.

@barrynl
Copy link
Author

barrynl commented Sep 9, 2017

I've just tested your latest commit in my example explained above and it works fine. I've also tested it in a more complex example (within Apache Jena Fuseki) and it works there as well!

I'll have to do some further tests to see if all problems are fixed now, but it looks good! Thank you.

Can you explain what you changed? Was it only the boolean value about statementsRemoved that you added that fixed it?

Regards, Barry

@Galigator
Copy link
Owner

The main correction is here [https://github.com/Galigator/openllet/blob/integration/module-jena/src/main/java/openllet/jena/PelletGraphListener.java#L343].
The line 349 (The one with the TODO) was only executed on the 'else' branch.

Other changes are only to get the code the way I like.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Developper confirm there is a bug in the product.
Projects
None yet
Development

No branches or pull requests

3 participants