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)
}
Related
I would like to use rules in my ontology so that at the moment of the inference I can retrieve some information not explicitly expressed in the triplestore.
I created a basic ontology and I want to add this rule:
Person(?p) ^ hasSibling(?p, ?s) ^ Man(?s) → hasBrother(?p, ?s)
The SPARQL query I would like to perform is
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX prova: <http://www.example.it/prova/>
SELECT ?subject ?object
WHERE { ?subject prova:hasBrother ?object }
Running this does not return anything. Of course, I have created the individuals for each class, but I have not created the instance that involves hasBrother, as this is what I want the intelligence to retrieve by itself.
So, my question is: is it possible to use SPARQL queries to achieve inference described by rules? Or these kind of inferences are only possible with a dedicated query system? In protegè I learn about the SQWRL tab for instance.
I am using the last version of Protegè (5.5.0) and the last version of the SWRL Rules plugin (2.11). I have defined the rule in the SWRL Tab. Then I tried the SQWRL tab to perform the query, but I get a strange error related to "invalid query name", which I don't really understand. Any suggestion about this second point would be helpful.
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.
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.
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX my: <http://www.ex.com#>
SELECT distinct ?person ?nationality
WHERE{
?person rdf:type ?p.
?person my:Nationality ?nationality.
filter (?nationality = "Some nationality")
}
I have created an ontology in Protege which describes a music production company. I have trouble understanding the SPARQL queries and the way they work.
Some explanations
?person: variable in which I want to output people. They are individuals in Protege
?nationality a variable in which I want to output nationalities. They are
data properties in Protege
Nationality: data property which contains nationalities as strings and every person has one
my: prefix I created
How does this work ?person rdf:type ?p and how does it select the right type? Does it work automatically? I don't feel like I have set the ?person variable as a type Person variable (which is a class I have created and it describes a person as an entity), even though it outputs exactly the outcome I need.
How does this work "?person rdf:type ?p" and how does it select the right type? I don't feel like I have set the ?person variable as a type Person variable (which is a class I have created and it describes a person as an entity), even though it outputs exactly the outcome I need.
It doesn't select the right type. It selects a type, any type (and also any individual). Presumably the reason you are seeing the expect outcome is the second part of your query:
?person my:Nationality ?nationality.
In your data, only person-individuals have this property, so only they will match the full query (even if there are other individuals that have a different type).
How SPARQL works is essentially pattern matching. You specify a template for your RDF graph, the variables in the query are the "holes" in that template. Whichever parts of your graph fit the entire template get returned.
Put another way, your query asks the following: "give me all things that have both a type, and a nationality". There may be many things that have a type, but since only persons have a nationality, only persons are returned.
If you want, you can make it explicit that you are only interested in individuals of type Person, by replacing the variable ?p with the class identifier for persons, for example:
?person rdf:type my:Person.
?person my:Nationality ?nationality.
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,