SPARQL - Inverse Path of dynamic discovered relationship - sparql

I have a Graph Database that implements only one side of relationships in the model structures. For instance, All Broader relationships are mapped as skos:broader. All Narrower relationships are mapped as ^skos:broader (for whatever reasons they chose to do this, I have no control over this.)
I am trying to write a SPARQL Query that delivers something like
Query for all relationships of a given IRI, and their associated values.
The goal is to make a JSON or XML Representation of all the content.
Here is what I have working.
PREFIX skosxl: <http://www.w3.org/2008/05/skos-xl#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?relation ?value
where
{
<CONCEPT_URI> ?r ?c
OPTIONAL {
?r rdfs:label|skosxl:prefLabel ?l
}
OPTIONAL {
?c skosxl:prefLabel/skosxl:literalForm|skosxl:literalForm ?d .
}
BIND ( if (bound(?d), ?d, ?c) as ?value )
BIND ( if (bound(?l), ?l, strafter(?r, '#')) as ?relation )
}
This works to give me all the concept relationships (IE: Broader), but it does not give me the narrower items (IE: ^broader).
Is there anyway that I can extend this generic query to produce the inverses of any relationships it finds, as well? I Tried simply adding the ^ to the ?r in the where clause but it does not like that syntactically.
Thanks,

Related

Construct loop in SPARQL

The following SPARQL query
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix skos: <http://www.w3.org/2004/02/skos/core#>
prefix msc: <http://msc.org/resources/MSC/msc2020/>
construct {?s skos:broader msc:00-XX . }
where
{
?s a skos:Concept ; skos:notation ?notation.
filter regex (?notation, "00-\d\d")
}
searches all notations 00-01, 00-02, etc. and constructs a relation to the top level class 00-XX. However, this is only the first of 63 top level classes altogether, so I would like to "loop" over all top level classes automatically. On top, I would like to adapt this to other patterns. Is there a way to do this with SPARQL? If not, what would you recommend instead?
In the meantime we found a solution without SPARQL.
The SPARQL CONSTRUCT query was supposed to create a skos:broader relation between a skos:Concept with a notation like "00-01" (and all other concepts with 00-\d\d notation) and its proper subordinate concept, which for 00-01 is the skos:Concept with the notation 00-XX.
The data originate from a table and Open Refine is much faster in creating the skos:broader statements than using the SPARQL query proposed above and adjusting it to other notation patterns.
We use GREL's value.replace on the cells with the notations to create a new column:
value.replace(/-\d\d/, "-XX").replace(/\d\d>/, "xx>")
The two replacements give us the notation of the original notation's superordinate concept in one step. The second replace already adapts to the other patterns mentioned in the question (e.g. 00A01).
With the original notation and the value in the new column, we can easily create the skos:broader triples by concatenating text and the values from both columns. These can then be exported from OpenRefine and just be copy-pasted to our SKOS vocabulary.
Here is a SPARQL answer based on the query in the question. Using filters and regex (as suggested in the comment by Yahalnaut as a reply to UninforomedUser above) is needed. Creating a skos:broader relation based on two concept's notations requires them to hava an identical sequence of digits before the - . The comparison should only between the first part of the notations, so each 00- should match another 00-but not a 01-. As asked, the solution below only considers topConcepts of the Vocabulary as potential objects for skos:broader. The concepts should also not relate to themselves, therefore the last filter. This should then be adoptable to other patterns as well. Depending on the number of Concepts and the memory available for the query, this may last a while or even stop before finished. It eliminates lot of the effort though.
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix skos: <http://www.w3.org/2004/02/skos/core#>
prefix msc: <http://msc.org/resources/MSC/msc2020/>
construct {?s skos:broader ?y . }
where {
?s a skos:Concept ; skos:notation ?notation.
?y skos:topConceptOf msc: ; skos:notation ?not2.
bind (REPLACE (?not2 , "-XX" , "") as ?1)
bind (REPLACE (?notation , "-\d\d", "" ) as ?2 )
filter (?1 = ?2)
filter (?not2 != ?notation)
}

Can I constrain the owl:onProperties when traversing over owl:Restrictions?

I'd like to use ChEBI to determine which molecular entities could be considered "taxanes", in the informal language that physicians use.
The Anatomical and Therapeutic Classification places both docetaxel and paclitaxel in class L01CD "Taxanes", but in ChEBI the paths include both subclass relations and
'has parent hydride' some 'taxane' relations, from an OWL perspective. The following SPARQL finds both docetaxel and paclitaxel
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
select * where {
?drug (rdfs:subClassOf|owl:someValuesFrom)*
<http://purl.obolibrary.org/obo/CHEBI_36064> .
optional {
?drug rdfs:label ?l .
}
}
order by ?l
I'm not explicitly requiring here that the owl:someValuesFrom predicate is applied to an owl:Restiction in the rdfs:subClassOf path. How could I limit this query so that only certain owl:onPropertys (like 'has parent hydride') are allowed in combination with that implicit owl:Restriction?
I'm afraid that this query is dangerously under specified as it is.

skos broader and narrow inverse not working

I have setup GraphDB SE trial version and trying out inference functionality with OWL2-RL ruleset. I have built a simple SKOS knowledge with a single broader relationship. Some how, when I try to query for narrower relationship am not getting any results. Am I going wrong in the usage ?
Insertion:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
INSERT DATA {
ex:mammals rdf:type skos:Concept;
skos:prefLabel "mammals"#en;
ex:animals rdf:type skos:Concept;
skos:prefLabel "animals"#en;
skos:broader ex:mammals .
}
Query:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
select * where {
?s skos:narrower ?o .
}
In the query result I don't see any response. Shouldn't it return below result -
ex:mammals skos:narrower ex:animals
I just came across this question and the OP is correct: Although the official SKOS reference explicitly states that skos:broader and skos:narrower are inverse, the actual RDF implementation does not include this statement. However, properties skos:broaderTransitive and skos:narrowerTransitive are declared as inverse.
And, although not relevant to the original question, the implementation does not state properties skos:topConceptOf and skos:hasTopConcept as inverse either.

SPARQL: using function bif:st_distance and bif:st_points do not work outside SERVICE

I'm trying to write a SPARQL request, where I want to query country names from my own dataset, use the dbpedia resource to retrieve the countrie's latitude and longitude and then calculate the distance among them with the bif:st_distance function. The latitude and longitude I want to use are floats, so I have to convert them to points with bif:st_point first, since the function takes points only.
On my local machine I'm running a apache jena-fuseki server with my dataset loaded. I tried the following:
PREFIX rate: <http://MYNAME.bplaced.net/rating/index.ttl#>
PREFIX dbr: <http://dbpedia.org/resource/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX bif: <bif:>
PREFIX dbr: <http://dbpedia.org/resource/>
PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
PREFIX afn: <http://jena.apache.org/ARQ/function#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?from ?to ?latituded ?longituded ?latitudeo ?longitudeo ?distance WHERE{
{SELECT ?from ?to (AVG(?latd) as ?latituded)
(AVG(?longd) as ?longituded)
(AVG(?lato) as ?latitudeo)
(AVG(?longo) as ?longitudeo) WHERE {
?rating rate:from dbr:Germany.
?rating rate:year "1965"^^xsd:gYear.
?rating rate:from ?from.
?rating rate:to ?to.
SERVICE <http://dbpedia.org/sparql>{
?from geo:lat ?latd.
?from geo:long ?longd.
?to geo:lat ?lato.
?to geo:long ?longo.
}
} GROUP BY ?from ?to
}
BIND(bif:st_distance(
bif:st_point(?latituded,?longituded),
bif:st_point(?latitudeo,?longitudeo)
)AS ?distance).
}
This leaves me with this result:
The query result
As you can see: The distance column remains empty. I am sure it has something to do with whether or not the BIND statement is located within the SERVICE. Might some values be invisible to the BIND?
What am I doing wrong or what can I do differently to solve this?
Thanks in advance!
The spatial functions in the bif namespace are specific to Virtuoso, the software used by DBpedia. Therefore they will only work in the SERVICE clause where the query is executed on the Virtuoso server. So either use these functions in the SERVICE clause or take a look at the Jena spatial functions.

Sparql result not containing specified property included in results

I have this query
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/>
PREFIX dbpedia: <http://dbpedia.org/>
PREFIX dbpedia_property: <http://dbpedia.org/property/>
PREFIX dbpedia_ontology: <http://dbpedia.org/ontology/>
PREFIX yago: <http://dbpedia.org/class/yago/>
PREFIX schema: <http://schema.org/>
SELECT * WHERE
{
{
SELECT ?school
WHERE
{
?school rdf:type yago:EducationalInstitution108276342 .
FILTER ( contains(str(?school), "Australia") )
}
ORDER BY ?school
}
}
Don't mind the extra brackets as this is part of a larger query.
What I want to know is why thi http://dbpedia.org/page/Academic_structure_of_the_Australian_National_University is included in the results since I specify rdf:type yago:EducationalInstitution108276342. This property is not included in the resource page. I'm using this endpoint: http://dbpedia.org/sparql
Looks like a bug in the Pubby Web interface or in the query that is used to get the data that will be shown.
The query
SELECT * WHERE{
<http://dbpedia.org/resource/Academic_Structure_of_the_Australian_National_University> ?p ?o
}
returns the necessary rdf:type statement.
The other strange thing is that even a SPARQL DESCRIBE query does not return the rdd:type triples:
DESCRIBE <http://dbpedia.org/resource/Academic_Structure_of_the_Australian_National_University>
Although DESCIBE is not really defined in the specs, a user would expect those triples for sure. And maybe this kind of query is used to retrieve the data for the Web pages of resources.