You have to load both the ontology and your test file into the same dataset graph.
Cheers, On Mon, 2023-02-20 at 17:12 +0100, Yang-Min KIM wrote: > @Steve > >So this will let me issue SPARQL queries against a reasoner that > pulls from a TDB store? > Yes, that's what I'd like to do: the reasoner is built from a TDB > dataset and it will be applied on other TDB datasets, then my SPARQL > queries will be run. I've never used BGP but as you say, I may have > to > change my SPARQL request > > @Simon > Thanks, I think we are close to solving the problem! > I have configuration files as below: > - Fuseki server configuration (one unique config file): > - /opt/tomcat/fuseki/base/config.ttl > - Dataset configuration (one file by a TDB dataset): > - > /opt/tomcat/fuseki/base/configuration/test_ontology_pizza.ttl > - > /opt/tomcat/fuseki/base/configuration/test_pizza.ttl > > With: > - `test_ontology_pizza.ttl` stores ontology data where the > reasoner > will be based > - `test_pizza.ttl` contains a small sample data where the > reasoner and > SPARQL query will be applied > > Your code seems to be rather suitable for the Dataset configuration > than Fuseki server configuration. I tried to apply your code in both > cases (Fuseki server and Dataset) but it did not work. Can you > specify > whether to configure at the Fuseki service level or per TDB Dataset? > > I've also tried with `ja:externalContent` (with a ontology file > manually saved in `/opt/tomcat/fuseki/pizza_ontology.rdf`) as bellow > but still no result. > > -------------------------------------------------------- > > @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 ja: <<http://jena.hpl.hp.com/2005/11/Assembler#>> . > @prefix tdb2: <<http://jena.apache.org/2016/tdb#>> . > > [] rdf:type fuseki:Server ; > fuseki:services ( > <#pizzaService> > ) . > > <#pizzaService> rdf:type fuseki:Service ; > # URI of the dataset -- <http://host:port/pizza> > fuseki:name "pizza" ; > fuseki:serviceQuery "sparql" ; > fuseki:serviceQuery "query" ; > fuseki:serviceUpdate "update" ; > fuseki:serviceUpload "upload" ; > fuseki:serviceReadWriteGraphStore "data" ; > fuseki:serviceReadGraphStore "get" ; > fuseki:dataset <#dataset> . > > <#dataset> rdf:type ja:RDFDataset ; > ja:defaultGraph <#model> . > > <#model> rdf:type ja:InfModel ; > ja:baseModel <#tdbGraph> ; > ja:content <#pizza> ; > ja:reasoner [ > ja:reasonerURL > <<http://jena.hpl.hp.com/2003/OWLFBRuleReasoner>>] > . > > <#tdbGraph> rdf:type tdb2:GraphTDB ; > tdb2:dataset <#tdbDataset> . > > <#tdbDataset> rdf:type tdb2:DatasetTDB ; > # tdb2:location "Pizza_test" . > tdb2:location > "/opt/tomcat/fuseki/base/databases/test_ontology_pizza" > . > > # Ontologies > <#pizza> ja:externalContent > <<file:///opt/tomcat/fuseki/pizza_ontology.rdf>> . > > Le jeu., févr. 16 2023 at 14:57:39 -0600, Steve Vestal > <steve.ves...@galois.com> a écrit : > > So this will let me issue SPARQL queries against a reasoner that > > pulls from a TDB store? But is it using a Graph interface to the > > store? I thought fetching things through a StageGenerator > > interface > > was needed to make full use of an indexed store , e.g., use BGPs > > rather than single triple queries? > > > > On 2/16/2023 1:37 PM, Simon Bin wrote: > > > You are only missing 2 steps on you fuseki config, then it can > > > work: > > > > > > 1) you need to use OWL reasoner, not an empty rule reasoner > > > > > > 2) you need to define a SPARQL service for your dataset > > > > > > here is the required changes in "git diff" format: > > > > > > diff --git a/data/config.ttl b/data/config.ttl > > > index 69c9cba..4b77ce7 100644 > > > --- a/data/config.ttl > > > +++ b/data/config.ttl > > > @@ -28,6 +28,16 @@ > > > ## --------------------------- Added > > > ------------------------------------ > > > +:service rdf:type fuseki:Service ; > > > + rdfs:label "Pizza Ontology Reasoning" ; > > > + fuseki:name "pizza" ; > > > + fuseki:dataset :dataset ; > > > + > > > + fuseki:endpoint [ fuseki:operation fuseki:query ] ; > > > + fuseki:endpoint [ fuseki:operation fuseki:update ] ; > > > + fuseki:endpoint [ fuseki:operation fuseki:gsp-rw ] ; > > > + . > > > + > > > # Dataset with only the default graph. > > > :dataset rdf:type ja:RDFDataset ; > > > ja:defaultGraph :model_inf ; > > > @@ -37,7 +47,7 @@ > > > :model_inf a ja:InfModel ; > > > ja:baseModel :tdbGraph ; > > > ja:reasoner [ > > > - ja:reasonerURL > > > <<http://jena.hpl.hp.com/2003/GenericRuleReasoner>> > > > + ja:reasonerURL > > > <<http://jena.hpl.hp.com/2003/OWLFBRuleReasoner>> > > > ] . > > > :tdbGraph rdf:type tdb2:GraphTDB2 ; > > > > > > > > > On Thu, 2023-02-16 at 19:35 +0100, Yang-Min KIM wrote: > > > > Dear Jena community, > > > > > > > > I tried with Jena API and it works! > > > > I still can't apply the ontology inference via Fuseki server's > > > > config > > > > file. > > > > > > > > I'm happy to share my repo on GitHub containing a complete > > > > report, > > > > data > > > > and (my first) Java code. > > > > <<https://github.com/0m1n0/jena_reasoner>> > > > > > > > > Thank you for your help. > > > > Min > > > > > > > > Le jeu., févr. 9 2023 at 18:17:48 +0100, Yang-Min KIM > > > > <yang-min.kim@microbiome.studio > > > > <mailto:yang-min.kim@microbiome.studio>> a écrit : > > > > > Thank you for your reply! > > > > > > > > > > @Lorenz > > > > > > > > > > I tried all reasoners: Generic Rule Reasoner, Transitive > > > > > Reasoner, > > > > > RDFS Rule Reasoner, Full OWL Reasoner, Mini OWL Reasoner, and > > > > > Micro > > > > > OWL Reasoner. > > > > > << > > > > > < > > > > > https://jena.apache.org/documentation/fuseki2/fuseki-configura > > > > > tion>. > > > > > html>> > > > > > -> "Possible reasoners" section > > > > > But unfortunately it didn't work... What I did: > > > > > > > > > > for i in list_of_all_possible_reasoners: > > > > > - update reasonerURL in config.ttl (where the data location > > > > > link in > > > > > TDB refers to > > > > > `/opt/tomcat/fuseki/base/databases/test_ontology_pizza`) > > > > > - restart server > > > > > - create new dataset and upload data as default graph with > > > > > two > > > > > options: > > > > > 1. create two separated datasets where ontology data > > > > > stored > > > > > in > > > > > `test_ontology_pizza` dataset and test data stored in > > > > > `test_pizza` > > > > > dataset > > > > > 2. create one dataset `test_ontology_pizza` where > > > > > both > > > > > ontology > > > > > data and test data are stored > > > > > - run SPARQL query -> check if it works > > > > > - remove created dataset(s) > > > > > > > > > > > > > > > @Steve > > > > > > > > > > I'm sure we can apply the inference model by customising via > > > > > Java > > > > > but > > > > > unfortunately I don't code in Java... > > > > > > > > > > > > > > > Le jeu., févr. 9 2023 at 05:11:15 -0600, Steve Vestal > > > > > <steve.ves...@galois.com <mailto:steve.ves...@galois.com> > > > > > <<mailto:steve.ves...@galois.com>>> a écrit > > > > > : > > > > > > Are you trying to issue a SPARQL query against a knowledge > > > > > > base > > > > > > that > > > > > > > includes inferred as well as explicitly asserted > > > > > > > information, > > > > > > such > > > > > > as an inverse of an asserted property? You can do this by > > > > > > issuing > > > > > > a query to an OntModel using QueryExecution.create(String > > > > > > queryStr, > > > > > > > Syntax lang, Model model). If anyone knows how to do > > > > > > > this for a > > > > > > > DataSet (TDP2), please let me know. > > > > > > > > > > > > On 2/8/2023 10:45 AM, Yang-Min KIM wrote: > > > > > > > Dear Jena community, > > > > > > > > > > > > > > As a beginner in Jena (and I do not code in Java), I > > > > > > > would like > > > > > > > to > > > > > > > > > ask you a question about ontology integration. > > > > > > > > > > > > > > - Data: small test data and corresponding OWL ontology > > > > > > > - Method: put data into GraphDB and Jena servers then run > > > > > > > SPARQL > > > > > > > > > query > > > > > > > - Expected result: initial missing information is > > > > > > > complemented > > > > > > > by > > > > > > > > > > ontology transitivity > > > > > > > > > > > > > > I will describe you step by step, the questions will come > > > > > > > at > > > > > > > the > > > > > > > end of the mail. > > > > > > > > > > > > > > ///////////////////////////// Report: what I did > > > > > > > > > > ///////////////////////////// > > > > > > > > > > > > > > 1. Test data: pizza! > > > > > > > > > > > > > > 1.1. Pizza ontology > > > > > > > As example, we use Pizza ontology provided by "OWL > > > > > > > Example with > > > > > > > RDF > > > > > > > > > > Graph" > > > > > > > <<< > > > > > > > < > > > > > > > https://www.obitko.com/tutorials/ontologies-semantic-web/o > > > > > > > wl>- > > > > > > > example-with-rdf-graph.html>>> > > > > > > > > > > > > > > > > > <<< > > > > > > > <https://i.postimg.cc/ZRjJy7XQ/Capture-d-cran-du-2023-02- > > > > > > > 08-15>- > > > > > > > 07-19.png>>> > > > > > > > > > > > > > > We focus on the inverse relationships: `:isIngredientOf > > > > > > > > > owl:inverseOf :hasIngredient .` i.e. the property > > > > > > > `isIngredientOf` is the inverse of the property > > > > > > > `hasIngredient`. > > > > > > > ------------------------------------------- > > > > > > > :isIngredientOf > > > > > > > a owl:TransitiveProperty , owl:ObjectProperty ; > > > > > > > owl:inverseOf :hasIngredient . > > > > > > > ------------------------------------------- > > > > > > > > > > > > > > > > > > > > > 1.2. Pizza data > > > > > > > Two pizza `Margherita` and `Cheese Bacon`: the > > > > > > > relationship > > > > > > > between > > > > > > > > > a pizza and an ingredient is declared by the > > > > > > > > > property either > > > > > > > > > > `isIngredientOf` or `hasIngredient`. In summary: > > > > > > > - Margherita contains tomato and basilic > > > > > > > - Cheese Bacon contains cheese, bacon, and tomato > > > > > > > > > > > > > > ------------------------------------------- > > > > > > > @prefix ex: <<http://example.com/>> . > > > > > > > @prefix pizza: <<http://example.com/pizzas.owl#>> . > > > > > > > @prefix rdf: > > > > > > > <<http://www.w3.org/1999/02/22-rdf-syntax-ns#>> . > > > > > > > > > > > > > > # Margherita > > > > > > > ex:margherita rdf:type pizza:Pizza . > > > > > > > ex:margherita rdf:type pizza:VegetarianPizza . > > > > > > > ex:tomato pizza:isIngredientOf ex:margherita . > > > > > > > ex:margherita pizza:hasIngredient ex:basilic . > > > > > > > > > > > > > > # Cheese Bacon > > > > > > > ex:cheese_bacon rdf:type pizza:Pizza . > > > > > > > ex:cheese_bacon rdf:type pizza:NonVegetarianPizza . > > > > > > > ex:cheese pizza:isIngredientOf ex:cheese_bacon . > > > > > > > ex:cheese_bacon pizza:hasIngredient ex:bacon . > > > > > > > ex:cheese_bacon pizza:hasIngredient ex:tomato . > > > > > > > ------------------------------------------- > > > > > > > > > > > > > > > > > > > > > > > > > > > > 2. GraphDB > > > > > > > > > > > > > > 2.1. Dataset (repository) creation: > > > > > > > <<< > > > > > > > <https://i.postimg.cc/k5QJ7Xsq/Capture-d-cran-du-2023-02- > > > > > > > 08-15>- > > > > > > > 09-15.png>>> > > > > > > > As shown in the image, the `RDFS-Plus (Optimized)` are > > > > > > > set up > > > > > > > by > > > > > > > > > > default when creating a repository (dataset in Jena > > > > > > > > > > term). > > > > > > > > > > > > > > 2.2. Upload test data > > > > > > > Both test data and ontology are uploaded in a same > > > > > > > repository > > > > > > > (as > > > > > > > > > > default or named graphes, results are unchanged). > > > > > > > <<< > > > > > > > <https://i.postimg.cc/qq501tJX/Capture-d-cran-du-2023-02- > > > > > > > 08-15>- > > > > > > > 06-01.png>>> > > > > > > > We can see reciprocal relationships between pizza and > > > > > > > ingredients > > > > > > > > > > (`hasIngredient` and `isIngredientOf`). > > > > > > > > > > > > > > 2.3. SPARQL query > > > > > > > <<< > > > > > > > <https://i.postimg.cc/KcqZGWPk/Capture-d-cran-du-2023-02- > > > > > > > 08-15>- > > > > > > > 05-47.png>>> > > > > > > > Got expected results: all ingredients are presents i.e. > > > > > > > initial > > > > > > > > > > missing information is complemented: `ex:tomato > > > > > > > > > pizza:isIngredientOf ex:margherita` is equivalent to > > > > > > > `ex:margherita pizza:hasIngredient ex:tomato` > > > > > > > > > > > > > > > > > > > > > > > > > > > > 3. Jena > > > > > > > > > > > > > > 3.1. Dataset creation > > > > > > > Fuseki UI does not allow to set default reasoner as seen > > > > > > > in > > > > > > > 2.1. > > > > > > > It would be awesome if we could specify at this step! > > > > > > > > > > > > > > 3.2. Upload test data > > > > > > > Each data is uploaded on TDB as default graph into: > > > > > > > - A same dataset > > > > > > > - Separated dataset > > > > > > > > > > > > > > 3.3. SPARQL query > > > > > > > <<< > > > > > > > <https://i.postimg.cc/Fz0cXJzm/Capture-d-cran-du-2023-02- > > > > > > > 08-15>- > > > > > > > 38-30.png>>> > > > > > > > Misisng relationships are still missing, e.g. tomato is > > > > > > > missing > > > > > > > as > > > > > > > > > > Margherita's ingredient. > > > > > > > > > > > > > > 3.4. Set inference model via config > > > > > > > According to your previous suggestions (thank you Dave > > > > > > > and > > > > > > > Lorenz!), I have tried to follow the configuration > > > > > > > steps > > > > > > > mentioned in Fuseki's configuration documentation. > > > > > > > <<< > > > > > > > < > > > > > > > https://jena.apache.org/documentation/fuseki2/fuseki-confi > > > > > > > gurat> > > > > > > > ion.html>>> > > > > > > > > > > -> section "Inference" > > > > > > > I uploaded ontology file into a separated TDB dataset > > > > > > > named > > > > > > > > > > "test_ontology_pizza". > > > > > > > Then I modified Fuseki's `config.ttl` by adding the part > > > > > > > after > > > > > > > ## > > > > > > > > > > ----------- as below. > > > > > > > The results are the same as the previous ones despite > > > > > > > restarting > > > > > > > the server. > > > > > > > > > > > > > > ------------------------------------------- > > > > > > > # Licensed under the terms of > > > > > > > > > > <<<<http://www.apache.org/licenses/LICENSE-2.0>>>> > > > > > > > > > > > > > > ## Fuseki Server configuration file. > > > > > > > > > > > > > > @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 ja: <<http://jena.hpl.hp.com/2005/11/Assembler#>> > > > > > > > . > > > > > > > @prefix tdb2: <<http://jena.apache.org/2016/tdb#>> . > > > > > > > > > > > > > > [] rdf:type fuseki:Server ; > > > > > > > # Example:: > > > > > > > # Server-wide query timeout. > > > > > > > # > > > > > > > # Timeout - server-wide default: milliseconds. > > > > > > > # Format 1: "1000" -- 1 second timeout > > > > > > > # Format 2: "10000,60000" -- 10s timeout to first > > > > > > > result, > > > > > > > # then 60s timeout for the > > > > > > > rest of > > > > > > > > > query. > > > > > > > # > > > > > > > # See javadoc for ARQ.queryTimeout for details. > > > > > > > # This can also be set on a per dataset basis in the > > > > > > > dataset > > > > > > > > > assembler. > > > > > > > # > > > > > > > # ja:context [ ja:cxtName "arq:queryTimeout" ; > > > > > > > ja:cxtValue > > > > > > > > > "30000" ] ; > > > > > > > > > > > > > > # Add any custom classes you want to load. > > > > > > > # Must have a "public static void init()" method. > > > > > > > # ja:loadClass "your.code.Class" ; > > > > > > > > > > > > > > # End triples. > > > > > > > . > > > > > > > > > > > > > > ## --------------------------- Added > > > > > > > > > ------------------------------------ > > > > > > > > > > > > > > # Dataset with only the default graph. > > > > > > > :dataset rdf:type ja:RDFDataset ; > > > > > > > ja:defaultGraph :model_inf ; > > > > > > > . > > > > > > > > > > > > > > # The inference model, data is taken from TDB > > > > > > > :model_inf a ja:InfModel ; > > > > > > > ja:baseModel :tdbGraph ; > > > > > > > ja:reasoner [ > > > > > > > ja:reasonerURL > > > > > > > > > > <<<<< > > > > > > > > > > http://jena.hpl.hp.com/2003/RDFSExptRuleReasoner>>> > > > > > > > > > > >> > > > > > > > ] . > > > > > > > > > > > > > > :tdbGraph rdf:type tdb2:GraphTDB2 ; > > > > > > > tdb2:dataset :tdbDataset . > > > > > > > > > > > > > > ## Base data in TDB. > > > > > > > :tdbDataset rdf:type tdb2:DatasetTDB2 ; > > > > > > > tdb2:location > > > > > > > > > > "/opt/tomcat/fuseki/base/databases/test_ontology_pi > > > > > > > > > > zza" ; > > > > > > > # If the unionDefaultGraph is used, then the "update" > > > > > > > service > > > > > > > > > > should be removed. > > > > > > > # tdb:unionDefaultGraph true ; > > > > > > > . > > > > > > > ------------------------------------------- > > > > > > > > > > > > > > > > > > > > > ///////////////////////////// Questions > > > > > > > ///////////////////////////// > > > > > > > > > > > > > > Q1. Where and how should the data (pizza test data and > > > > > > > pizza > > > > > > > > > ontology) be stored? Separated dataset? As default > > > > > > > > > graph? > > > > > > > > > > > > > > Q2. Is it better to configure at the global server level > > > > > > > > > (congif.ttl) or dataset level (dataset_name.ttl) ? > > > > > > > > > > > > > > Q3. Should we restart tomcat or redeploy war each time we > > > > > > > update > > > > > > > > > gobal config or per dataset config ? > > > > > > > > > > > > > > Q4. I'm pretty sure there are errors in my > > > > > > > configuration..., > > > > > > > but > > > > > > > > > where? > > > > > > > > > > > > > > Q5. Side question. Is it possible to trigger from command > > > > > > > line > > > > > > > one > > > > > > > > > of those predefined rule engine () on a given > > > > > > > > > dataset ? > > > > > > > > > > > > > > > > > > > > > Thank you for reading my long story and for your > > > > > > > insights! > > > > > > > > > > > > > > Best Regards, > > > > > > > Min > > > > > > > > > > > > > > > > > > > > > >