$$%% examples \newcommand{\exGraph}{\graph_{\mathrm{ex}}} \newcommand{\exOnto}{\onto_{\mathrm{ex}}} \newcommand{\exMappings}{\mappings_{\mathrm{ex}}} \newcommand{\exExtensions}{\extensions_{\mathrm{ex}}} \newcommand{\exRule}{r_{\mathrm{ex}}} \newcommand{\RDFSrules}{\rules_{\mathrm{RDFS}}} %% RDF \newcommand{\triple}[3]{(#1, #2, #3)} \newcommand{\tuple}[1]{\langle #1 \rangle} \newcommand{\subject}{\mathtt{s}} \newcommand{\prop}{\mathtt{p}} \newcommand{\object}{\mathtt{o}} \newcommand{\blank}{\_{:}b} \newcommand{\blankn}[1]{\_{:}#1} \newcommand{\irin}[1]{{:}\mathrm{#1}} \newcommand{\class}{\mathtt{c}} \newcommand{\nsrdf}{\mathrm{rdf{:}}} \newcommand{\nsrdfs}{\mathrm{rdfs{:}}} \newcommand{\rdftype}{\mathrm{rdf{:}type}} \newcommand{\rdfLiteral}{\mathrm{rdf{:}Literal}} \newcommand{\rdfssubClassOf}{\mathrm{rdfs{:}subClassOf}} \newcommand{\rdfssubPropertyOf}{\mathrm{rdfs{:}subPropertyOf}} \newcommand{\rdfsdomain}{\mathrm{rdfs{:}domain}} \newcommand{\rdfsrange}{\mathrm{rdfs{:}range}} \newcommand{\rdfsClass}{\mathrm{rdfs{:}Class}} \newcommand{\rdfProperty}{\mathrm{rdf{:}Property}} \newcommand{\xsdint}{\mathrm{xsd{:}int}} %% \newcommand{\type}{\tau} \newcommand{\subclass}{\prec_{sc}} \newcommand{\subproperty}{\prec_{sp}} \newcommand{\domain}{\hookleftarrow_{d}} \newcommand{\range}{\hookrightarrow_{r}} \newcommand{\rdfentailment}{\vdash_{^\mathrm{RDF}}} \newcommand{\RDFS}[1]{\mathrm{RDFS}(#1)} \newcommand{\aka}{a.k.a.~} \newcommand{\etc}{etc} \newcommand{\wrt}{w.r.t.~} \newcommand{\st}{s.t.~} \newcommand{\ie}{i.e.,~} \newcommand{\eg}{e.g.,~} \newcommand{\graph}{G} \newcommand{\rules}{\mathcal{R}} \newcommand{\sources}{\mathcal{S}} \newcommand{\views}{\mathcal{V}} \newcommand{\extensions}{\mathcal{E}} \newcommand{\onto}{\mathcal{O}} \newcommand{\mappings}{\mathcal{M}} \newcommand{\modelsrdf}{\models_\rules} \newcommand{\bgp}{P} \newcommand{\Bl}[1]{\mathrm{Bl}(#1)} \newcommand{\Val}[1]{\mathrm{Val}(#1)} \newcommand{\Var}[1]{\mathrm{Var(#1)}} \newcommand{\ext}[1]{\mathrm{ext}(#1)} \newcommand{\cert}{\mathrm{cert}} \newcommand{\ans}{\mathrm{ans}} \newcommand{\query}{\leftarrow} \newcommand{\body}[1]{\textrm{body}(#1)} \newcommand{\head}[1]{\textrm{head}(#1)} \newcommand{\cs}{\mathrm{cs}} \newcommand{\lcs}{\mathrm{lcs}} \newcommand{\cl}{\mathrm{cl}} \newcommand{\lua}{\mathrm{lua}} \newcommand{\lur}{\mathrm{lur}} \newtheorem{lemma}{Lemma} \newtheorem{definition}{Definition} \newtheorem{problem}{Problem} \newtheorem{property}{Property} \newtheorem{corollary}{Corollary} \newtheorem{example}{Example} \newtheorem{theorem}{Theorem} \newcommand{\URIs}{\mathscr U} \newcommand{\IRIs}{\mathscr I} \newcommand{\BNodes}{\mathscr B} \newcommand{\Literals}{\mathscr L} \newcommand{\Variables}{\mathscr V} % DB \newcommand{\CQ}{\ensuremath{\mathtt{CQ}}\xspace} \newcommand{\UCQ}{\ensuremath{\mathtt{UCQ}}\xspace} \newcommand{\SQL}{\ensuremath{\mathtt{SQL}}\xspace} \newcommand{\rel}[1]{\mathsf{#1}} % Cost model \newcommand{\cans}[1]{|#1|_t} \newcommand{\cref}[1]{|#1|_r} \newcommand{\db}{\mathtt{db}} % DL \newcommand{\cn}{\ensuremath{N_{C}}\xspace} \newcommand{\rn}{\ensuremath{N_{R}}\xspace} \newcommand{\inds}{\ensuremath{N_{I}}\xspace} \newcommand{\ainds}{\ensuremath{\mathrm{Ind}}\xspace} \newcommand{\funct}{\mathit{funct} \ } \newcommand{\KB}{\mathcal{K}\xspace} \newcommand{\dlr}{DL-Lite$_{\mathcal{R}}$\xspace} % Logics \newcommand{\FOL}{\ensuremath{\mathtt{FOL}}\xspace} \newcommand{\datalog}{\ensuremath{\mathtt{Datalog}}\xspace} \newcommand{\dllite}{DL-Lite\xspace} \newcommand{\true}{\mathrm{true}} \newcommand{\false}{\mathrm{false}} \newcommand{\dis}{\mathtt{dis}} \newcommand{\vars}[1]{\ensuremath{\mathrm{vars}(#1)}} %\newcommand{\terms}[1]{\ensuremath{\mathrm{terms}(#1)}} %math \renewcommand{\phi}{\varphi} \newcommand\eqdef{\stackrel{\mathclap{\normalfont\mbox{def}}}{=}} \newcommand\restr[2]{#1_{|#2}} \newcommand{\ontoBody}[1]{\mathrm{body}_\onto(#1)} %proof of the rewriting theorem \newcommand{\rdfGraph}{\graph^{\mappings}_{\extensions}} \newcommand\systemGraph{\graph^{\mappings \cup \mappings^{\text{STD}}_\onto}_{\extensions \cup \extensions_\onto}} \newcommand\viewsGraph{\graph^{\mappings^{\rules,\onto} \cup \mappings^{\text{STD}}_\onto}_{\extensions \cup \extensions_\onto}} \newcommand{\standMappings}{\mappings^{\text{STD}}_\onto} \newcommand{\reminder}[1]{[\vadjust{\vbox to0pt{\vss\hbox to0pt{\hss{\Large $\Longrightarrow$}}}}{{\textsf{\small #1}}}]} %\newcommand{\FG}[1]{\textcolor{blue}{\reminder{FG:~#1}}} \newcommand{\extVersion}{false} \newcommand{\printIfExtVersion}[2] { \ifthenelse{\equal{\extVersion}{true}}{#1}{} \ifthenelse{\equal{\extVersion}{false}}{#2}{} } \newcommand{\bda}{\true} \newcommand{\ifBDA}[2]% {% \ifthenelse{\equal{\bda}{true}}{#1}{}% \ifthenelse{\equal{\bda}{false}}{#2}{}% } %%% Local Variables: %%% TeX-master: "paper" %%% End: $$

Virtuoso

Table of Contents

1. Installation

some instructions: http://vos.openlinksw.com/owiki/wiki/VOS/VOSUbuntuNotes

Welcome to the Emacs shell

maxime@uca-pc [13-07-2023 14:51] /home/maxime/work/org/posts 
└─>sudo apt install virtuoso-opensource

2. Command Lines

2.1. Starting the server

sudo virtuoso-t -fd +configfile /etc/virtuoso/virtuoso.ini

2.2. Data Loading

2.3. List all graph

isql-vt 1111 dba dba exec="SPARQL SELECT  DISTINCT ?g \
   WHERE  { GRAPH ?g {?s ?p ?o} } \
ORDER BY  ?g"

3. Reasoning at query time

The reasoning is done at query time by default. The reasoning is expressed either using an ontology (with default rules) or custom rules.

3.1. RDFS (Ra) and OWL

In the official documentation, we can see that Virtuoso reasoning w.r.t. Ra rules set is limited to:

  • rdfs7 \(\triple{\prop_a}{\subproperty}{\prop_b},\triple{\mathrm{s}}{\prop_a}{\object} \rightarrow \triple{\mathrm{s}}{\prop_b}{\object}\)
  • rdfs9 \(\triple{\mathrm{s}}{\subclass}{\object},\triple{\mathrm{s}_1}{\type}{\mathrm{s}} \rightarrow \triple{\mathrm{s}_1}{\type}{\object}\)

The reasoning w.r.t. domain and range is not supported.

See also:

3.1.1. Ra Tests

I test the reasoning according to subClassOf and subPropertyOf using the query answering test developed for OntoSQL.

  1. clear and load the graph:

    isql-vt 1111 dba dba exec="SPARQL 
    CLEAR GRAPH <urn:qa-test-graph>;"
    
    isql-vt 1111 dba dba exec="SPARQL 
    LOAD <http://pages.saclay.inria.fr/maxime.buron/projects/qa-test/qa-test.nt>
    INTO <urn:qa-test-graph>;"
    
  2. check the data triples:

    isql-vt 1111 dba dba exec="SPARQL 
    SELECT * 
    FROM <urn:qa-test-graph>
    WHERE 
    { ?s ?p ?o };"
    
  3. loading of the ontology

    isql-vt 1111 dba dba exec="sparql 
    clear graph <urn:qa-test-onto>;"
    
    isql-vt 1111 dba dba exec="SPARQL 
    LOAD <http://pages.saclay.inria.fr/maxime.buron/projects/qa-test/qa-test-schema.nt> INTO 
    <urn:qa-test-onto>;"
    
  4. creation of the rules set from the schema

    isql-vt 1111 dba dba exec="
    DELETE FROM sys_rdf_schema WHERE RS_NAME='urn:owl:inference:rules:qa-test';"
    
    isql-vt 1111 dba dba exec="
    rdfs_rule_set('urn:owl:inference:rules:qa-test', 'urn:qa-test-onto');"
    
  5. list the sets of inference rules:

    isql-vt 1111 dba dba exec="SELECT * FROM sys_rdf_schema;"
    
  6. query type per subject using the reasoning:

    isql-vt 1111 dba dba exec="SPARQL
    DEFINE input:inference 'urn:owl:inference:rules:qa-test'
    SELECT *
    FROM <urn:qa-test-graph>
    WHERE { ?s a ?o}
    ORDER BY ?s ?o;"
    
    s o
    qa-test:François qa-test:Thing
    qa-test:Ioana qa-test:Person
    qa-test:Ioana qa-test:Thing
    qa-test:Marie-Laure qa-test:Thing
    qa-test:Place http://www.w3.org/2000/01/rdf-schema#Class
    qa-test:contact http://www.w3.org/1999/02/22-rdf-syntax-ns#Property
       

    The answers set is not correct because François, Ioana and Marie-Laure are of type Person and Person is a subclass of Thing, but only Ioana is of type Thing. We notice that Maxime doesn't have a type, even if the domain of phoneNumber is Person, so domain is not used (the same for range, with Orsay for example).

  7. query all the subject of type Thing (it is correct):

    isql-vt 1111 dba dba exec="SPARQL
    DEFINE input:inference 'urn:owl:inference:rules:qa-test'
    SELECT *
    FROM <urn:qa-test-graph>
    WHERE { ?s a <qa-test:Thing>}
    ORDER BY ?s ;"
    
    s
    qa-test:François
    qa-test:Ioana
    qa-test:Marie-Laure
     
  8. query all the types of François (correct also):

    isql-vt 1111 dba dba exec="SPARQL
    DEFINE input:inference 'urn:owl:inference:rules:qa-test'
    SELECT ?o
    FROM <urn:qa-test-graph>
    WHERE { <qa-test:François> a ?o }
    ORDER BY ?o ;"
    
    o
    qa-test:Person
    qa-test:Thing
     

3.1.2. RC Test

  1. query all the subclass relations, no reasoning seems activated:

    isql-vt 1111 dba dba exec="SPARQL
    DEFINE input:inference 'urn:owl:inference:rules:qa-test'
    SELECT *
    FROM <urn:qa-test-graph>
    WHERE { ?s <http://www.w3.org/2000/01/rdf-schema#subClassOf> ?o }
    ORDER BY ?s ?o ;"
    
    s o
       
    qa-test:City qa-test:Place
    qa-test:Person qa-test:Thing
    qa-test:Place qa-test:Thing
    qa-test:Thing qa-test:Thing
       
  2. We try again by adding first, a triple that declares rdfs:subClassOf as a transitive property. It returns a error, because the transitivity of property is not supported in BGP with a variable as subject.

    isql-vt 1111 dba dba exec="SPARQL
    INSERT
      {
        GRAPH <urn:qa-test-onto> {
          <http://www.w3.org/2000/01/rdf-schema#subClassOf> a <http://www.w3.org/2002/07/owl#TransitiveProperty> .
        }
      };"
    
    isql-vt 1111 dba dba exec="
    rdfs_rule_set('urn:owl:inference:rules:qa-test', 'urn:qa-test-onto');"
    
    isql-vt 1111 dba dba exec="SPARQL
    DEFINE input:inference 'urn:owl:inference:rules:qa-test'
    SELECT *
    FROM <urn:qa-test-graph>
    WHERE { ?s <http://www.w3.org/2000/01/rdf-schema#subClassOf> ?o }
    ORDER BY ?s ?o ;"
    
    Connected to OpenLink Virtuoso
    Driver: 06.01.3127 OpenLink Virtuoso ODBC Driver
    OpenLink Interactive SQL (Virtuoso), version 0.9849b.
    Type HELP; for help and EXIT; to exit.
    
    *** Error 37000: [Virtuoso Driver][Virtuoso Server]TR...: transitive start not given
    at line 0 of Top-Level:
    SPARQL DEFINE input:inference 'urn:owl:inference:rules:qa-test' SELECT * FROM <urn:qa-test-graph> WHERE { ?s <http://www.w3.org/2000/01/rdf-schema#subClassOf> ?o } ORDER BY ?s ?o 
    
  3. Then we query for super classes of City (should be Place and Thing), but instead it returns a out of memory error,

    isql-vt 1111 dba dba exec="SPARQL
    DEFINE input:inference 'urn:owl:inference:rules:qa-test'
    SELECT DISTINCT *
    FROM <urn:qa-test-graph>
    WHERE { <qa-test:City> <http://www.w3.org/2000/01/rdf-schema#subClassOf> ?o OPTION (TRANSITIVE)}
    ORDER BY ?o ;"
    
    Connected to OpenLink Virtuoso
    Driver: 06.01.3127 OpenLink Virtuoso ODBC Driver
    OpenLink Interactive SQL (Virtuoso), version 0.9849b.
    Type HELP; for help and EXIT; to exit.
    
    *** Error 42000: [Virtuoso Driver][Virtuoso Server]TN...: Exceeded 100000000 bytes in transitive temp memory.  use t_distinct, t_max or more T_MAX_memory options to limit the search or increase the pool
    at line 0 of Top-Level:
    SPARQL DEFINE input:inference 'urn:owl:inference:rules:qa-test' SELECT * FROM <urn:qa-test-graph> WHERE { <qa-test:City> <http://www.w3.org/2000/01/rdf-schema#subClassOf> ?o } ORDER BY ?o
    
  4. In fact, there are specific settings for transitivity, so we have to specify the distinct near the transitive triples in the query.

    isql-vt 1111 dba dba exec="SPARQL
    DEFINE input:inference 'urn:owl:inference:rules:qa-test'
    SELECT DISTINCT *
    FROM <urn:qa-test-graph>
    WHERE { <qa-test:City> <http://www.w3.org/2000/01/rdf-schema#subClassOf> ?o OPTION (TRANSITIVE, t_distinct)}
    ORDER BY ?o ;"
    
    trans-subj-s30 o
       
    qa-test:City qa-test:Place
    qa-test:City qa-test:Thing
       

3.2. Custom Inference Rules

The custom inference rules are available only in Virtuoso 8.0, which is the commercial version.

This rules are build using the SPIN (for SPARQL Inference Notation) language.

We define the following sql script in order to test the reasoning in Virtuoso. This script has of three input $GRAPH which the RDF graph that will be loaded, $RULES defining the SPIN rule and $QUERY is the query evaluated in the graph. We notice that the SPIN rule is applied on the class <#Thing>, so the variable ?this in rule definition can only be bound to value in the class <#Thing> (see specification).

cat > .test.sql << EOF
SPARQL DROP SPIN  LIBRARY <urn:rules> ; 
    SPARQL CLEAR GRAPH <urn:graph>
    ;

    SPARQL
    prefix rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>
    prefix rdfs:<http://www.w3.org/2000/01/rdf-schema#>
    WITH <urn:graph>
    INSERT
    {
    $GRAPH
    };
  SPARQL SELECT * FROM <urn:graph> WHERE {?s ?p ?o};


    SPARQL CLEAR GRAPH <urn:rules> ;

    TTLP ('
    ## Collection of Inference Rules that describe
    ## various British Royal Family Relationship Types
    @prefix sp:    <http://spinrdf.org/sp#> .
    @prefix spin:    <http://spinrdf.org/spin#> .
    @prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
    @prefix rdfs:    <http://www.w3.org/2000/01/rdf-schema#> .
    @prefix foaf: <http://xmlns.com/foaf/0.1/> .

    <#Thing>
    a rdfs:Class ;
    rdfs:label "A Royal Person"^^xsd:string ;
    rdfs:subClassOf foaf:Person ;
    spin:rule
    [ a sp:Construct ;
    sp:text """
    $RULE
    """
    ] .
    ',
    '', 'urn:rules', 4096)
    ;

    SELECT 
    SPARQL_SPIN_GRAPH_TO_DEFSPIN('urn:rules');

    EXEC ('SPARQL ' || SPARQL_SPIN_GRAPH_TO_DEFSPIN('urn:rules'));
EOF

isql-vt 1111 dba dba exec="LOAD .test.sql" > /dev/null
isql-vt 1111 dba dba exec="SPARQL $QUERY" | tail -n +5 

3.2.1. Simple Case

We will consider the following RDF graph:

<Maxime> <livesIn> <Orsay> .
<Maxime> a <#Thing> .

The following SPIN rule says that the object of <livesIn> is of type <Person>.

CONSTRUCT { ?this a <Person> }
WHERE {
{ ?this <livesIn> ?y . }
}

We query for things of type <Person>.

DEFINE input:macro-lib <urn:rules>
WITH <urn:graph>
SELECT ?s
WHERE { ?s a <#Thing> . 
        ?s a <Person> . };
s
Maxime

The SPIN rule have been defined on the class <Thing>, so it seems mandatory to specify the type of <Thing> in the query to activate the reasoning process … So, the answer <Maxime> is missing.

DEFINE input:macro-lib <urn:rules>
WITH <urn:graph>
SELECT *
WHERE { ?s a <Person> .};
s
 

It is not possible neither to generalize the query as:

DEFINE input:macro-lib <urn:rules>
WITH <urn:graph>
SELECT ?s ?c
WHERE { ?s a <#Thing> . 
        ?s a ?c . };
s c
Maxime #Thing

3.2.2. Try to reason using domain specification

We define <Person> as the domain of <livesIn>.

<Maxime> <livesIn> <Orsay> .
<Maxime> a <#Thing> .
<livesIn> <http://www.w3.org/2000/01/rdf-schema#domain> <Person> .

We define the domain reasoning as in the standard:

CONSTRUCT { ?this a ?c }
WHERE {
{ ?this ?p ?y .
  ?p  <http://www.w3.org/2000/01/rdf-schema#domain> ?c . }
}

We query for things of type <Person>.

DEFINE input:macro-lib <urn:rules>
WITH <urn:graph>
SELECT ?s
WHERE { ?s a <#Thing> . 
        ?s a <Person> . };
s
Maxime

The SPIN rule have been defined on the class <Thing>, so it seems mandatory to specify the type of <Thing> in the query to activate the reasoning process …

DEFINE input:macro-lib <urn:rules>
WITH <urn:graph>
SELECT *
WHERE { ?s a <Person> .};
s
 

In this case, it is possible to generalize the query as:

DEFINE input:macro-lib <urn:rules>
WITH <urn:graph>
SELECT ?s ?c
WHERE { ?s a <#Thing> . 
        ?s a ?c . };
s c
Maxime Person
Maxime #Thing

But, it is not possible to generalize the query as:

DEFINE input:macro-lib <urn:rules>
WITH <urn:graph>
SELECT ?s ?p ?o
WHERE { ?s ?p ?o .};
s p o
Maxime http://www.w3.org/1999/02/22-rdf-syntax-ns#type #Thing
livesIn http://www.w3.org/2000/01/rdf-schema#domain Person
Maxime livesIn Orsay

But, it is not possible to generalize the query as:

DEFINE input:macro-lib <urn:rules>
WITH <urn:graph>
SELECT ?s ?p ?o
WHERE { ?s a <#Thing> . 
        ?s ?p ?o . };
s p o
Maxime http://www.w3.org/1999/02/22-rdf-syntax-ns#type #Thing
Maxime livesIn Orsay