1

Can I use a SPARQL* query to query a classic RDF model that uses reification? To me, the Jena documentation is a bit vague here.

The code below creates a reified statement:

<< <http://www.mysubject.com> <http://www.mypredicate.com> <http://www.myobject.com> >> <http://www.sayed.de#sayed> <http://www.sayer.de> .

The code further contains two queries: (i) A classic SPARQL query, (ii) a SPARQL* query. Both query for <http://www.sayer.de> as result. While (i) comes back with the solution, (ii) fails to do so.

What am I doing/understanding wrong here?

import org.apache.jena.ontology.DatatypeProperty;
import org.apache.jena.ontology.OntModel;
import org.apache.jena.ontology.OntModelSpec;
import org.apache.jena.query.*;
import org.apache.jena.rdf.model.*;

import java.io.StringWriter;

public class RdfStar {

    public static void main(String[] args) {

        // let's create an ontModel and fill it with data:
        OntModel model =  ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
        ReifiedStatement s = model.createReifiedStatement(
                model.createStatement(
                        ResourceFactory.createResource("http://www.mysubject.com"),
                        ResourceFactory.createProperty("http://www.mypredicate.com"),
                        ResourceFactory.createResource("http://www.myobject.com"))
        );
        ObjectProperty sayedProperty = model.createObjectProperty("http://www.sayed.de#sayed");
        s.addProperty(sayedProperty, model.createResource("http://www.sayer.de"));

        // write to console
        StringWriter myWriter = new StringWriter();
        model.write(myWriter, "NT");
        String result = myWriter.toString();
        System.out.println(result);

        // now let's create a regular query
        String queryString = "SELECT ?who WHERE {" +
                "?statement <http://www.sayed.de#sayed> ?who ." +
                "}";
        Query query = QueryFactory.create(queryString) ;
        try (QueryExecution qexec = QueryExecutionFactory.create(query, model)) {
            ResultSet results = qexec.execSelect();
            while (results.hasNext()) {
                QuerySolution soln = results.nextSolution();
                RDFNode x = soln.get("who");
                System.out.println(x);
            }
        } catch (Exception e){
            e.printStackTrace();
        }

        // NOW SPARQL STAR

        queryString = "SELECT ?who WHERE {" +
                "<< ?a ?b ?c >> ?d ?who ." +
                "}";
        query = QueryFactory.create(queryString, Syntax.syntaxARQ) ;
        try (QueryExecution qexec = QueryExecutionFactory.create(query, model)) {
            ResultSet results = qexec.execSelect();
            while (results.hasNext()) {
                QuerySolution soln = results.nextSolution();
                RDFNode x = soln.get("who");
                System.out.println("Star result: " + x);
            }
        } catch (Exception e){
            e.printStackTrace();
        }
    }
}

Janothan
  • 446
  • 4
  • 16
  • First: Let's be clear about terminology `<<:s :p :o>> :q :z .` is not a reified statement. RDF Reification uses the properties `rdf;subject`, `rdf;predicate`, `rdf:object` : see https://www.w3.org/wiki/RdfReification. There is a possible transformation to reification. – AndyS Jan 14 '21 at 12:36
  • Yes, sorry for the imprecision! I just used this notation to be very short. If you execute the Java file you can see the actual triples. – Janothan Jan 14 '21 at 13:18

1 Answers1

2

It is easier at the moment to write data in Turtle (or N-Triples) rather than through the Model API.

model.createReifiedStatement is older functionality for reificiation which is not RDF*.

The implementation of RDF*/SPARQL* in Jena will track the work in the RDF-star community group and will need to change.

The current SPARQL* is rooted in the original RDF* paper. It uses the triple index for <<>> so matches happen using the index (it is "PG-mode" like): <<:s :p :o>> :q :z .

Try the following data (D.ttl) (the development version of Jena has the new annotation syntax as well:

PREFIX ex: <http://example/>

ex:s ex:p ex:o .
<<ex:s ex:p ex:o>> ex:q ex:z .

and query (Q.rq):

PREFIX ex: <http://example/>

SELECT * {
  << ?s ?p ?o >> ?q ?z .
}

which, using the command line tools

sparql --data D.ttl --query Q.rq 

gives

------------------------------------
| s    | p    | o    | q    | z    |
====================================
| ex:s | ex:p | ex:o | ex:q | ex:z |
------------------------------------

AndyS
  • 16,345
  • 17
  • 21
  • Thank you for your detailed answer. I can reproduce the documented behavior in the command line. I have two small subsequent questions: (1) Is there currently no "convenient way" through the Model API at all? (2) Will SPARQL* eventually also work with reified statements? – Janothan Jan 14 '21 at 13:43
  • 1
    (1) Not in Model API - there is in the Graph/Triple API.The Model API can handle RDF* `<<>>` terms but not create them. The final direction and semantics isn't completely settled yet and the Model API should be cautious and stable. – AndyS Jan 14 '21 at 17:18
  • 1
    (2) Reified - as in `rdf:subject`, `rdf:predicate`, `rdf:object`? It already does But that is nothing to do with `<<:s :p :o>>`. – AndyS Jan 14 '21 at 17:22