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> 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-configuration. > > 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>> 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/owl- > > > > 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-configurat > > > > 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_pizza" ; > > > > # 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 > > > > > > > > > > > > > > >