@Steve
>So this will let me issue SPARQL queries against a reasoner that pulls from a TDB store? Yes, that's what I'd like to do: the reasoner is built from a TDB dataset and it will be applied on other TDB datasets, then my SPARQL queries will be run. I've never used BGP but as you say, I may have to change my SPARQL request

@Simon
Thanks, I think we are close to solving the problem!
I have configuration files as below:
        - Fuseki server configuration (one unique config file):
                - /opt/tomcat/fuseki/base/config.ttl
        - Dataset configuration (one file by a TDB dataset):
                - /opt/tomcat/fuseki/base/configuration/test_ontology_pizza.ttl
                - /opt/tomcat/fuseki/base/configuration/test_pizza.ttl

With:
- `test_ontology_pizza.ttl` stores ontology data where the reasoner will be based - `test_pizza.ttl` contains a small sample data where the reasoner and SPARQL query will be applied

Your code seems to be rather suitable for the Dataset configuration than Fuseki server configuration. I tried to apply your code in both cases (Fuseki server and Dataset) but it did not work. Can you specify whether to configure at the Fuseki service level or per TDB Dataset?

I've also tried with `ja:externalContent` (with a ontology file manually saved in `/opt/tomcat/fuseki/pizza_ontology.rdf`) as bellow but still no result.

--------------------------------------------------------

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

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

<#pizzaService> rdf:type fuseki:Service ;
   # URI of the dataset -- <http://host:port/pizza>
   fuseki:name                        "pizza" ;
   fuseki:serviceQuery                "sparql" ;
   fuseki:serviceQuery                "query" ;
   fuseki:serviceUpdate               "update" ;
   fuseki:serviceUpload               "upload" ;
   fuseki:serviceReadWriteGraphStore  "data" ;
   fuseki:serviceReadGraphStore       "get" ;
   fuseki:dataset                     <#dataset> .

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

<#model> rdf:type ja:InfModel ;
   ja:baseModel <#tdbGraph> ;
   ja:content <#pizza> ;
   ja:reasoner [
ja:reasonerURL <<http://jena.hpl.hp.com/2003/OWLFBRuleReasoner>>]
   .

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

<#tdbDataset> rdf:type tdb2:DatasetTDB ;
#       tdb2:location "Pizza_test" .
tdb2:location "/opt/tomcat/fuseki/base/databases/test_ontology_pizza" .

# Ontologies
<#pizza> ja:externalContent <<file:///opt/tomcat/fuseki/pizza_ontology.rdf>> .

Le jeu., févr. 16 2023 at 14:57:39 -0600, Steve Vestal <steve.ves...@galois.com> a écrit :
So this will let me issue SPARQL queries against a reasoner that pulls from a TDB store? But is it using a Graph interface to the store? I thought fetching things through a StageGenerator interface was needed to make full use of an indexed store , e.g., use BGPs rather than single triple queries?

On 2/16/2023 1:37 PM, Simon Bin wrote:
You are only missing 2 steps on you fuseki config, then it can work:

1) you need to use OWL reasoner, not an empty rule reasoner

2) you need to define a SPARQL service for your dataset

here is the required changes in "git diff" format:

diff --git a/data/config.ttl b/data/config.ttl
index 69c9cba..4b77ce7 100644
--- a/data/config.ttl
+++ b/data/config.ttl
@@ -28,6 +28,16 @@
 ## --------------------------- Added ------------------------------------
  +:service rdf:type fuseki:Service ;
+    rdfs:label      "Pizza Ontology Reasoning" ;
+    fuseki:name     "pizza" ;
+    fuseki:dataset  :dataset ;
+
+    fuseki:endpoint [ fuseki:operation fuseki:query ] ;
+    fuseki:endpoint [ fuseki:operation fuseki:update ] ;
+    fuseki:endpoint [ fuseki:operation fuseki:gsp-rw ] ;
+    .
+
  # Dataset with only the default graph.
  :dataset rdf:type ja:RDFDataset ;
           ja:defaultGraph :model_inf ;
@@ -37,7 +47,7 @@
  :model_inf a ja:InfModel ;
             ja:baseModel :tdbGraph ;
             ja:reasoner [
- ja:reasonerURL <<http://jena.hpl.hp.com/2003/GenericRuleReasoner>> + ja:reasonerURL <<http://jena.hpl.hp.com/2003/OWLFBRuleReasoner>>
               ] .
    :tdbGraph rdf:type tdb2:GraphTDB2 ;


On Thu, 2023-02-16 at 19:35 +0100, Yang-Min KIM wrote:
Dear Jena community,

I tried with Jena API and it works!
I still can't apply the ontology inference via Fuseki server's config
file.

I'm happy to share my repo on GitHub containing a complete report,
data
and (my first) Java code.
<<https://github.com/0m1n0/jena_reasoner>>

Thank you for your help.
Min

Le jeu., févr. 9 2023 at 18:17:48 +0100, Yang-Min KIM
<yang-min.kim@microbiome.studio <mailto:yang-min.kim@microbiome.studio>> a écrit :
Thank you for your reply!

@Lorenz

I tried all reasoners: Generic Rule Reasoner, Transitive Reasoner,
RDFS Rule Reasoner, Full OWL Reasoner, Mini OWL Reasoner, and Micro
OWL Reasoner.
<<
<https://jena.apache.org/documentation/fuseki2/fuseki-configuration>.
html>>
-> "Possible reasoners" section
But unfortunately it didn't work... What I did:

for i in list_of_all_possible_reasoners:
- update reasonerURL in config.ttl (where the data location link in
TDB refers to
`/opt/tomcat/fuseki/base/databases/test_ontology_pizza`)
- restart server
- create new dataset and upload data as default graph with two
options:
1. create two separated datasets where ontology data stored
in
`test_ontology_pizza` dataset  and test data stored in `test_pizza`
dataset
         2. create one dataset `test_ontology_pizza` where both
ontology
data and test data are stored
- run SPARQL query -> check if it works
- remove created dataset(s)


@Steve

I'm sure we can apply the inference model by customising via Java
but
unfortunately I don't code in Java...


Le jeu., févr. 9 2023 at 05:11:15 -0600, Steve Vestal
<steve.ves...@galois.com <mailto:steve.ves...@galois.com> <<mailto:steve.ves...@galois.com>>> a écrit
:
Are you trying to issue a SPARQL query against a knowledge base
that
includes inferred as well as explicitly asserted information,
such
as an inverse of an asserted property?  You can do this by
issuing
a query to an OntModel using QueryExecution.create(String
queryStr,
Syntax lang, Model model).  If anyone knows how to do this for a
DataSet (TDP2), please let me know.

On 2/8/2023 10:45 AM, Yang-Min KIM wrote:
Dear Jena community,

As a beginner in Jena (and I do not code in Java), I would like
to
ask you a question about ontology integration.

- Data: small test data and corresponding OWL ontology
- Method: put data into GraphDB and Jena servers then run
SPARQL
query
- Expected result: initial missing information is complemented
by
ontology transitivity

I will describe you step by step, the questions will come at
the
end of the mail.

///////////////////////////// Report: what I did
/////////////////////////////

1. Test data: pizza!

1.1. Pizza ontology
As example, we use Pizza ontology provided by "OWL Example with
RDF
Graph"
<<<
<https://www.obitko.com/tutorials/ontologies-semantic-web/owl>-
example-with-rdf-graph.html>>>

<<<
<https://i.postimg.cc/ZRjJy7XQ/Capture-d-cran-du-2023-02-08-15>-
07-19.png>>>

We focus on the inverse relationships: `:isIngredientOf
owl:inverseOf :hasIngredient .` i.e. the property
`isIngredientOf` is the inverse of the property
`hasIngredient`.
-------------------------------------------
:isIngredientOf
    a owl:TransitiveProperty , owl:ObjectProperty ;
    owl:inverseOf :hasIngredient .
-------------------------------------------


1.2. Pizza data
Two pizza `Margherita` and `Cheese Bacon`: the relationship
between
a pizza and an ingredient is declared by the property either
`isIngredientOf` or `hasIngredient`. In summary:
- Margherita contains tomato and basilic
- Cheese Bacon contains cheese, bacon, and tomato

-------------------------------------------
@prefix ex:     <<http://example.com/>> .
@prefix pizza:  <<http://example.com/pizzas.owl#>> .
@prefix rdf: <<http://www.w3.org/1999/02/22-rdf-syntax-ns#>> .

# Margherita
ex:margherita rdf:type pizza:Pizza .
ex:margherita rdf:type pizza:VegetarianPizza .
ex:tomato pizza:isIngredientOf ex:margherita .
ex:margherita pizza:hasIngredient ex:basilic .

# Cheese Bacon
ex:cheese_bacon rdf:type pizza:Pizza .
ex:cheese_bacon rdf:type pizza:NonVegetarianPizza .
ex:cheese pizza:isIngredientOf ex:cheese_bacon .
ex:cheese_bacon pizza:hasIngredient ex:bacon .
ex:cheese_bacon pizza:hasIngredient ex:tomato .
-------------------------------------------



2. GraphDB

2.1. Dataset (repository) creation:
<<<
<https://i.postimg.cc/k5QJ7Xsq/Capture-d-cran-du-2023-02-08-15>-
09-15.png>>>
As shown in the image, the `RDFS-Plus (Optimized)` are set up
by
default when creating a repository (dataset in Jena term).

2.2. Upload test data
Both test data and ontology are uploaded in a same repository
(as
default or named graphes, results are unchanged).
<<<
<https://i.postimg.cc/qq501tJX/Capture-d-cran-du-2023-02-08-15>-
06-01.png>>>
We can see reciprocal relationships between pizza and
ingredients
(`hasIngredient` and `isIngredientOf`).

2.3. SPARQL query
<<<
<https://i.postimg.cc/KcqZGWPk/Capture-d-cran-du-2023-02-08-15>-
05-47.png>>>
Got expected results: all ingredients are presents i.e. initial
missing information is complemented: `ex:tomato
pizza:isIngredientOf ex:margherita` is equivalent to
`ex:margherita pizza:hasIngredient ex:tomato`



3. Jena

3.1. Dataset creation
Fuseki UI does not allow to set default reasoner as seen in
2.1.
It would be awesome if we could specify at this step!

3.2. Upload test data
Each data is uploaded on TDB as default graph into:
- A same dataset
- Separated dataset

3.3. SPARQL query
<<<
<https://i.postimg.cc/Fz0cXJzm/Capture-d-cran-du-2023-02-08-15>-
38-30.png>>>
Misisng relationships are still missing, e.g. tomato is missing
as
Margherita's ingredient.

3.4. Set inference model via config
According to your previous suggestions (thank you Dave and
Lorenz!), I have tried to follow the configuration steps
mentioned in Fuseki's configuration documentation.
<<<
<https://jena.apache.org/documentation/fuseki2/fuseki-configurat>
ion.html>>>
-> section "Inference"
I uploaded ontology file into a separated TDB dataset named
"test_ontology_pizza".
Then I modified Fuseki's `config.ttl` by adding the part after
##
----------- as below.
The results are the same as the previous ones despite
restarting
the server.

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

## Fuseki Server configuration file.

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

[] rdf:type fuseki:Server ;
   # Example::
   # Server-wide query timeout.
   #
   # Timeout - server-wide default: milliseconds.
   # Format 1: "1000" -- 1 second timeout
   # Format 2: "10000,60000" -- 10s timeout to first result,
   #                            then 60s timeout for the rest of
query.
   #
   # See javadoc for ARQ.queryTimeout for details.
   # This can also be set on a per dataset basis in the dataset
assembler.
   #
   # ja:context [ ja:cxtName "arq:queryTimeout" ;  ja:cxtValue
"30000" ] ;

   # Add any custom classes you want to load.
   # Must have a "public static void init()" method.
   # ja:loadClass "your.code.Class" ;

   # End triples.
   .

## --------------------------- Added
------------------------------------

# Dataset with only the default graph.
:dataset rdf:type ja:RDFDataset ;
    ja:defaultGraph :model_inf ;
     .

# The inference model, data is taken from TDB
:model_inf a ja:InfModel ;
     ja:baseModel :tdbGraph ;
     ja:reasoner [
         ja:reasonerURL
<<<<<http://jena.hpl.hp.com/2003/RDFSExptRuleReasoner>>>>>
     ] .

:tdbGraph rdf:type tdb2:GraphTDB2 ;
    tdb2:dataset :tdbDataset .

## Base data in TDB.
:tdbDataset rdf:type tdb2:DatasetTDB2 ;
    tdb2:location
"/opt/tomcat/fuseki/base/databases/test_ontology_pizza" ;
    # If the unionDefaultGraph is used, then the "update"
service
should be removed.
    # tdb:unionDefaultGraph true ;
    .
-------------------------------------------


///////////////////////////// Questions
/////////////////////////////

Q1. Where and how should the data (pizza test data and pizza
ontology) be stored? Separated dataset? As default graph?

Q2. Is it better to configure at the global server level
(congif.ttl) or dataset level (dataset_name.ttl) ?

Q3. Should we restart tomcat or redeploy war each time we
update
gobal config or per dataset config ?

Q4. I'm pretty sure there are errors in my configuration...,
but
where?

Q5. Side question. Is it possible to trigger from command line
one
of those predefined rule engine () on a given dataset ?


Thank you for reading my long story and for your insights!

Best Regards,
Min




Reply via email to