extract labels with different languages out of a bound variable in sparql - sparql

As the title suggests, I have preferred labels in english and german. I am trying to extract each label by it's language and bind to a (newly created) variable.
SELECT ?copyC ?enLabel ?defaultLabel
WHERE {
?targetC skos:prefLabel ?prefUri .
?prefUri skosxl:literalForm ?b
# handle languages - english and german
bind(if(langMatches(lang(?b),"en"),?b,?_) as ?enLabel)
bind(if(langMatches(lang(?b),"de"),?b, ?_) as ?defaultLabel)
####
.
# create some uris
BIND(IRI(CONCAT("http://example.com/", REPLACE(STR(?enLabel), "\\W", "", "i") )) AS ?copyC ) .
BIND(IRI(CONCAT("http://example.com/", REPLACE(STR(?enLabel), "\\W", "", "i"),"_prefLabel_en" )) AS ?enLabelc ) .
BIND(IRI(CONCAT("http://example.com/", REPLACE(STR(?defaultLabel), "\\W", "", "i"),"_prefLabel_de" )) AS ?defaultLabelc ) .
####
}
A toy example model:
#prefix skos: <http://www.w3.org/2004/02/skos/core#> .
#prefix skosxl: <http://www.w3.org/2008/05/skos-xl#> . <http://example_copy.com/thing1> a skos:Concept ;
skosxl:prefLabel <http://example_copy.com/some_german_label>, <http://example> <http://example_copy.com/some_german_label> a skosxl:Label ;
skosxl:literalForm "some german label"#de . <http://example_copy.com/some_english_label> a skosxl:Label ;
skosxl:literalForm "some english label"#en .
results:
?c ?enLabel ?defaultLabel
1 <http://example.com/thing1> <http:/example.com/some_english_label>
2 <http:/example.com/some_german_label>
above query follows this post:
SPARQL filter language if possible in multiple value context
The ?englishLabelc is correctly associated to the bound ?copyC variable but the ?defaultLabelc is not. My desire is that both the english and german label will correctly be associated uri bound to ?copyC. I assume there is a scope problem in how I am "BIND"ing the ?copyC variable but I am not sure how to go about troubleshooting. If I simply use the ?b variable to create ?copyC two concepts will be created - one for the english and one for the german label which is what I want. Can someone help me figure this out?

Related

Extract synonyms and label from Turtle file using SPARQL

I am in a learning phase of SPARQL. I am working with a Turtle file to extract some information. The condition is: if the exact synonym has a substring 'stroke' or 'Stroke', the query should return all the synonyms and rdfs:label.
I am using below query but getting no output:
prefix oboInOwl: <http://www.geneontology.org/formats/oboInOwl#>
prefix obo: <http://purl.obolibrary.org/obo/>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
Select * where {
?s ?p ?o .
rdfs:label <http://www.geneontology.org/formats/oboInOwl#hasExactSynonym> "stroke"^^xsd:string
}
Below is the sample Turtle file:
### https://ontology.aaaa.com/aaaa/meddra_10008196
:meddra_10008196
rdf:type owl:Class ;
<http://www.geneontology.org/formats/oboInOwl#hasDbXref> "DOID:6713" , "EFO:0000712" , "EFO:0003763" , "HE:A10008190" ;
<http://www.geneontology.org/formats/oboInOwl#hasExactSynonym>
"(cva) cerebrovascular accident" ,
"Acute Cerebrovascular Accident" ,
"Acute Cerebrovascular Accidents" ,
"Acute Stroke" ,
"Acute Strokes" ;
rdfs:label "Cerebrovascular disorder"#en ;
:hasSocs "Nervous system disorders [meddra:10029205]" , "Vascular disorders [meddra:10047065]" ;
:uid "6e46da69b727e4e924c31027cdf47b8a" .
I am expecting this output:
(cva) cerebrovascular accident
Acute Cerebrovascular Accident
Acute Cerebrovascular Accidents
Acute Stroke
Acute Strokes
Cerebrovascular disorder
With this triple pattern, you are querying for rdfs:label as subject, not as predicate:
rdfs:label <http://www.geneontology.org/formats/oboInOwl#hasExactSynonym> "stroke"^^xsd:string
What you are asking with this is: "Does the resource rdfs:label have the property oboInOwl:hasExactSynonym with the string value 'stroke'?"
But you want to ask this about the class (e.g., :meddra_10008196), not rdfs:label:
?class oboInOwl:hasExactSynonym "stroke" .
Finding matches
As you don’t want to find only exact string matches, you can use CONTAINS:
?class oboInOwl:hasExactSynonym ?matchingSynonym .
FILTER( CONTAINS(?matchingSynonym, "stroke") ) .
As you want to ignore case, you can query lower-cased synonyms with LCASE:
?class oboInOwl:hasExactSynonym ?matchingSynonym .
FILTER( CONTAINS(LCASE(?matchingSynonym), "stroke") ) .
Displaying results
To display the label and all synonyms in the same column, you could use a property path with | (AlternativePath):
?class rdfs:label|oboInOwl:hasExactSynonym ?labelOrSynonym .
Full query
# [prefixes]
SELECT ?class ?labelOrSynonym
WHERE {
?class rdfs:label|oboInOwl:hasExactSynonym ?labelOrSynonym .
FILTER EXISTS {
?class oboInOwl:hasExactSynonym ?matchingSynonym .
FILTER( CONTAINS(LCASE(?matchingSynonym), "stroke") ) .
}
}

SPARQL - Make a Anti pattern query that select the ClassName that respect the CamelCase (No uppercase)

I want to find a query that select the ClassName that doesn't begin with an uppercace.
The architecture is:
SELECT DISTINCT ?prop WHERE { { ?prop rdf:type owl:Class . } UNION { ?prop rdf:type owl:DatatypeProperty . } MINUS { #To DO }. }
You can't perform regex directly on your ?prop because it probably contains the prefix and you don't want it.
First you have to remove the prefix (let's say your prefix is ":")
bind(strafter(str(?class),str(:)) as ?propertyName)
It will create a var called propertyName that contains only the name (without prefix)
Now that you have this you can perform regex on it. If you only want to keep properties starting with a capital case you can do:
FILTER regex(str(?propertyName),"^[A-Z]")
Note: if you want to verify every rules of camelCase you can check this regex

Numeric properties that are returned as string by SPARQL

I'm having a problem with SPARQL when dealing with numeric data types.
I have an ontology (http://cabas.ugr.es/ontology/ugr) in which I have defined a pair of properties that represent the number of students who are of a particular sex:
<http://cabas.ugr.es/ontology/ugr#hombres>
a owl:DatatypeProperty, owl:FunctionalProperty, rdf:Property ;
rdfs:label
"hombres"#es,
"men"#en ;
rdfs:comment
"Número de estudiantes hombres."#es,
"Number of male students."#en ;
rdfs:range xsd:nonNegativeInteger ;
rdfs:isDefinedBy <http://cabas.ugr.es/ontology/ugr#> ;
owl:sameAs <http://cabas.ugr.es/ontology/ugr#hombres> ;
owl:inverseOf <http://cabas.ugr.es/ontology/ugr#mujeres> ;
ns1:term_status "stable" .
<http://cabas.ugr.es/ontology/ugr#mujeres>
a owl:DatatypeProperty, owl:FunctionalProperty, rdf:Property ;
rdfs:label
"mujeres"#es,
"women"#en ;
rdfs:comment
"Número de estudiantes mujeres."#es,
"Number of female students."#en ;
rdfs:range xsd:nonNegativeInteger ;
rdfs:isDefinedBy <http://cabas.ugr.es/ontology/ugr#> ;
owl:sameAs <http://cabas.ugr.es/ontology/ugr#mujeres> ;
owl:inverseOf <http://cabas.ugr.es/ontology/ugr#hombres> ;
ns1:term_status "stable" .
I have a SPARQL endpoint mounted on Virtuoso (http://cabas.ugr.es:8890/sparql), in which I enter for example the following query:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ugr: <http://cabas.ugr.es/ontology/ugr#>
SELECT ?X ?titulacion ?rama ?hombres ?mujeres
WHERE {
?X ugr:Titulación ?titulacion .
?X ugr:RamaConocimiento ?rama .
?X ugr:hombres ?hombres .
?X ugr:mujeres ?mujeres
}
(Which would correspond with this link)
It returns all the records, but the fields "hombres" and "mujeres" returns them to me as if it were a string instead of a numeric value, so for example it is impossible to apply a filter like FILTER (?hombres > 500). Any idea what I'm wrong about?
By the way, the ontology and the resource with the values are accessible through these links:
Ontology:
Turtle Format:
http://cabas.ugr.es/ontology/ugr
http://cabas.ugr.es/ontology/ugr.ttl
RDF/XML Format:
http://cabas.ugr.es/ontology/ugr.rdf
Resource:
Turtle Format:
http://cabas.ugr.es/resources/MatriculasGrado1516
http://cabas.ugr.es/resources/matriculas_grado_1516.ttl
RDF/XML Format:
http://cabas.ugr.es/resources/matriculas_grado_1516.rdf
In order to treat the numbers as numbers, you need to define them as such.
Right now you define them as strings:
<http://cabas.ugr.es/resources/MatriculasGrado1516#21>
ns0:hombres "91" ;
ns0:mujeres "68" .
To define them as integers, you need to set their type to xsd:integer:
<http://cabas.ugr.es/resources/MatriculasGrado1516#21>
ns0:hombres "91"^^xsd:integer ;
ns0:mujeres "68"^^xsd:integer .
Strings can also be cast to integer in queries, if needed. For example:
FILTER(xsd:integer(?hombres) > 500)

Matching user inputs with tripplestore data

I am trying to develop a decision support system for soybean disease analysis using protege, fuseki server and php. I want to take input from a user and a return a disease name based on the matching of the literal. The query I am trying is :
$sparql = "PREFIX : <http://localhost/soy_test1#>
select ?Diaporthe_stem_canker where {?Diaporthe_stem_canker :hasTOC ' . TOC . ' . ' . TOC .' :hasTOC 'July'}";
It always returns Diaporthe_stem_canker no matter what the input is. I am trying to find what's the error in the sparql query. Any help would be appreciated.
Thanks.
Edit
The ontology I have is as follows:
A plant soybean is described by some plant descriptors. Plant descriptor has several types with some attribute values.
Example:
:PlantDescriptor :hasType "EnvironmentalDescriptors" .
:PlantDescriptor :hasAttribute :TOC .
:PlantDescriptor :hasTOC "July" .
:TOC rdfs:subClassOf :Attribute .
where PlantDescriptor and Attribute are the concepts of the ontology.
I am trying to take an input from the user for the attribute "TOC", which I want to match whether it's "July" or not; if it matches with July then it will return the disease name Diaporthe-stem-canker.
The string part is for matching the user input text with the value "July". That's why I have used it as a php variable inside SPARQL Query.
The query that I used in my Query engine is like this:
PREFIX : <http://localhost/soy_test1#>
select distinct ?P ?X ?Time
where {?PlantDescriptor :hasType ?P .
?PlantDescriptor :hasAttribute ?X.
?X :hasTOC "July" .
?X :hasTOC ?Time .}
which returns the value "July" under ?Time, the url for Attribute concept and the type of the PlantDescriptor for the corresponding Attribute.
Hope I have made my point more clear.
Thanks in advance.
The example isn't entirely clear because you say you are searching for Diaporthe-stem-canker, but that's not in your sample data. Assuming Diaporthe-stem-canker is a PlantDescriptor, the following query could get you what you need:
SELECT ?disease
WHERE {
?disease :hasTOC "July" .
}
And in your case the "July" string is inserted into the string, so you may have something like the following if you were using PHP (no idea what your syntax is(:
$sparql = "PREFIX : <http://localhost/soy_test1#>
select ?disease where {?disease :hasTOC " . $date . " . }"
...where $date is bound to "July", etc.

Require individual's property values to be a superset of another's?

I have defined an ontology with the following classes, properties, and individuals with object property assertions:
Class: Employee > Individuals: { EmployeeA }
Class: Skill > Individuals: { Skill1, Skill2, Skill3 }
Class: Job > Individuals: { DBA }
hasSkill > Domain (Employee) and Range (Skill)
isAskillBy > Domain (Skill) and Range (Employee) <inverse of hasSkill>
requireSkill > Domain (Job) and Range (Skill)
isAskillrequiredBy > Domain (Skill) and Range (Job) <inverse of requireSkill>
Individual: EmployeeA, object property assertion: hasSkill Skill1
hasSkill Skill2
, types : hasSkill only ({Skill1,Skill2}) <to close OWA
, Negative object property assertion: hasSkill Skill3
Individual: DBA, object property assertion: requireSkill Skill1
requireSkill Skill2
requireSkill Skill3
, types : requireSkill only ({Skill1,Skill2, Skill3}) <to close OWA
To classify whether an Employee is qualified for a job (in this case, the DBA position), I created the class Fit and made it equivalent to:
Employee and (hasSkill only (isAskillrequiredBy value DBA))
When I run a reasoner in Protege, the reasoner classifies EmployeeA under the class Fit, but with the closure axioms to address the Open World Assumption (OWA), EmployeeA should not be classified as Fit, since he does not have all three skills needed for the DBA position.
First, recall what the "universal" quantification in OWL means. The class expression
p only C
is the individuals x such that if x is related to y by property p, then y must be a C. That is, p(x,y) implies C(y). Your query is returning the correct results, but the query doesn't mean exactly what you want it to mean. The query
Employee and (hasSkill only (isAskillrequiredBy value DBA))
says that something must be an Employee, and if the employee has a skill, then the skill must be one that is required by the DBA position. EmployeeA certainly meets that definition, since the skills that EmployeeA has are Skill1 and Skill2, both of which are required for the DBA position.
The problem in this query is the only. It will manifest in two different ways: (i) if someone is qualified for DBA position (i.e., has all the necessary skills), but has additional skills, then you won't retrieve them, since they have skills that aren't required for the DBA position (but maybe you don't want overqualified people); and (ii) it retrieves people all of whose skills are required for the DBA position, but doesn't require that the people actually have all the skills needed for the DBA position.
What you actually want to ask for is individuals that have all the skills necessary for the DBA position. What you'd need to check is whether an individual lacks any skills that are required for the DBA. The skills required for the DBA position can be found with:
(inverse requiresSkill) value DBA
The skills not needed for the DBA are simply the negation of that:
not ((inverse requiresSkill) value DBA)
What you'd like to say is that any skills that an individual doesn't have must be from that class. Currently, you don't have a property that connects an individual to the skills that they don't have. If you did, then you could define your "Fit" class as
Employee and (lacksSkill only (not ((inverse requiresSkill) value DBA)))
Now, the question is whether you can define a property lacksSkill that's true exactly when an employee doesn't have a skill. I'm not sure whether you can do exactly that, but you can define
lacksSkill disjointProperty hasSkill
which will mean that if hasSkill(x,y) is true, then lacksSkill(x,y) must be false. It's not exactly the the same as a negation, because they can both be false at the same time, but they can't both be true.
That's enough to make this query work, and it removes the need for some of the closure axioms. You'll still need to close what the position requires, but you don't need to close the skills of the employees. That is, you don't need to say, e.g., that EmployeeA has only the skills Skill1, Skill2. I created an ontology in Protege that you can use to see this in action. It has an EmployeeA who has Skill1 and Skill2 (not enough to qualify for the job), and an EmployeeB who has all three skills, which is enough to qualify.
#prefix : <http://example.org/> .
#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 example: <http://example.org/> .
example:Skill a owl:Class .
example:Position a owl:Class .
example:Skill3 a owl:NamedIndividual , example:Skill .
example:hasSkill a owl:ObjectProperty ;
owl:propertyDisjointWith example:lacksSkill .
example:requiresSkill
a owl:ObjectProperty .
example: a owl:Ontology .
example:DBA a owl:NamedIndividual , example:Position ;
a [ a owl:Restriction ;
owl:allValuesFrom [ a owl:Class ;
owl:oneOf ( example:Skill3 example:Skill2 example:Skill1 )
] ;
owl:onProperty example:requiresSkill
] ;
example:requiresSkill example:Skill1 , example:Skill2 , example:Skill3 .
example:Skill2 a owl:NamedIndividual , example:Skill .
example:Employee a owl:Class .
example:EmployeeA a owl:NamedIndividual , example:Employee ;
example:hasSkill example:Skill1 , example:Skill2 .
example:Skill1 a owl:NamedIndividual , example:Skill .
example:lacksSkill a owl:ObjectProperty .
example:EmployeeB a owl:NamedIndividual , example:Employee ;
example:hasSkill example:Skill1 , example:Skill2 , example:Skill3 .