NotMyJob
NotMyJob

Reputation: 93

Property Path equivalent to OPTION(TRANSITIVE) statement in SPARQL

I'm a naive user trying to replicate a query that results in the following type of string:

derives_from some (epithelial cell and (part_of some (uterine cervix and (part_of some (Homo sapiens and (has disease some adenocarcinoma)))))

I'm at a hackathon, we have no ontology/SPARQL expert, and we're just trying to get these related fields out of this ontology and into SOLR. We're desperate!

The webpage this is from http://www.ontobee.org/ontology/CLO?iri=http://purl.obolibrary.org/obo/CLO_000368) helpfully provides all the SPARQL queries that are used on the page. I think this is the relevant query:

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
SELECT DISTINCT ?ref ?refp ?label ?o FROM <http://purl.obolibrary.org/obo/merged/CLO> WHERE {
    ?ref ?refp ?o .
    FILTER ( ?refp IN ( owl:equivalentClass, rdfs:subClassOf ) ) .
    OPTIONAL { ?ref rdfs:label ?label } .
    {
        {
            SELECT ?s ?o FROM <http://purl.obolibrary.org/obo/merged/CLO> WHERE {
                ?o ?p ?s .
                FILTER ( ?p IN ( rdf:first, rdf:rest, owl:intersectionOf, owl:unionOf, owl:someValuesFrom, owl:hasValue, owl:allValuesFrom, owl:complementOf, owl:inverseOf, owl:onClass, owl:onProperty ) )
            }
        }
        OPTION ( TRANSITIVE, t_in( ?s ), t_out( ?o ), t_step( ?s ) as ?link ).
        FILTER ( ?s= <http://purl.obolibrary.org/obo/CLO_0003684> )
    }
}
ORDER BY ?label

However, I can't even run that to check, because my SPARQL endpoint doesn't support Virtuoso. http://sparql.bioontology.org So, it spits back an error on OPTION(TRANSITIVE). Can anyone show me the equivalent standard pathway language? There are varying pathway lengths between the target nodes.

Upvotes: 0

Views: 442

Answers (1)

Jeen Broekstra
Jeen Broekstra

Reputation: 22042

Virtuoso's transitivity operator is more powerful than what standard SPARQL provides, so in the general case it will not always be possible to express the same thing in a single standard SPARQL query. However, I believe that in this case it is possible.

The following property path would be the equivalent (disclaimer, I haven't tested this query, but it should give you the general idea):

?o (rdf:first|rdf:rest|owl:intersectionOf|owl:unionOf|owl:someValuesFrom|owl:hasValue|owl:allValuesFrom|owl:complementOf|owl:inverseOf|owl:onClass|owl:onProperty)+ ?s .

The full query would become something like this:

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
SELECT DISTINCT ?ref ?refp ?label ?o FROM <http://purl.obolibrary.org/obo/merged/CLO> WHERE {
    ?ref ?refp ?o .
    FILTER ( ?refp IN ( owl:equivalentClass, rdfs:subClassOf ) ) .
    OPTIONAL { ?ref rdfs:label ?label } .
    {
        {
            SELECT ?s ?o FROM <http://purl.obolibrary.org/obo/merged/CLO> WHERE {
                    ?o (rdf:first|rdf:rest|owl:intersectionOf|owl:unionOf|owl:someValuesFrom|owl:hasValue|owl:allValuesFrom|owl:complementOf|owl:inverseOf|owl:onClass|owl:onProperty)+ ?s .
            }
        }
        FILTER ( ?s= <http://purl.obolibrary.org/obo/CLO_0003684> )
    }
}
ORDER BY ?label

Note, by the way, that the FILTER condition on your variable ?s is outside the subselect, which might make this query a bit of a performance hog. Since you are not using ?s anywhere else in the query, you can simplify this part of the query further, eliminating the FILTER, like so:

    {
        {
            SELECT ?o FROM <http://purl.obolibrary.org/obo/merged/CLO> WHERE {
                    ?o (rdf:first|rdf:rest|owl:intersectionOf|owl:unionOf|owl:someValuesFrom|owl:hasValue|owl:allValuesFrom|owl:complementOf|owl:inverseOf|owl:onClass|owl:onProperty)+ <http://purl.obolibrary.org/obo/CLO_0003684> .
            }
        }
    }

Upvotes: 2

Related Questions