You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@jena.apache.org by Yang-Min KIM <ya...@microbiome.studio> on 2023/02/08 16:45:33 UTC

Inference reasoner

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-configuration.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



Re: Inference reasoner

Posted by Lorenz Buehmann <bu...@informatik.uni-leipzig.de>.
Your config indicates some RDFS reasoner, but apparently transitivity as 
well as inverse relations both a re part of OWL semantics only (also 
indicarted by the owl: prefix of course). And OWL is way more expressive 
than RDFS, and inference way more expensive of course.

  Thus, you should use an appropriate OWL reasoner, see the coverage of 
the existing reasoner profiles: 
https://jena.apache.org/documentation/inference/#OWLcoverage

On 08.02.23 17:45, 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-configuration.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
>
>
>

Re: Re: Inference reasoner

Posted by Simon Bin <sb...@informatik.uni-leipzig.de>.
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 
> <st...@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 
> > > > <ma...@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.vestal@galois.com <ma...@galois.com> 
> > > > > <<m...@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
> > > > > > > 
> > > > > > > 
> > > > > > > 
> 


Re: Inference reasoner

Posted by Yang-Min KIM <ya...@microbiome.studio>.
@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 
<st...@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 
>>> <ma...@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.vestal@galois.com <ma...@galois.com> 
>>>> <<m...@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
>>>>>> 
>>>>>> 
>>>>>> 


Re: Inference reasoner

Posted by Steve Vestal <st...@galois.com>.
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
>> <ya...@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.vestal@galois.com <ma...@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
>>>>>
>>>>>
>>>>>

Re: Re: Inference reasoner

Posted by Simon Bin <sb...@informatik.uni-leipzig.de>.
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 
> <ya...@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.vestal@galois.com <ma...@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
> > > > 
> > > > 
> > > > 
> > 
> 


Re: Inference reasoner

Posted by Yang-Min KIM <ya...@microbiome.studio>.
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 
<ya...@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.vestal@galois.com <ma...@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-configuration.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
>>> 
>>> 
>>> 
> 


Re: Inference reasoner

Posted by Yang-Min KIM <ya...@microbiome.studio>.
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 
<st...@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-configuration.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
>> 
>> 
>> 


Re: Inference reasoner

Posted by Steve Vestal <st...@galois.com>.
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-configuration.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
>
>
>